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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * k99 v0.8.0
2
+ * k99 v0.9.1
3
3
  * (c) 2019-2026 猛火Fierflame
4
4
  * @license MIT
5
5
  */
@@ -413,7 +413,7 @@
413
413
  if (result instanceof Response) { return result; }
414
414
  const headers = new Headers(context.responseHeaders);
415
415
  const { status } = context;
416
- if (!result) { return new Response(null, { status, headers }); }
416
+ if (!result == null) { return new Response(null, { status, headers }); }
417
417
  const body = toBody(result, headers, replacer, aborted);
418
418
  return new Response(body, { status, headers });
419
419
  }).then(response => {
@@ -432,40 +432,151 @@
432
432
  return exec(request);
433
433
  }
434
434
 
435
- /** @import { FindHandler, Options } from './main/types' */
435
+ /** @import { Method, Params } from './main/types' */
436
436
 
437
437
  /**
438
- *
439
- * @param {FindHandler} getHandler
440
- * @param {Options} options
441
- * @returns {(request: Request) => Promise<Response | null>}
438
+ * @template {Function} T
439
+ * @typedef {[T | T[] | Router<T>, Record<string | symbol, any>, string[]]} FindItem
442
440
  */
443
- function make(getHandler, options) {
444
- return r => main(r, getHandler, options);
441
+ /**
442
+ * @template {Function} T
443
+ * @callback Finder
444
+ * @this {Router<T>}
445
+ * @param {Method} method
446
+ * @param {string[]} path
447
+ * @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
448
+ */
449
+
450
+ /**
451
+ * @abstract
452
+ * @template {Function} T
453
+ */
454
+ class Router {
455
+ disabled = false;
456
+ /**
457
+ *
458
+ * @template {Function} T
459
+ * @param {Router<T> | T[] | T} route
460
+ * @param {Method} method
461
+ * @param {string[]} path
462
+ * @param {Params} params
463
+ * @param {AbortSignal?} [signal]
464
+ * @param {((v: Params) => void)?} [setParams]
465
+ * @returns {Promise<T[] | null>}
466
+ */
467
+ static async #find(route, method, path, params, signal, setParams) {
468
+ if (!(route instanceof Router)) {
469
+ if (typeof setParams === 'function') { setParams(params); }
470
+ // @ts-ignore
471
+ return [route].flat();
472
+ }
473
+ if (route.disabled) { return null; }
474
+ if (signal?.aborted) { return null; }
475
+ for await (const [r, result, p] of route.find(method, path)) {
476
+ if (signal?.aborted) { return null; }
477
+ const res = await Router.#find(r, method, p, { ...params, ...result }, signal, setParams);
478
+ if (res) { return [...route.#guards, ...res]; }
479
+ }
480
+ return null;
481
+ }
482
+ /**
483
+ *
484
+ * @template {Function} T
485
+ * @param {Router<T>[]} routers
486
+ * @param {Method} method
487
+ * @param {string[]} path
488
+ * @param {AbortSignal?} [signal]
489
+ * @param {((v: Params) => void)?} [setParams]
490
+ * @returns {Promise<T[] | null>}
491
+ */
492
+ static async find(routers, method, path, signal, setParams) {
493
+ const m = `${method}`.toUpperCase();
494
+ for (const route of routers.flat()) {
495
+ const res = await Router.#find(route, m, path, {}, signal, setParams);
496
+ if (res) { return res; }
497
+ }
498
+ return null;
499
+ }
500
+ /**
501
+ * @abstract
502
+ * @param {Method} method
503
+ * @param {string[]} path
504
+ * @returns {AsyncIterable<FindItem<T>> | Iterable<FindItem<T>>}
505
+ */
506
+ find(method, path) { return []; }
507
+
508
+
509
+ /** @type {T[]} */
510
+ #guards = [];
511
+ /**
512
+ *
513
+ * @param {...T | T[]} guards
514
+ */
515
+ guard(...guards) {
516
+ const list = this.#guards;
517
+ for (const guard of guards.flat()) {
518
+ if (typeof guard !== 'function') { continue; }
519
+ // @ts-ignore
520
+ list.push(guard);
521
+ }
522
+ }
523
+
524
+ /**
525
+ *
526
+ * @template {Function} T
527
+ * @param {Finder<T>} find
528
+ * @returns {Router<T>}
529
+ */
530
+ static create(find) {
531
+ return Object.defineProperties(new Router(), {
532
+ 'find': { configurable: true, value: find, writable: true },
533
+ });
534
+ }
445
535
  }
446
536
 
447
- /** @import { Context, Handler, HandlerResult } from './main/types' */
537
+ /** @import { FindHandler, Handler, Options } from './main/types' */
538
+
539
+ /**
540
+ *
541
+ * @param {string} t
542
+ * @returns
543
+ */
544
+ function uriDecode(t) {
545
+ try {
546
+ return decodeURIComponent(t);
547
+ } catch {
548
+ return t;
549
+ }
550
+ }
448
551
  /**
449
552
  *
450
- * @param {Context} context
451
- * @param {Handler[]} handlers
452
- * @returns {Promise<HandlerResult>}
553
+ * @param {Router<Handler> | Router<Handler>[] | FindHandler} routers
554
+ * @param {Options} options
555
+ * @returns {(request: Request) => Promise<Response | null>}
453
556
  */
454
- async function runHandles(context, handlers) {
455
- for (const handle of handlers) {
456
- const result = await handle(context);
457
- if (result === undefined) { continue; }
458
- return result;
557
+ function make(routers, options) {
558
+ if (typeof routers === 'function') {
559
+ return r => main(r, routers, options);
459
560
  }
561
+ const list = [routers].flat();
562
+ /** @type {FindHandler} */
563
+ const getHandler = (ctx, setParams) => {
564
+ const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
565
+ return Router.find(list, ctx.method, path, ctx.signal, setParams);
566
+ };
567
+ return r => main(r, getHandler, options);
460
568
  }
461
569
 
570
+ /** @import { FindHandler, Options } from './main/types' */
571
+
462
572
  /**
463
573
  *
464
- * @param {...(Handler | Handler[])} handlers
465
- * @returns {Handler}
574
+ * @param {FindHandler} getHandler
575
+ * @param {Options} options
576
+ * @returns {(request: Request) => Promise<Response | null>}
466
577
  */
467
- function merge(...handlers) {
468
- return ctx => runHandles(ctx, handlers.flat());
578
+ function bind$1(getHandler, options) {
579
+ return r => main(r, getHandler, options);
469
580
  }
470
581
 
471
582
  /** @import { Context, Service } from './main/types' */
@@ -647,151 +758,6 @@
647
758
  return service;
648
759
  }
649
760
 
650
- /** @import { Handler } from './main/types' */
651
- /** @import { Onionskin } from './onionskin.mjs' */
652
- /**
653
- * @callback Packer
654
- * @param {Handler | Handler[]} handler
655
- * @returns {Handler | Handler[]}
656
- */
657
-
658
-
659
- /** @type {Packer} */
660
- const noop$1 = h => h;
661
- /**
662
- *
663
- * @param {Onionskin} onionskin
664
- * @param {Packer} [packer]
665
- * @returns {Packer}
666
- */
667
- function packer(onionskin, packer = noop$1) {
668
- return h => {
669
- const handler = packer(h);
670
- return async (ctx) => onionskin(ctx, async () => runHandles(ctx, [handler].flat()));
671
- };
672
- }
673
-
674
- /** @import { Context, FindHandler, Handler, Method, Params } from './main/types' */
675
- /** @import { Onionskin } from './onionskin.mjs' */
676
-
677
- /**
678
- * @callback Guard
679
- * @param {Context} ctx
680
- * @returns {PromiseLike<boolean | Handler | void> | boolean | Handler | void}
681
- */
682
- /**
683
- * @typedef {[Handler | Handler[] | Router, Record<string | symbol, any>, string[]]} FindItem
684
- */
685
- /**
686
- * @callback Finder
687
- * @this {Router}
688
- * @param {Method} method
689
- * @param {string[]} path
690
- * @param {Context} ctx
691
- * @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
692
- */
693
-
694
-
695
- /**
696
- *
697
- * @param {string} t
698
- * @returns
699
- */
700
- function uriDecode(t) {
701
- try {
702
- return decodeURIComponent(t);
703
- } catch {
704
- return t;
705
- }
706
- }
707
- /**
708
- * @abstract
709
- */
710
- class Router {
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
- }
735
- /**
736
- * @abstract
737
- * @param {Method} method
738
- * @param {string[]} path
739
- * @param {Context} ctx
740
- * @returns {AsyncIterable<FindItem> | Iterable<FindItem>}
741
- */
742
- find(method, path, ctx) { return []; }
743
- /**
744
- *
745
- * @param {Router[]} routers
746
- * @returns {FindHandler}
747
- */
748
- static make(routers) {
749
- return async (ctx, setParams) => {
750
- const list = routers.flat();
751
- const path = ctx.url.pathname.split('/').filter(Boolean).map(uriDecode);
752
- for (const route of list) {
753
- const res = await Router.#find(route, path, ctx, setParams, {});
754
- if (res) { return res; }
755
- }
756
- return null;
757
- };
758
- }
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
-
775
- /**
776
- *
777
- * @param {Finder} find
778
- * @returns {Router}
779
- */
780
- static create(find) {
781
- return Object.defineProperties(new Router(), {
782
- 'find': { configurable: true, value: find, writable: true },
783
- });
784
- }
785
- /**
786
- *
787
- * @param {Handler | Handler[]} h
788
- * @returns {Handler | Handler[]}
789
- */
790
- #onionskin = (h) => h;
791
- /** @param {Onionskin} os */
792
- onionskin(os) { this.#onionskin = packer(os, this.#onionskin); }
793
- }
794
-
795
761
  /** @import { Match } from './index.mjs' */
796
762
  /** @import { Params } from '../main/types.js' */
797
763
  /**
@@ -974,19 +940,20 @@
974
940
  return path => exec(list, path, end);
975
941
  }
976
942
 
977
- /** @import { Handler, Method } from '../main/types' */
943
+ /** @import { Method } from '../main/types' */
978
944
  /** @import { Binder, Match, Route, RouterRoute } from './index.mjs' */
979
945
 
980
946
  /**
981
947
  *
982
- * @param {(Route | RouterRoute)[]} routes
948
+ * @template {Function} T
949
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
983
950
  * @param {Set<Method>} methods
984
951
  * @param {Match | undefined} match
985
- * @param {Handler[]} handlers
952
+ * @param {T[]} handlers
986
953
  * @returns {() => void}
987
954
  */
988
955
  function bind(routes, methods, match, handlers) {
989
- /** @type {Route} */
956
+ /** @type {Route<T>} */
990
957
  const route = { match, methods, handlers: handlers };
991
958
  routes.push(route);
992
959
  let removed = false;
@@ -998,45 +965,45 @@
998
965
  routes.splice(index, 1);
999
966
  };
1000
967
  }
1001
- /** @type {(v: any) => v is Handler} */
968
+ /** @type {(v: any) => v is Function} */
1002
969
  const findHandler = v => typeof v === 'function';
1003
970
  /**
1004
971
  *
1005
- * @param {(Route | RouterRoute)[]} routes
972
+ * @template {Function} T
973
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
1006
974
  * @param {Iterable<Method>} methods
1007
975
  * @param {any[]} p
1008
- * @returns {Binder | (() => void)}
976
+ * @returns {Binder<T> | (() => void)}
1009
977
  */
1010
978
  function verb(routes, methods, p) {
1011
979
  const methodSet = new Set(methods);
1012
980
  if (!p.length) {
1013
981
  const match = undefined;
1014
- /** @type {Binder} */
982
+ /** @type {Binder<T>} */
1015
983
  return (...handlers) => bind(routes, methodSet, match, handlers);
1016
984
  }
1017
985
  const [path] = p;
1018
986
  if (path && typeof path === 'object') {
1019
987
  const match = toMatch([path, p.slice(1)], true);
1020
- /** @type {Binder} */
988
+ /** @type {Binder<T>} */
1021
989
  return (...handlers) => bind(routes, methodSet, match, handlers);
1022
990
  }
1023
991
  const match = toMatch(typeof path === 'string' ? path : '', true);
1024
992
  const handlers = p.filter(findHandler);
1025
993
  if (!handlers.length) {
1026
- /** @type {Binder} */
994
+ /** @type {Binder<T>} */
1027
995
  return (...handlers) => bind(routes, methodSet, match, handlers);
1028
996
  }
1029
997
  return bind(routes, methodSet, match, handlers);
1030
998
  }
1031
999
 
1032
1000
  /** @import { Method } from '../main/types' */
1033
- const methods = new Set(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']);
1034
1001
  /**
1035
1002
  *
1036
1003
  * @param {any} v
1037
1004
  * @returns {v is Method}
1038
1005
  */
1039
- function isMethod(v) { return methods.has(v); }
1006
+ function isMethod(v) { return Boolean(v); }
1040
1007
  /**
1041
1008
  *
1042
1009
  * @param {Method | Iterable<Method> | ArrayLike<Method>} [methods]
@@ -1054,7 +1021,7 @@
1054
1021
  .filter(isMethod);
1055
1022
  }
1056
1023
 
1057
- /** @import { Context, Handler, Method, Params } from '../main/types' */
1024
+ /** @import { Handler, Method, Params } from '../main/types' */
1058
1025
  /** @import { Finder, FindItem } from '../Router.mjs' */
1059
1026
 
1060
1027
  /**
@@ -1063,78 +1030,125 @@
1063
1030
  * @returns {[Params, string[]] | undefined}
1064
1031
  */
1065
1032
 
1066
- /** @typedef {(handler: Handler, ...handlers: Handler[]) => () => void} Binder */
1033
+ /**
1034
+ * @template {Function} T
1035
+ * @typedef {(handler: T, ...handlers: T[]) => () => void} Binder
1036
+ */
1037
+
1067
1038
 
1068
1039
  /**
1040
+ * @template {Function} T
1041
+ * @callback Verb1
1042
+ * @param {T} handler 要注册的处理函数
1043
+ * @param {...T} handlers 要注册的处理函数
1044
+ * @returns {() => void}
1045
+ */
1046
+ /**
1047
+ * @template {Function} T
1048
+ * @callback Verb2
1049
+ * @param {string} path 要注册的路径
1050
+ * @param {T} handler 要注册的处理函数
1051
+ * @param {...T} handlers 要注册的处理函数
1052
+ * @returns {() => void}
1053
+ */
1054
+ /**
1055
+ * @template {Function} T
1056
+ * @callback Verb3
1057
+ * @param {string} path 要注册的路径
1058
+ * @returns {Binder<T>}
1059
+ */
1060
+ /**
1061
+ * @template {Function} T
1062
+ * @callback Verb4
1063
+ * @param {TemplateStringsArray} template 要注册的路径模板
1064
+ * @param {...any} substitutions 要注册的路径模板代替内容
1065
+ * @returns {Binder<T>}
1066
+ */
1067
+ /**
1068
+ * @template {Function} T
1069
+ * @typedef {Verb1<T> & Verb2<T> & Verb3<T> & Verb4<T>} Verb
1070
+ */
1071
+
1072
+ /**
1073
+ * @template {Function} T
1069
1074
  * @typedef {object} Route
1070
1075
  * @property {Match} [match] 路径匹配
1071
1076
  * @property {null} [router]
1072
- * @property {Handler[]} handlers 处理函数
1077
+ * @property {T[]} handlers 处理函数
1073
1078
  * @property {Set<Method>} methods 方法列表
1074
1079
  */
1075
1080
 
1076
1081
  /**
1082
+ * @template {Function} T
1077
1083
  * @typedef {object} RouterRoute
1078
1084
  * @property {Match} [match] 路径匹配
1079
- * @property {Router} router
1085
+ * @property {Router<T>} router
1080
1086
  */
1081
1087
 
1082
1088
 
1083
1089
  /**
1084
- * @template {Router | Finder} [T=ApiRouter]
1090
+ * @template {Function} T
1091
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1085
1092
  * @callback RouteBinder
1086
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1087
- * @returns {T extends Finder ? Router : T}
1093
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1094
+ * @returns {P extends Finder<T> ? Router<T> : P}
1088
1095
  */
1089
1096
  /**
1090
1097
  *
1091
- * @param {(Route | RouterRoute)[]} routes
1098
+ * @template {Function} T
1099
+ * @param {(Route<T> | RouterRoute<T>)[]} routes
1092
1100
  * @param {string | [string[], any[]]} path
1093
- * @param {Router | Finder} [r]
1094
- * @returns {Router}
1101
+ * @param {Router<T> | Finder<T>} [r]
1102
+ * @returns {Router<T>}
1095
1103
  */
1096
1104
  function bindRouter(routes, path, r) {
1105
+ /** @type {Router<T>} */
1097
1106
  const router = r instanceof Router ? r
1098
1107
  : typeof r === 'function' ? Router.create(r)
1099
- : new ApiRouter();
1108
+ : new MapRouter();
1100
1109
  routes.push({ match: toMatch(path, false), router });
1101
1110
  return router;
1102
1111
  }
1103
- class ApiRouter extends Router {
1104
- /** @readonly @type {(Route | RouterRoute)[]} 路由列表 */
1112
+ /**
1113
+ *
1114
+ * @template {Function} T
1115
+ * @extends {Router<T>}
1116
+ */
1117
+ class MapRouter extends Router {
1118
+ /** @readonly @type {(Route<T> | RouterRoute<T>)[]} 路由列表 */
1105
1119
  #routes = [];
1106
1120
  /**
1107
1121
  * 添加子路由
1108
- * @template {Router | Finder} [T=ApiRouter]
1122
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1109
1123
  * @overload
1110
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1111
- * @returns {T extends Finder ? Router : T}
1124
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1125
+ * @returns {P extends Finder<T> ? Router<T> : P}
1112
1126
  */
1113
1127
  /**
1114
1128
  * 添加子路由
1115
- * @template {Router | Finder} [T=ApiRouter]
1129
+ * @template {Router<T> | Finder<T>} [P=MapRouter<T>]
1116
1130
  * @overload
1117
1131
  * @param {string} path 要注册的路径
1118
- * @param {T} [router] 要注册的子路由或子路由的 Finder
1119
- * @returns {T extends Finder ? Router : T}
1132
+ * @param {P} [router] 要注册的子路由或子路由的 Finder<T>
1133
+ * @returns {P extends Finder<T> ? Router<T> : P}
1120
1134
  */
1121
1135
  /**
1122
1136
  * 添加子路由
1123
1137
  * @overload
1124
1138
  * @param {TemplateStringsArray} template 要注册的路径模板
1125
1139
  * @param {...any} substitutions 要注册的路径模板代替内容
1126
- * @returns {RouteBinder}
1140
+ * @returns {RouteBinder<T>}
1127
1141
  */
1128
1142
  /**
1129
1143
  * 添加子路由
1130
1144
  * @param {...any} p 要注册的路径
1131
- * @returns {Router | RouteBinder}
1145
+ * @returns {Router<T> | RouteBinder<T>}
1132
1146
  */
1133
1147
  route(...p) {
1134
1148
  const [a] = p;
1135
1149
  if (a && typeof a === 'object' && !(a instanceof Router)) {
1136
1150
  /**
1137
- * @param { Finder | Router} [r];
1151
+ * @param { Finder<T> | Router<T>} [r];
1138
1152
  * @returns {any}
1139
1153
  */
1140
1154
  return r => bindRouter(this.#routes, [a, p.slice(1)], r);
@@ -1147,10 +1161,9 @@
1147
1161
  *
1148
1162
  * @param {Method} method
1149
1163
  * @param {string[]} path
1150
- * @param {Context} ctx
1151
- * @returns {Iterable<FindItem>}
1164
+ * @returns {Iterable<FindItem<T>>}
1152
1165
  */
1153
- *find(method, path, ctx) {
1166
+ *find(method, path) {
1154
1167
  for (const route of Array.from(this.#routes)) {
1155
1168
  if (!route.router && !route.methods.has(method)) { continue; }
1156
1169
  const {match} = route;
@@ -1170,7 +1183,7 @@
1170
1183
  * 注册处理函数
1171
1184
  * @overload
1172
1185
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1173
- * @param {Handler} handler 要注册的处理函数
1186
+ * @param {T} handler 要注册的处理函数
1174
1187
  * @returns {() => void}
1175
1188
  */
1176
1189
  /**
@@ -1178,7 +1191,7 @@
1178
1191
  * @overload
1179
1192
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1180
1193
  * @param {string} path 要注册的路径
1181
- * @param {Handler} handler 要注册的处理函数
1194
+ * @param {T} handler 要注册的处理函数
1182
1195
  * @returns {() => void}
1183
1196
  */
1184
1197
  /**
@@ -1186,48 +1199,58 @@
1186
1199
  * @overload
1187
1200
  * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1188
1201
  * @param {string} path 要注册的路径
1189
- * @returns {Binder}
1202
+ * @returns {Binder<T>}
1190
1203
  */
1191
1204
  /**
1192
1205
  * @param {Method | Iterable<Method> | ArrayLike<Method>} methods
1193
- * @param {string| Handler} [path]
1194
- * @param {...Handler} handler
1195
- * @returns {Binder | (() => void)}
1206
+ * @param {string| T} [path]
1207
+ * @param {...T} handler
1208
+ * @returns {Binder<T> | (() => void)}
1196
1209
  */
1197
1210
  verb(methods, path, ...handler) {
1198
1211
  const allMethods = getMethods(methods);
1199
1212
  if (!allMethods.length) { return () => {}; }
1200
1213
  return verb(this.#routes, allMethods, [path, ...handler]);
1201
1214
  }
1215
+
1216
+ /**
1217
+ * @param {Method | Iterable<Method> | ArrayLike<Method>} method 要注册的方法
1218
+ * @returns {Verb<T>}
1219
+ */
1220
+ method(method) {
1221
+ const methods = getMethods(method);
1222
+ // @ts-ignore
1223
+ return (...p) => verb(this.#routes, methods, p);
1224
+ }
1202
1225
  /**
1203
1226
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1204
1227
  * @overload
1205
- * @param {...Handler} handlers 要注册的处理函数
1228
+ * @param {...T} handlers 要注册的处理函数
1206
1229
  * @returns {() => void}
1207
1230
  */
1208
1231
  /**
1209
1232
  * 注册处理函数
1210
1233
  * @overload
1211
1234
  * @param {string} path 要注册的路径
1212
- * @param {...Handler} handlers 要注册的处理函数
1235
+ * @param {...T} handlers 要注册的处理函数
1213
1236
  * @returns {() => void}
1214
1237
  */
1215
1238
  /**
1216
1239
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1217
1240
  * @overload
1218
1241
  * @param {string} path 要注册的路径
1219
- * @returns {Binder}
1242
+ * @returns {Binder<T>}
1220
1243
  */
1221
1244
  /**
1222
1245
  * 注册 HTTP GET/POST/PUT/DELETE 处理函数
1223
1246
  * @overload
1224
1247
  * @param {TemplateStringsArray} template 要注册的路径模板
1225
1248
  * @param {...any} substitutions 要注册的路径模板代替内容
1226
- * @returns {Binder}
1249
+ * @returns {Binder<T>}
1227
1250
  */
1228
1251
  /**
1229
1252
  * @param {...any} p 要注册的路径
1230
- * @returns {Binder | (() => void)}
1253
+ * @returns {Binder<T> | (() => void)}
1231
1254
  */
1232
1255
  match(...p) {
1233
1256
  return verb(this.#routes, ['GET', 'POST', 'PUT', 'DELETE'], p);
@@ -1249,18 +1272,18 @@
1249
1272
  * 注册 HTTP GET 处理函数
1250
1273
  * @overload
1251
1274
  * @param {string} path 要注册的路径
1252
- * @returns {Binder}
1275
+ * @returns {Binder<T>}
1253
1276
  */
1254
1277
  /**
1255
1278
  * 注册 HTTP GET 处理函数
1256
1279
  * @overload
1257
1280
  * @param {TemplateStringsArray} template 要注册的路径模板
1258
1281
  * @param {...any} substitutions 要注册的路径模板代替内容
1259
- * @returns {Binder}
1282
+ * @returns {Binder<T>}
1260
1283
  */
1261
1284
  /**
1262
1285
  * @param {...any} p 要注册的路径
1263
- * @returns {Binder | (() => void)}
1286
+ * @returns {Binder<T> | (() => void)}
1264
1287
  */
1265
1288
  get(...p) { return verb(this.#routes, ['GET'], p); }
1266
1289
  /**
@@ -1280,18 +1303,18 @@
1280
1303
  * 注册 HTTP POST 处理函数
1281
1304
  * @overload
1282
1305
  * @param {string} path 要注册的路径
1283
- * @returns {Binder}
1306
+ * @returns {Binder<T>}
1284
1307
  */
1285
1308
  /**
1286
1309
  * 注册 HTTP POST 处理函数
1287
1310
  * @overload
1288
1311
  * @param {TemplateStringsArray} template 要注册的路径模板
1289
1312
  * @param {...any} substitutions 要注册的路径模板代替内容
1290
- * @returns {Binder}
1313
+ * @returns {Binder<T>}
1291
1314
  */
1292
1315
  /**
1293
1316
  * @param {...any} p 要注册的路径
1294
- * @returns {Binder | (() => void)}
1317
+ * @returns {Binder<T> | (() => void)}
1295
1318
  */
1296
1319
  post(...p) { return verb(this.#routes, ['POST'], p); }
1297
1320
  /**
@@ -1311,18 +1334,18 @@
1311
1334
  * 注册 HTTP PUT 处理函数
1312
1335
  * @overload
1313
1336
  * @param {string} path 要注册的路径
1314
- * @returns {Binder}
1337
+ * @returns {Binder<T>}
1315
1338
  */
1316
1339
  /**
1317
1340
  * 注册 HTTP PUT 处理函数
1318
1341
  * @overload
1319
1342
  * @param {TemplateStringsArray} template 要注册的路径模板
1320
1343
  * @param {...any} substitutions 要注册的路径模板代替内容
1321
- * @returns {Binder}
1344
+ * @returns {Binder<T>}
1322
1345
  */
1323
1346
  /**
1324
1347
  * @param {...any} p 要注册的路径
1325
- * @returns {Binder | (() => void)}
1348
+ * @returns {Binder<T> | (() => void)}
1326
1349
  */
1327
1350
  put(...p) { return verb(this.#routes, ['PUT'], p); }
1328
1351
  /**
@@ -1342,18 +1365,18 @@
1342
1365
  * 注册 HTTP DELETE 处理函数
1343
1366
  * @overload
1344
1367
  * @param {string} path 要注册的路径
1345
- * @returns {Binder}
1368
+ * @returns {Binder<T>}
1346
1369
  */
1347
1370
  /**
1348
1371
  * 注册 HTTP DELETE 处理函数
1349
1372
  * @overload
1350
1373
  * @param {TemplateStringsArray} template 要注册的路径模板
1351
1374
  * @param {...any} substitutions 要注册的路径模板代替内容
1352
- * @returns {Binder}
1375
+ * @returns {Binder<T>}
1353
1376
  */
1354
1377
  /**
1355
1378
  * @param {...any} p 要注册的路径
1356
- * @returns {Binder | (() => void)}
1379
+ * @returns {Binder<T> | (() => void)}
1357
1380
  */
1358
1381
  delete(...p) { return verb(this.#routes, ['DELETE'], p); }
1359
1382
  /**
@@ -1373,18 +1396,18 @@
1373
1396
  * 注册 HTTP HEAD 处理函数
1374
1397
  * @overload
1375
1398
  * @param {string} path 要注册的路径
1376
- * @returns {Binder}
1399
+ * @returns {Binder<T>}
1377
1400
  */
1378
1401
  /**
1379
1402
  * 注册 HTTP HEAD 处理函数
1380
1403
  * @overload
1381
1404
  * @param {TemplateStringsArray} template 要注册的路径模板
1382
1405
  * @param {...any} substitutions 要注册的路径模板代替内容
1383
- * @returns {Binder}
1406
+ * @returns {Binder<T>}
1384
1407
  */
1385
1408
  /**
1386
1409
  * @param {...any} p 要注册的路径
1387
- * @returns {Binder | (() => void)}
1410
+ * @returns {Binder<T> | (() => void)}
1388
1411
  */
1389
1412
  head(...p) { return verb(this.#routes, ['HEAD'], p); }
1390
1413
  /**
@@ -1404,18 +1427,18 @@
1404
1427
  * 注册 HTTP OPTIONS 处理函数
1405
1428
  * @overload
1406
1429
  * @param {string} path 要注册的路径
1407
- * @returns {Binder}
1430
+ * @returns {Binder<T>}
1408
1431
  */
1409
1432
  /**
1410
1433
  * 注册 HTTP OPTIONS 处理函数
1411
1434
  * @overload
1412
1435
  * @param {TemplateStringsArray} template 要注册的路径模板
1413
1436
  * @param {...any} substitutions 要注册的路径模板代替内容
1414
- * @returns {Binder}
1437
+ * @returns {Binder<T>}
1415
1438
  */
1416
1439
  /**
1417
1440
  * @param {...any} p 要注册的路径
1418
- * @returns {Binder | (() => void)}
1441
+ * @returns {Binder<T> | (() => void)}
1419
1442
  */
1420
1443
  options(...p) { return verb(this.#routes, ['OPTIONS'], p); }
1421
1444
  }
@@ -1443,30 +1466,6 @@
1443
1466
  };
1444
1467
  }
1445
1468
 
1446
- /** @import { Context, Handler, HandlerResult } from './main/types' */
1447
- /**
1448
- * @callback Onionskin
1449
- * @param {Context} ctx
1450
- * @param {() => Promise<HandlerResult>} next
1451
- * @returns {PromiseLike<HandlerResult> | HandlerResult}
1452
- */
1453
-
1454
- const noop = () => {};
1455
- /**
1456
- *
1457
- * @param {...(Onionskin | Onionskin[])} handlers
1458
- * @returns {Handler}
1459
- */
1460
- function onionskin(...handlers) {
1461
- /** @type {Handler} */
1462
- let handler = noop;
1463
- for (const os of handlers.flat()) {
1464
- const currentHandler = handler;
1465
- handler = async ctx => os(ctx, async () => currentHandler(ctx));
1466
- }
1467
- return handler;
1468
- }
1469
-
1470
1469
  /** @import { Context } from './main/types.js' */
1471
1470
  class Param {
1472
1471
  #symbol = Symbol();
@@ -1503,15 +1502,13 @@
1503
1502
  }
1504
1503
  }
1505
1504
 
1506
- exports.ApiRouter = ApiRouter;
1505
+ exports.MapRouter = MapRouter;
1507
1506
  exports.Param = Param;
1508
1507
  exports.Router = Router;
1508
+ exports.bind = bind$1;
1509
1509
  exports.createFetch = createFetch;
1510
1510
  exports.main = main;
1511
1511
  exports.make = make;
1512
- exports.merge = merge;
1513
- exports.onionskin = onionskin;
1514
- exports.packer = packer;
1515
1512
  exports.service = service;
1516
1513
  exports.stateService = stateService;
1517
1514
  exports.storeService = storeService;