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