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