@taserjs/router 0.1.6 → 0.1.8
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/dist/cjs/builder/factories.cjs +2 -0
- package/dist/cjs/builder/factories.cjs.map +1 -1
- package/dist/cjs/builder/factories.d.cts +2 -1
- package/dist/cjs/builder/standalone.cjs +3 -0
- package/dist/cjs/builder/standalone.cjs.map +1 -1
- package/dist/cjs/builder/standalone.d.cts +2 -0
- package/dist/cjs/define/middleware.cjs.map +1 -1
- package/dist/cjs/define/middleware.d.cts +20 -20
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/index.d.cts +6 -2
- package/dist/cjs/middleware/hono-mw.cjs.map +1 -1
- package/dist/cjs/middleware/hono-mw.d.cts +2 -1
- package/dist/cjs/types/index.d.cts +90 -64
- package/dist/cjs/types/type-utils.d.cts +3 -3
- package/dist/cjs/types/units.d.cts +26 -20
- package/dist/esm/builder/factories.d.ts +2 -1
- package/dist/esm/builder/factories.js +2 -1
- package/dist/esm/builder/factories.js.map +1 -1
- package/dist/esm/builder/standalone.d.ts +2 -0
- package/dist/esm/builder/standalone.js +4 -2
- package/dist/esm/builder/standalone.js.map +1 -1
- package/dist/esm/define/middleware.d.ts +20 -20
- package/dist/esm/define/middleware.js.map +1 -1
- package/dist/esm/index.d.ts +6 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/middleware/hono-mw.d.ts +2 -1
- package/dist/esm/middleware/hono-mw.js.map +1 -1
- package/dist/esm/types/index.d.ts +90 -64
- package/dist/esm/types/type-utils.d.ts +3 -3
- package/dist/esm/types/units.d.ts +26 -20
- package/package.json +3 -3
- package/src/builder/factories.ts +3 -2
- package/src/builder/standalone.ts +5 -0
- package/src/define/middleware.ts +68 -60
- package/src/index.ts +4 -0
- package/src/middleware/hono-mw.ts +5 -3
- package/src/types/index.ts +215 -130
- package/src/types/type-utils.ts +1 -1
- package/src/types/units.ts +47 -22
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export interface RouterRegister {}
|
|
2
|
+
export interface RouterMiddlewaresRegister {}
|
|
3
|
+
export interface RouterRoutesRegister {}
|
|
2
4
|
export type {
|
|
3
5
|
AppContext,
|
|
4
6
|
EmptyAppContext,
|
|
@@ -11,6 +13,7 @@ export type {
|
|
|
11
13
|
InferRouteOutput,
|
|
12
14
|
LayoutBuilder,
|
|
13
15
|
LayoutId,
|
|
16
|
+
LayoutMiddlewaresMap,
|
|
14
17
|
LayoutTree,
|
|
15
18
|
Method,
|
|
16
19
|
MiddlewareBuilder,
|
|
@@ -51,6 +54,7 @@ export {
|
|
|
51
54
|
patch,
|
|
52
55
|
post,
|
|
53
56
|
put,
|
|
57
|
+
query,
|
|
54
58
|
t,
|
|
55
59
|
type TaserNamespace,
|
|
56
60
|
} from "./builder/standalone.js";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createTaserCompatHandler } from "@taserjs/router-core";
|
|
2
2
|
import type { MiddlewareHandler } from "hono";
|
|
3
3
|
|
|
4
|
+
import type { NextFn } from "../types/units.js";
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`
|
|
6
8
|
* into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.
|
|
@@ -15,8 +17,8 @@ import type { MiddlewareHandler } from "hono";
|
|
|
15
17
|
* const customCors = middleware(honoMw(cors()));
|
|
16
18
|
* ```
|
|
17
19
|
*/
|
|
18
|
-
export function honoMw(
|
|
20
|
+
export function honoMw<TState extends Record<string, unknown> = {}>(
|
|
19
21
|
middleware: MiddlewareHandler,
|
|
20
|
-
): (ctx: unknown, next:
|
|
21
|
-
return createTaserCompatHandler(middleware) as (ctx: unknown, next:
|
|
22
|
+
): (ctx: unknown, next: NextFn<TState>) => Promise<Response> {
|
|
23
|
+
return createTaserCompatHandler(middleware) as (ctx: unknown, next: NextFn<TState>) => Promise<Response>;
|
|
22
24
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Awaitable, TaserCookieJar, TaserHeaders } from "@taserjs/router-core";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
RouterMiddlewaresRegister,
|
|
4
|
+
RouterRegister,
|
|
5
|
+
RouterRoutesRegister,
|
|
6
|
+
} from "../index.js";
|
|
3
7
|
import type {
|
|
4
8
|
MergeMiddlewareField,
|
|
5
9
|
MergeMiddlewareInputField,
|
|
@@ -16,6 +20,7 @@ import type {
|
|
|
16
20
|
ExtractState,
|
|
17
21
|
Method,
|
|
18
22
|
MiddlewareDefinition,
|
|
23
|
+
MiddlewareRequirements,
|
|
19
24
|
MiddlewareReturnFromParts,
|
|
20
25
|
MiddlewareUnit,
|
|
21
26
|
NextFn,
|
|
@@ -57,6 +62,7 @@ export type {
|
|
|
57
62
|
IsUnknown,
|
|
58
63
|
Method,
|
|
59
64
|
MiddlewareDefinition,
|
|
65
|
+
MiddlewareRequirements,
|
|
60
66
|
MiddlewareReturnFromParts,
|
|
61
67
|
MiddlewareUnit,
|
|
62
68
|
MiddlewareUnitBuilder,
|
|
@@ -72,9 +78,18 @@ export type AppContext = RouterRegister extends { AppContext: infer C } ? C : Em
|
|
|
72
78
|
export type RoutePath = RouterRegister extends { RoutePath: infer P } ? P : never;
|
|
73
79
|
export type LayoutId = RouterRegister extends { LayoutId: infer L } ? L : never;
|
|
74
80
|
export type LayoutTree = RouterRegister extends { LayoutTree: infer T } ? T : Record<never, never>;
|
|
75
|
-
export type
|
|
81
|
+
export type LayoutMiddlewaresMap = RouterMiddlewaresRegister extends {
|
|
82
|
+
LayoutMiddlewares: infer M;
|
|
83
|
+
}
|
|
84
|
+
? M
|
|
85
|
+
: RouterRegister extends { LayoutMiddlewares: infer M }
|
|
86
|
+
? M
|
|
87
|
+
: Record<never, never>;
|
|
88
|
+
export type RouteByPathMethod = RouterRoutesRegister extends { RouteByPathMethod: infer R }
|
|
76
89
|
? R
|
|
77
|
-
:
|
|
90
|
+
: RouterRegister extends { RouteByPathMethod: infer R }
|
|
91
|
+
? R
|
|
92
|
+
: Record<never, never>;
|
|
78
93
|
|
|
79
94
|
export type LayoutBuilder<TAppContext extends Record<string, unknown> = AppContext> = <
|
|
80
95
|
const Layout extends LayoutId,
|
|
@@ -105,40 +120,32 @@ export type ResolveParams<TPathParams, TSchemaParams> =
|
|
|
105
120
|
: Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams>
|
|
106
121
|
: TPathParams;
|
|
107
122
|
|
|
108
|
-
type
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
? LP
|
|
112
|
-
: {};
|
|
113
|
-
|
|
114
|
-
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutParentsMap
|
|
115
|
-
? LayoutParentsMap[Layout] extends LayoutId
|
|
116
|
-
? LayoutParentsMap[Layout]
|
|
123
|
+
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutTree
|
|
124
|
+
? LayoutTree[Layout] extends { parent: infer P extends LayoutId }
|
|
125
|
+
? P
|
|
117
126
|
: null
|
|
118
|
-
:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
: null;
|
|
123
|
-
|
|
124
|
-
type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
|
|
125
|
-
readonly __acc?: infer Acc extends readonly unknown[];
|
|
126
|
-
}
|
|
127
|
-
? Acc
|
|
128
|
-
: LayoutTree[Layout]["middlewares"] extends infer Acc extends readonly unknown[]
|
|
127
|
+
: null;
|
|
128
|
+
|
|
129
|
+
type LayoutMiddlewares<Layout extends LayoutId> = [Layout] extends [keyof LayoutMiddlewaresMap]
|
|
130
|
+
? LayoutMiddlewaresMap[Layout] extends { readonly __acc?: infer Acc extends readonly unknown[] }
|
|
129
131
|
? Acc
|
|
130
|
-
: readonly []
|
|
132
|
+
: LayoutMiddlewaresMap[Layout] extends readonly unknown[]
|
|
133
|
+
? LayoutMiddlewaresMap[Layout]
|
|
134
|
+
: readonly []
|
|
135
|
+
: readonly [];
|
|
131
136
|
|
|
132
137
|
type ResolveLayoutMiddlewares<
|
|
133
138
|
Layout extends LayoutId | null,
|
|
134
139
|
Depth extends readonly unknown[] = [],
|
|
135
140
|
> = Depth["length"] extends 10
|
|
136
141
|
? readonly []
|
|
137
|
-
: Layout extends LayoutId
|
|
138
|
-
?
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
: [Layout] extends [LayoutId]
|
|
143
|
+
? LayoutParent<Layout> extends infer Parent extends LayoutId
|
|
144
|
+
? readonly [
|
|
145
|
+
...ResolveLayoutMiddlewares<Parent, [...Depth, unknown]>,
|
|
146
|
+
...LayoutMiddlewares<Layout>,
|
|
147
|
+
]
|
|
148
|
+
: readonly [...LayoutMiddlewares<Layout>]
|
|
142
149
|
: readonly [];
|
|
143
150
|
|
|
144
151
|
export type ResolveLayoutIdChain<
|
|
@@ -182,17 +189,10 @@ type RouteEntry<Path extends RoutePath, TMethod extends Method> = RouteByPathMet
|
|
|
182
189
|
? Entry
|
|
183
190
|
: never;
|
|
184
191
|
|
|
185
|
-
type RouteParent<Path extends RoutePath, TMethod extends Method> =
|
|
186
|
-
RouteEntry<Path, TMethod> extends { parent: infer Parent extends LayoutId | null }
|
|
187
|
-
? Parent
|
|
188
|
-
: null;
|
|
189
|
-
|
|
190
192
|
type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> =
|
|
191
|
-
RouteEntry<Path, TMethod> extends {
|
|
193
|
+
RouteEntry<Path, TMethod> extends { layouts: infer Chain extends readonly LayoutId[] }
|
|
192
194
|
? Chain
|
|
193
|
-
:
|
|
194
|
-
? readonly [RouteParent<Path, TMethod>]
|
|
195
|
-
: readonly [];
|
|
195
|
+
: readonly [];
|
|
196
196
|
|
|
197
197
|
export type RouteLayoutMiddlewares<
|
|
198
198
|
Path extends RoutePath,
|
|
@@ -229,15 +229,13 @@ export type RouteChainContext<
|
|
|
229
229
|
> = Simplify<
|
|
230
230
|
TAppContext &
|
|
231
231
|
UnitRuntimeContext & {
|
|
232
|
-
query:
|
|
233
|
-
params:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>
|
|
237
|
-
>
|
|
232
|
+
query: MergePart<TQuery, RouteResolvedField<Path, TMethod, Acc, "query">>;
|
|
233
|
+
params: ResolveParams<
|
|
234
|
+
PathParams<Path>,
|
|
235
|
+
MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>
|
|
238
236
|
>;
|
|
239
|
-
body:
|
|
240
|
-
state:
|
|
237
|
+
body: MergePart<TBody, RouteResolvedField<Path, TMethod, Acc, "body">>;
|
|
238
|
+
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
241
239
|
headers: TaserHeaders;
|
|
242
240
|
cookies: TaserCookieJar;
|
|
243
241
|
}
|
|
@@ -352,19 +350,66 @@ export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]
|
|
|
352
350
|
: true
|
|
353
351
|
: true;
|
|
354
352
|
|
|
355
|
-
export type
|
|
353
|
+
export type IsRequirementsSatisfied<
|
|
354
|
+
TActual extends {
|
|
355
|
+
query?: unknown;
|
|
356
|
+
params?: unknown;
|
|
357
|
+
body?: unknown;
|
|
358
|
+
state?: unknown;
|
|
359
|
+
},
|
|
360
|
+
TRequires extends MiddlewareRequirements,
|
|
361
|
+
> = [TRequires] extends [never]
|
|
356
362
|
? true
|
|
357
|
-
: [unknown] extends [
|
|
363
|
+
: [unknown] extends [TRequires]
|
|
358
364
|
? true
|
|
359
|
-
: [null] extends [
|
|
365
|
+
: [null] extends [TRequires]
|
|
360
366
|
? true
|
|
361
|
-
: [undefined] extends [
|
|
367
|
+
: [undefined] extends [TRequires]
|
|
362
368
|
? true
|
|
363
|
-
: [IsEmptyObject<
|
|
369
|
+
: [IsEmptyObject<TRequires>] extends [true]
|
|
364
370
|
? true
|
|
365
|
-
:
|
|
366
|
-
|
|
367
|
-
|
|
371
|
+
: (
|
|
372
|
+
TRequires extends { state: infer S extends Record<string, unknown> }
|
|
373
|
+
? [TActual["state"]] extends [S]
|
|
374
|
+
? true
|
|
375
|
+
: false
|
|
376
|
+
: true
|
|
377
|
+
) extends false
|
|
378
|
+
? false
|
|
379
|
+
: (
|
|
380
|
+
TRequires extends { query: infer Q extends Record<string, unknown> }
|
|
381
|
+
? [TActual["query"]] extends [Q]
|
|
382
|
+
? true
|
|
383
|
+
: false
|
|
384
|
+
: true
|
|
385
|
+
) extends false
|
|
386
|
+
? false
|
|
387
|
+
: (
|
|
388
|
+
TRequires extends { params: infer P extends Record<string, unknown> }
|
|
389
|
+
? [TActual["params"]] extends [P]
|
|
390
|
+
? true
|
|
391
|
+
: false
|
|
392
|
+
: true
|
|
393
|
+
) extends false
|
|
394
|
+
? false
|
|
395
|
+
: (
|
|
396
|
+
TRequires extends { body: infer B }
|
|
397
|
+
? unknown extends B
|
|
398
|
+
? true
|
|
399
|
+
: [TRequires["body"]] extends [undefined]
|
|
400
|
+
? true
|
|
401
|
+
: [TActual["body"]] extends [B]
|
|
402
|
+
? true
|
|
403
|
+
: false
|
|
404
|
+
: true
|
|
405
|
+
) extends false
|
|
406
|
+
? false
|
|
407
|
+
: true;
|
|
408
|
+
|
|
409
|
+
export type IsStateSatisfied<TActualState, TRequiredState> = IsRequirementsSatisfied<
|
|
410
|
+
{ state: TActualState },
|
|
411
|
+
{ state: TRequiredState extends Record<string, unknown> ? TRequiredState : {} }
|
|
412
|
+
>;
|
|
368
413
|
|
|
369
414
|
type InputFacet<T, K extends string> =
|
|
370
415
|
IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : { [Key in K]: T };
|
|
@@ -447,7 +492,9 @@ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Meth
|
|
|
447
492
|
export type MiddlewareLayoutField<
|
|
448
493
|
Layout extends LayoutId,
|
|
449
494
|
Field extends "query" | "params" | "body" | "state",
|
|
450
|
-
> =
|
|
495
|
+
> = [LayoutParent<Layout>] extends [infer Parent extends LayoutId]
|
|
496
|
+
? MergeMiddlewareField<ResolveLayoutMiddlewares<Parent>, Field>
|
|
497
|
+
: {};
|
|
451
498
|
|
|
452
499
|
type MiddlewareChainField<
|
|
453
500
|
Layout extends LayoutId,
|
|
@@ -458,20 +505,22 @@ type MiddlewareChainField<
|
|
|
458
505
|
export type MiddlewareChainContext<
|
|
459
506
|
Layout extends LayoutId,
|
|
460
507
|
Acc extends readonly unknown[],
|
|
461
|
-
TQuery,
|
|
462
|
-
TParams,
|
|
463
|
-
TBody,
|
|
508
|
+
TQuery = unknown,
|
|
509
|
+
TParams = unknown,
|
|
510
|
+
TBody = unknown,
|
|
464
511
|
TAppContext extends Record<string, unknown> = AppContext,
|
|
465
512
|
> = Simplify<
|
|
466
|
-
TAppContext &
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
513
|
+
TAppContext & {
|
|
514
|
+
readonly request: Request;
|
|
515
|
+
readonly method: Method;
|
|
516
|
+
readonly url: URL;
|
|
517
|
+
readonly headers: TaserHeaders;
|
|
518
|
+
readonly cookies: TaserCookieJar;
|
|
519
|
+
query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
520
|
+
params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
521
|
+
body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
522
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
523
|
+
}
|
|
475
524
|
>;
|
|
476
525
|
|
|
477
526
|
export type MiddlewareBuilder<
|
|
@@ -482,29 +531,42 @@ export type MiddlewareBuilder<
|
|
|
482
531
|
readonly layout: Layout;
|
|
483
532
|
readonly middlewares: readonly MiddlewareDefinition[];
|
|
484
533
|
readonly __acc?: Acc;
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
534
|
+
use<
|
|
535
|
+
TAcc,
|
|
536
|
+
TReturns extends ReturnsMap = {},
|
|
537
|
+
TRequiredLayouts = unknown,
|
|
538
|
+
TRequires extends MiddlewareRequirements = {},
|
|
539
|
+
>(
|
|
540
|
+
unit: [
|
|
491
541
|
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
492
|
-
|
|
542
|
+
IsRequirementsSatisfied<
|
|
543
|
+
{
|
|
544
|
+
query: MiddlewareChainField<Layout, Acc, "query">;
|
|
545
|
+
params: MiddlewareChainField<Layout, Acc, "params">;
|
|
546
|
+
body: MiddlewareChainField<Layout, Acc, "body">;
|
|
547
|
+
state: MiddlewareChainField<Layout, Acc, "state">;
|
|
548
|
+
},
|
|
549
|
+
TRequires
|
|
550
|
+
>,
|
|
493
551
|
] extends [true, true]
|
|
494
|
-
?
|
|
495
|
-
:
|
|
496
|
-
{
|
|
497
|
-
error: "Middleware cannot be attached to this layout";
|
|
498
|
-
requiredLayouts: TRequiredLayouts;
|
|
499
|
-
layoutChain: ResolveLayoutIdChain<Layout>;
|
|
500
|
-
requiredState: TRequiredState;
|
|
501
|
-
actualState: MiddlewareChainField<Layout, Acc, "state">;
|
|
502
|
-
},
|
|
503
|
-
]
|
|
552
|
+
? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires>
|
|
553
|
+
: never,
|
|
504
554
|
): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
505
555
|
use<R = unknown>(
|
|
506
556
|
fn: (
|
|
507
|
-
ctx:
|
|
557
|
+
ctx: Simplify<
|
|
558
|
+
TAppContext & {
|
|
559
|
+
readonly request: Request;
|
|
560
|
+
readonly method: Method;
|
|
561
|
+
readonly url: URL;
|
|
562
|
+
readonly headers: TaserHeaders;
|
|
563
|
+
readonly cookies: TaserCookieJar;
|
|
564
|
+
query: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
565
|
+
params: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
566
|
+
body: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
567
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
568
|
+
}
|
|
569
|
+
>,
|
|
508
570
|
next: NextFn,
|
|
509
571
|
) => Awaitable<R>,
|
|
510
572
|
): MiddlewareBuilder<
|
|
@@ -563,7 +625,7 @@ type RouteHandleResult<
|
|
|
563
625
|
};
|
|
564
626
|
};
|
|
565
627
|
|
|
566
|
-
export type
|
|
628
|
+
export type RouteContractBuilderBase<
|
|
567
629
|
Path extends RoutePath,
|
|
568
630
|
TMethod extends Method,
|
|
569
631
|
Acc extends readonly unknown[] = readonly [],
|
|
@@ -584,7 +646,7 @@ export type RouteBuilderBase<
|
|
|
584
646
|
};
|
|
585
647
|
query<TQuery, TQueryIn = unknown>(
|
|
586
648
|
schema: Schema<TQuery, TQueryIn>,
|
|
587
|
-
):
|
|
649
|
+
): RouteContractBuilder<
|
|
588
650
|
Path,
|
|
589
651
|
TMethod,
|
|
590
652
|
Acc,
|
|
@@ -594,7 +656,7 @@ export type RouteBuilderBase<
|
|
|
594
656
|
>;
|
|
595
657
|
params<TParams, TParamsIn = unknown>(
|
|
596
658
|
schema: Schema<TParams, TParamsIn>,
|
|
597
|
-
):
|
|
659
|
+
): RouteContractBuilder<
|
|
598
660
|
Path,
|
|
599
661
|
TMethod,
|
|
600
662
|
Acc,
|
|
@@ -604,44 +666,7 @@ export type RouteBuilderBase<
|
|
|
604
666
|
>;
|
|
605
667
|
returns<const M extends ReturnsMap>(
|
|
606
668
|
map: M,
|
|
607
|
-
):
|
|
608
|
-
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
|
|
609
|
-
unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
|
|
610
|
-
..._assert: [
|
|
611
|
-
IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
|
|
612
|
-
IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>,
|
|
613
|
-
] extends [true, true]
|
|
614
|
-
? []
|
|
615
|
-
: [
|
|
616
|
-
{
|
|
617
|
-
error: "Middleware cannot be attached to this route";
|
|
618
|
-
requiredLayouts: TRequiredLayouts;
|
|
619
|
-
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
620
|
-
requiredState: TRequiredState;
|
|
621
|
-
actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
622
|
-
},
|
|
623
|
-
]
|
|
624
|
-
): RouteBuilder<
|
|
625
|
-
Path,
|
|
626
|
-
TMethod,
|
|
627
|
-
readonly [...Acc, TAcc],
|
|
628
|
-
Validators,
|
|
629
|
-
Omit<TReturns, keyof UReturns> & UReturns,
|
|
630
|
-
TAppContext
|
|
631
|
-
>;
|
|
632
|
-
use<R = unknown>(
|
|
633
|
-
fn: (
|
|
634
|
-
ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>,
|
|
635
|
-
next: NextFn,
|
|
636
|
-
) => Awaitable<R>,
|
|
637
|
-
): RouteBuilder<
|
|
638
|
-
Path,
|
|
639
|
-
TMethod,
|
|
640
|
-
readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>],
|
|
641
|
-
Validators,
|
|
642
|
-
TReturns,
|
|
643
|
-
TAppContext
|
|
644
|
-
>;
|
|
669
|
+
): RouteContractBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
645
670
|
handler<R extends Response = Response>(
|
|
646
671
|
fn: (
|
|
647
672
|
ctx: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
|
|
@@ -659,20 +684,20 @@ export type RouteBuilderBase<
|
|
|
659
684
|
): RouteHandleResult<Path, TMethod, Acc, Validators, TReturns, R, TAppContext>;
|
|
660
685
|
};
|
|
661
686
|
|
|
662
|
-
export type
|
|
687
|
+
export type RouteContractBuilder<
|
|
663
688
|
Path extends RoutePath,
|
|
664
689
|
TMethod extends Method,
|
|
665
690
|
Acc extends readonly unknown[] = readonly [],
|
|
666
691
|
Validators extends ValidatorParts = {},
|
|
667
692
|
TReturns extends ReturnsMap = {},
|
|
668
693
|
TAppContext extends Record<string, unknown> = AppContext,
|
|
669
|
-
> =
|
|
694
|
+
> = RouteContractBuilderBase<Path, TMethod, Acc, Validators, TReturns, TAppContext> &
|
|
670
695
|
(TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
|
|
671
696
|
? {}
|
|
672
697
|
: {
|
|
673
698
|
body<TBody, TBodyIn = unknown>(
|
|
674
699
|
schema: Schema<TBody, TBodyIn>,
|
|
675
|
-
):
|
|
700
|
+
): RouteContractBuilder<
|
|
676
701
|
Path,
|
|
677
702
|
TMethod,
|
|
678
703
|
Acc,
|
|
@@ -683,7 +708,7 @@ export type RouteBuilder<
|
|
|
683
708
|
body<Mode extends "json" | "form" | "urlencoded", TBody, TBodyIn = unknown>(
|
|
684
709
|
mode: Mode,
|
|
685
710
|
schema: Schema<TBody, TBodyIn>,
|
|
686
|
-
):
|
|
711
|
+
): RouteContractBuilder<
|
|
687
712
|
Path,
|
|
688
713
|
TMethod,
|
|
689
714
|
Acc,
|
|
@@ -693,6 +718,66 @@ export type RouteBuilder<
|
|
|
693
718
|
>;
|
|
694
719
|
});
|
|
695
720
|
|
|
721
|
+
export type RouteMiddlewareBuilder<
|
|
722
|
+
Path extends RoutePath,
|
|
723
|
+
TMethod extends Method,
|
|
724
|
+
Acc extends readonly unknown[] = readonly [],
|
|
725
|
+
Validators extends ValidatorParts = {},
|
|
726
|
+
TReturns extends ReturnsMap = {},
|
|
727
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
728
|
+
> = RouteContractBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext> & {
|
|
729
|
+
use<
|
|
730
|
+
TAcc,
|
|
731
|
+
UReturns extends ReturnsMap = {},
|
|
732
|
+
TRequiredLayouts = unknown,
|
|
733
|
+
TRequires extends MiddlewareRequirements = {},
|
|
734
|
+
>(
|
|
735
|
+
unit: [
|
|
736
|
+
IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
|
|
737
|
+
IsRequirementsSatisfied<
|
|
738
|
+
{
|
|
739
|
+
query: RouteResolvedField<Path, TMethod, Acc, "query">;
|
|
740
|
+
params: ResolveParams<PathParams<Path>, RouteResolvedField<Path, TMethod, Acc, "params">>;
|
|
741
|
+
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
742
|
+
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
743
|
+
},
|
|
744
|
+
TRequires
|
|
745
|
+
>,
|
|
746
|
+
] extends [true, true]
|
|
747
|
+
? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires>
|
|
748
|
+
: never,
|
|
749
|
+
): RouteMiddlewareBuilder<
|
|
750
|
+
Path,
|
|
751
|
+
TMethod,
|
|
752
|
+
readonly [...Acc, TAcc],
|
|
753
|
+
Validators,
|
|
754
|
+
Omit<TReturns, keyof UReturns> & UReturns,
|
|
755
|
+
TAppContext
|
|
756
|
+
>;
|
|
757
|
+
use<R = unknown>(
|
|
758
|
+
fn: (
|
|
759
|
+
ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>,
|
|
760
|
+
next: NextFn,
|
|
761
|
+
) => Awaitable<R>,
|
|
762
|
+
): RouteMiddlewareBuilder<
|
|
763
|
+
Path,
|
|
764
|
+
TMethod,
|
|
765
|
+
readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>],
|
|
766
|
+
Validators,
|
|
767
|
+
TReturns,
|
|
768
|
+
TAppContext
|
|
769
|
+
>;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
export type RouteBuilder<
|
|
773
|
+
Path extends RoutePath,
|
|
774
|
+
TMethod extends Method,
|
|
775
|
+
Acc extends readonly unknown[] = readonly [],
|
|
776
|
+
Validators extends ValidatorParts = {},
|
|
777
|
+
TReturns extends ReturnsMap = {},
|
|
778
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
779
|
+
> = RouteMiddlewareBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext>;
|
|
780
|
+
|
|
696
781
|
export type RouteDefinition<
|
|
697
782
|
Path extends RoutePath = RoutePath,
|
|
698
783
|
TMethod extends Method = Method,
|
package/src/types/type-utils.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type UnwrapPart<T> = unknown extends T ? {} : T;
|
|
|
13
13
|
export type MergePart<T, Base> = unknown extends T ? Base : Base & T;
|
|
14
14
|
|
|
15
15
|
/** Collapse intersections so `Omit`/`keyof` treat the result as one object type. */
|
|
16
|
-
export type Simplify<T> = { [K in keyof
|
|
16
|
+
export type Simplify<T> = [T] extends [infer U] ? { [K in keyof U]: U[K] } : never;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Request prop: when schema input is `unknown` (e.g. zod coerce),
|