@taserjs/router 0.0.2 → 0.0.4

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.
Files changed (138) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/constants.cjs.map +1 -1
  3. package/dist/cjs/create-context.cjs.map +1 -1
  4. package/dist/cjs/define/handler.cjs.map +1 -1
  5. package/dist/cjs/define/middleware.cjs +18 -27
  6. package/dist/cjs/define/middleware.cjs.map +1 -1
  7. package/dist/cjs/define/middleware.d.cts +27 -79
  8. package/dist/cjs/define/validators.cjs.map +1 -1
  9. package/dist/cjs/factories.cjs.map +1 -1
  10. package/dist/cjs/factories.d.cts +2 -2
  11. package/dist/cjs/index.cjs +1 -2
  12. package/dist/cjs/index.d.cts +1 -1
  13. package/dist/cjs/middleware/body-limit.cjs +2 -2
  14. package/dist/cjs/middleware/body-limit.cjs.map +1 -1
  15. package/dist/cjs/middleware/compress.cjs +2 -2
  16. package/dist/cjs/middleware/compress.cjs.map +1 -1
  17. package/dist/cjs/middleware/cors.cjs +2 -2
  18. package/dist/cjs/middleware/cors.cjs.map +1 -1
  19. package/dist/cjs/middleware/csrf.cjs +2 -2
  20. package/dist/cjs/middleware/csrf.cjs.map +1 -1
  21. package/dist/cjs/middleware/etag.cjs +2 -2
  22. package/dist/cjs/middleware/etag.cjs.map +1 -1
  23. package/dist/cjs/middleware/jwk.cjs +11 -4
  24. package/dist/cjs/middleware/jwk.cjs.map +1 -1
  25. package/dist/cjs/middleware/jwk.d.cts +4 -5
  26. package/dist/cjs/middleware/jwt.cjs +11 -5
  27. package/dist/cjs/middleware/jwt.cjs.map +1 -1
  28. package/dist/cjs/middleware/jwt.d.cts +7 -5
  29. package/dist/cjs/middleware/secure-headers.cjs +2 -2
  30. package/dist/cjs/middleware/secure-headers.cjs.map +1 -1
  31. package/dist/cjs/middleware/timing.cjs +2 -2
  32. package/dist/cjs/middleware/timing.cjs.map +1 -1
  33. package/dist/cjs/middleware/wrap-hono.cjs +9 -0
  34. package/dist/cjs/middleware/wrap-hono.cjs.map +1 -0
  35. package/dist/cjs/middleware/wrap-hono.d.cts +3 -0
  36. package/dist/cjs/middleware.cjs.map +1 -1
  37. package/dist/cjs/reply.d.cts +1 -1
  38. package/dist/cjs/route.cjs.map +1 -1
  39. package/dist/cjs/route.d.cts +1 -1
  40. package/dist/cjs/stream.d.cts +1 -1
  41. package/dist/cjs/taser-app.cjs +0 -6
  42. package/dist/cjs/taser-app.cjs.map +1 -1
  43. package/dist/cjs/taser-app.d.cts +0 -3
  44. package/dist/cjs/taser-router.cjs +9 -10
  45. package/dist/cjs/taser-router.cjs.map +1 -1
  46. package/dist/cjs/taser-router.d.cts +9 -11
  47. package/dist/cjs/types/app.d.cts +3 -2
  48. package/dist/cjs/types/index.d.cts +94 -143
  49. package/dist/cjs/types/type-utils.d.cts +8 -10
  50. package/dist/cjs/types/units.cjs.map +1 -1
  51. package/dist/cjs/types/units.d.cts +32 -27
  52. package/dist/esm/constants.js.map +1 -1
  53. package/dist/esm/create-context.js.map +1 -1
  54. package/dist/esm/define/handler.js.map +1 -1
  55. package/dist/esm/define/middleware.d.ts +27 -79
  56. package/dist/esm/define/middleware.js +18 -27
  57. package/dist/esm/define/middleware.js.map +1 -1
  58. package/dist/esm/define/validators.js.map +1 -1
  59. package/dist/esm/factories.d.ts +2 -2
  60. package/dist/esm/factories.js.map +1 -1
  61. package/dist/esm/index.d.ts +1 -1
  62. package/dist/esm/index.js +3 -3
  63. package/dist/esm/middleware/body-limit.js +1 -1
  64. package/dist/esm/middleware/body-limit.js.map +1 -1
  65. package/dist/esm/middleware/compress.js +1 -1
  66. package/dist/esm/middleware/compress.js.map +1 -1
  67. package/dist/esm/middleware/cors.js +1 -1
  68. package/dist/esm/middleware/cors.js.map +1 -1
  69. package/dist/esm/middleware/csrf.js +1 -1
  70. package/dist/esm/middleware/csrf.js.map +1 -1
  71. package/dist/esm/middleware/etag.js +1 -1
  72. package/dist/esm/middleware/etag.js.map +1 -1
  73. package/dist/esm/middleware/jwk.d.ts +4 -5
  74. package/dist/esm/middleware/jwk.js +11 -4
  75. package/dist/esm/middleware/jwk.js.map +1 -1
  76. package/dist/esm/middleware/jwt.d.ts +7 -5
  77. package/dist/esm/middleware/jwt.js +11 -5
  78. package/dist/esm/middleware/jwt.js.map +1 -1
  79. package/dist/esm/middleware/secure-headers.js +1 -1
  80. package/dist/esm/middleware/secure-headers.js.map +1 -1
  81. package/dist/esm/middleware/timing.js +1 -1
  82. package/dist/esm/middleware/timing.js.map +1 -1
  83. package/dist/esm/middleware/wrap-hono.d.ts +3 -0
  84. package/dist/esm/middleware/wrap-hono.js +9 -0
  85. package/dist/esm/middleware/wrap-hono.js.map +1 -0
  86. package/dist/esm/middleware.js.map +1 -1
  87. package/dist/esm/reply.d.ts +1 -1
  88. package/dist/esm/route.d.ts +1 -1
  89. package/dist/esm/route.js.map +1 -1
  90. package/dist/esm/stream.d.ts +1 -1
  91. package/dist/esm/taser-app.d.ts +0 -3
  92. package/dist/esm/taser-app.js +1 -6
  93. package/dist/esm/taser-app.js.map +1 -1
  94. package/dist/esm/taser-router.d.ts +9 -11
  95. package/dist/esm/taser-router.js +7 -8
  96. package/dist/esm/taser-router.js.map +1 -1
  97. package/dist/esm/types/app.d.ts +3 -2
  98. package/dist/esm/types/index.d.ts +94 -143
  99. package/dist/esm/types/type-utils.d.ts +8 -10
  100. package/dist/esm/types/units.d.ts +32 -27
  101. package/dist/esm/types/units.js.map +1 -1
  102. package/package.json +17 -17
  103. package/src/constants.ts +6 -6
  104. package/src/create-context.ts +8 -8
  105. package/src/define/handler.ts +24 -34
  106. package/src/define/middleware.ts +222 -222
  107. package/src/define/validators.ts +10 -10
  108. package/src/factories.ts +63 -61
  109. package/src/index.ts +12 -12
  110. package/src/middleware/body-limit.ts +5 -5
  111. package/src/middleware/compress.ts +5 -5
  112. package/src/middleware/cors.ts +5 -5
  113. package/src/middleware/csrf.ts +5 -5
  114. package/src/middleware/etag.ts +5 -5
  115. package/src/middleware/jwk.ts +33 -26
  116. package/src/middleware/jwt.ts +26 -10
  117. package/src/middleware/secure-headers.ts +5 -5
  118. package/src/middleware/timing.ts +5 -5
  119. package/src/middleware/wrap-hono.ts +12 -0
  120. package/src/middleware.ts +7 -7
  121. package/src/reply.ts +2 -6
  122. package/src/route.ts +45 -48
  123. package/src/stream.ts +1 -7
  124. package/src/taser-app.ts +13 -18
  125. package/src/taser-router.ts +103 -98
  126. package/src/types/app.ts +33 -35
  127. package/src/types/index.ts +403 -731
  128. package/src/types/returns.ts +92 -97
  129. package/src/types/schema.ts +8 -9
  130. package/src/types/type-utils.ts +42 -45
  131. package/src/types/units.ts +140 -104
  132. package/dist/cjs/middleware/auth.cjs +0 -34
  133. package/dist/cjs/middleware/auth.cjs.map +0 -1
  134. package/dist/cjs/middleware/auth.d.cts +0 -9
  135. package/dist/esm/middleware/auth.d.ts +0 -9
  136. package/dist/esm/middleware/auth.js +0 -33
  137. package/dist/esm/middleware/auth.js.map +0 -1
  138. package/src/middleware/auth.ts +0 -51
@@ -1,6 +1,5 @@
1
- import type { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core'
2
- import type { ReplyResult } from '@taserjs/router-utils'
3
- import type { RouterRegister } from '../register.js'
1
+ import type { Awaitable, TaserCookieJar, TaserHeaders } from "@taserjs/router-core";
2
+ import type { RouterRegister } from "../register.js";
4
3
  import type {
5
4
  MergeMiddlewareField,
6
5
  MergeMiddlewareInputField,
@@ -8,30 +7,33 @@ import type {
8
7
  RequestShape,
9
8
  RuntimeContextFields,
10
9
  Simplify,
11
- } from './type-utils.js'
12
- import type { ReturnsMap, ValidHandlerReply } from './returns.js'
13
- import type { Schema } from './schema.js'
10
+ UnionToIntersection,
11
+ } from "./type-utils.js";
12
+ import type { ReturnsMap, ValidHandlerReply } from "./returns.js";
13
+ import type { Schema } from "./schema.js";
14
14
  import type {
15
15
  AppContext,
16
+ ExtractState,
16
17
  HandlerContext,
17
18
  HandlerUnit,
19
+ InlineMiddlewareOptions,
18
20
  Method,
19
21
  MiddlewareDefinition,
20
22
  MiddlewareReturnFromParts,
21
23
  MiddlewareUnit,
22
24
  NativeContext,
23
25
  ValidatorParts,
24
- } from './units.js'
26
+ } from "./units.js";
25
27
 
26
- export type { Awaitable } from '@taserjs/router-core'
28
+ export type { Awaitable } from "@taserjs/router-core";
27
29
  export type {
28
30
  SchemaRequestShape,
29
31
  InferInput,
30
32
  InferOutput,
31
33
  Schema,
32
34
  StandardSchemaV1,
33
- } from './schema.js'
34
- export type { RouterRegister } from '../register.js'
35
+ } from "./schema.js";
36
+ export type { RouterRegister } from "../register.js";
35
37
  export type {
36
38
  MergeMiddlewareField,
37
39
  MergeMiddlewareInputField,
@@ -39,7 +41,7 @@ export type {
39
41
  RequestShape,
40
42
  Simplify,
41
43
  UnwrapPart,
42
- } from './type-utils.js'
44
+ } from "./type-utils.js";
43
45
  export type {
44
46
  EmptyReturns,
45
47
  EnforceHandlerReply,
@@ -50,112 +52,132 @@ export type {
50
52
  ReturnsMap,
51
53
  StatusCode,
52
54
  ValidHandlerReply,
53
- } from './returns.js'
55
+ } from "./returns.js";
54
56
  export type {
55
57
  AppContext,
58
+ ExtractState,
56
59
  HandlerContext,
57
60
  HandlerUnit,
58
61
  HttpMethod,
59
62
  InlineMiddlewareOptions,
63
+ IsUnknown,
60
64
  Method,
61
65
  MiddlewareDefinition,
62
66
  MiddlewareNext,
63
67
  MiddlewareReturnFromParts,
64
68
  MiddlewareUnit,
65
69
  NativeContext,
70
+ NextFn,
71
+ NextResult,
66
72
  StandaloneMiddlewareContext,
73
+ StateBrand,
67
74
  ValidatorParts,
68
- } from './units.js'
75
+ } from "./units.js";
69
76
 
70
- export type RoutePath = RouterRegister extends { RoutePath: infer P } ? P : never
71
- export type LayoutId = RouterRegister extends { LayoutId: infer L } ? L : never
72
- export type LayoutTree = RouterRegister extends { LayoutTree: infer T } ? T : Record<never, never>
77
+ export type RoutePath = RouterRegister extends { RoutePath: infer P } ? P : never;
78
+ export type LayoutId = RouterRegister extends { LayoutId: infer L } ? L : never;
79
+ export type LayoutTree = RouterRegister extends { LayoutTree: infer T } ? T : Record<never, never>;
73
80
  export type RouteByPathMethod = RouterRegister extends { RouteByPathMethod: infer R }
74
81
  ? R
75
- : Record<never, never>
76
-
77
- type ParseParam<Segment extends string>
78
- = Segment extends '*' ? { _splat: string }
79
- : Segment extends `:${infer Name extends string}`
80
- ? Name extends '' ? {} : { [K in Name]: string }
81
- : {}
82
-
83
- type ParseParamsFromSegments<S extends string>
84
- = S extends `${infer Segment}/${infer Rest}`
85
- ? ParseParam<Segment> & ParseParamsFromSegments<Rest>
86
- : ParseParam<S>
87
-
88
- export type PathParams<Path extends string>
89
- = Path extends `/${infer Rest}` ? ParseParamsFromSegments<Rest> : {}
90
-
91
- type LayoutParent<Layout extends LayoutId>
92
- = LayoutTree[Layout] extends { parent: infer Parent extends LayoutId | null }
93
- ? Parent
94
- : null
82
+ : Record<never, never>;
83
+
84
+ type ParseParam<Segment extends string> = Segment extends "*"
85
+ ? { _splat: string }
86
+ : Segment extends `:${infer Name extends string}`
87
+ ? Name extends ""
88
+ ? {}
89
+ : { [K in Name]: string }
90
+ : {};
91
+
92
+ type ParseParamsFromSegments<S extends string> = S extends `${infer Segment}/${infer Rest}`
93
+ ? ParseParam<Segment> & ParseParamsFromSegments<Rest>
94
+ : ParseParam<S>;
95
+
96
+ export type PathParams<Path extends string> = Path extends `/${infer Rest}`
97
+ ? ParseParamsFromSegments<Rest>
98
+ : {};
99
+
100
+ type LayoutParent<Layout extends LayoutId> = LayoutTree[Layout] extends {
101
+ parent: infer Parent extends LayoutId | null;
102
+ }
103
+ ? Parent
104
+ : null;
95
105
 
96
- type ResolveLayoutMiddlewares<Layout extends LayoutId | null>
97
- = Layout extends null ? readonly []
98
- : Layout extends LayoutId
99
- ? readonly [
106
+ type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends null
107
+ ? readonly []
108
+ : Layout extends LayoutId
109
+ ? readonly [
100
110
  ...ResolveLayoutMiddlewares<LayoutParent<Layout>>,
101
- ...LayoutTree[Layout]['middlewares'],
111
+ ...LayoutTree[Layout]["middlewares"],
102
112
  ]
103
- : readonly []
113
+ : readonly [];
114
+
115
+ export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null
116
+ ? readonly []
117
+ : L extends LayoutId
118
+ ? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L]
119
+ : readonly [];
120
+
121
+ export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId
122
+ ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state">
123
+ : {};
124
+
125
+ export type ResolveLayoutsState<Layouts extends LayoutId | readonly LayoutId[]> =
126
+ Layouts extends LayoutId
127
+ ? ResolveLayoutMiddlewaresState<Layouts>
128
+ : Layouts extends readonly LayoutId[]
129
+ ? UnionToIntersection<
130
+ Layouts[number] extends infer L extends LayoutId
131
+ ? ResolveLayoutMiddlewaresState<L>
132
+ : never
133
+ >
134
+ : {};
104
135
 
105
136
  /** Fold layout middleware Acc from a route's layoutChain (shallow → deep). */
106
- type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]>
107
- = Chain extends readonly [infer Head extends LayoutId, ...infer Rest]
108
- ? readonly [
109
- ...LayoutTree[Head]['middlewares'],
110
- ...ResolveLayoutChainMiddlewares<
111
- Rest extends readonly LayoutId[] ? Rest : readonly []
112
- >,
137
+ type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain extends readonly [
138
+ infer Head extends LayoutId,
139
+ ...infer Rest,
140
+ ]
141
+ ? readonly [
142
+ ...LayoutTree[Head]["middlewares"],
143
+ ...ResolveLayoutChainMiddlewares<Rest extends readonly LayoutId[] ? Rest : readonly []>,
113
144
  ]
114
- : readonly []
145
+ : readonly [];
115
146
 
116
- type RouteEntry<
117
- Path extends RoutePath,
118
- TMethod extends Method,
119
- > = RouteByPathMethod[Path] extends { [K in TMethod]: infer Entry } ? Entry : never
147
+ type RouteEntry<Path extends RoutePath, TMethod extends Method> = RouteByPathMethod[Path] extends {
148
+ [K in TMethod]: infer Entry;
149
+ }
150
+ ? Entry
151
+ : never;
120
152
 
121
- type RouteParent<Path extends RoutePath, TMethod extends Method>
122
- = RouteEntry<Path, TMethod> extends { parent: infer Parent extends LayoutId | null }
153
+ type RouteParent<Path extends RoutePath, TMethod extends Method> =
154
+ RouteEntry<Path, TMethod> extends { parent: infer Parent extends LayoutId | null }
123
155
  ? Parent
124
- : null
156
+ : null;
125
157
 
126
- type RouteLayoutChain<Path extends RoutePath, TMethod extends Method>
127
- = RouteEntry<Path, TMethod> extends { layoutChain: infer Chain extends readonly LayoutId[] }
158
+ type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> =
159
+ RouteEntry<Path, TMethod> extends { layoutChain: infer Chain extends readonly LayoutId[] }
128
160
  ? Chain
129
161
  : RouteParent<Path, TMethod> extends LayoutId
130
162
  ? readonly [RouteParent<Path, TMethod>]
131
- : readonly []
163
+ : readonly [];
132
164
 
133
165
  type RouteResolvedField<
134
166
  Path extends RoutePath,
135
167
  TMethod extends Method,
136
168
  Acc extends readonly unknown[],
137
- Field extends 'query' | 'params' | 'body' | 'state' | 'ctx',
138
- > = MergeMiddlewareField<
139
- ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>,
140
- Field
141
- > & MergeMiddlewareField<Acc, Field>
142
-
143
- type MiddlewareCtxField<
144
- Layout extends LayoutId,
145
- Field extends 'query' | 'params' | 'body' | 'state' | 'ctx',
146
- > = MergeMiddlewareField<
147
- ResolveLayoutMiddlewares<LayoutParent<Layout>>,
148
- Field
149
- >
169
+ Field extends "query" | "params" | "body" | "state",
170
+ > = MergeMiddlewareField<ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>, Field> &
171
+ MergeMiddlewareField<Acc, Field>;
150
172
 
151
173
  type RouteChainField<
152
174
  Path extends RoutePath,
153
175
  TMethod extends Method,
154
176
  Acc extends readonly unknown[],
155
- Field extends 'query' | 'params' | 'body' | 'state' | 'ctx',
156
- > = RouteResolvedField<Path, TMethod, Acc, Field>
177
+ Field extends "query" | "params" | "body" | "state",
178
+ > = RouteResolvedField<Path, TMethod, Acc, Field>;
157
179
 
158
- type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, 'var'>
180
+ type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, "var">;
159
181
 
160
182
  export type RouteChainContext<
161
183
  Path extends RoutePath,
@@ -166,104 +188,144 @@ export type RouteChainContext<
166
188
  TBody,
167
189
  TAppContext extends Record<string, unknown> = AppContext,
168
190
  > = Simplify<
169
- TAppContext
170
- & UnitRuntimeContext
171
- & RouteChainField<Path, TMethod, Acc, 'ctx'>
172
- & {
173
- query: Simplify<MergePart<TQuery, RouteChainField<Path, TMethod, Acc, 'query'>>>
174
- params: Simplify<PathParams<Path> & MergePart<TParams, RouteChainField<Path, TMethod, Acc, 'params'>>>
175
- body: Simplify<MergePart<TBody, RouteChainField<Path, TMethod, Acc, 'body'>>>
176
- state: Simplify<RouteChainField<Path, TMethod, Acc, 'state'>>
177
- headers: TaserHeaders
178
- cookies: TaserCookieJar
179
- }
180
- >
191
+ TAppContext &
192
+ UnitRuntimeContext & {
193
+ query: Simplify<MergePart<TQuery, RouteChainField<Path, TMethod, Acc, "query">>>;
194
+ params: Simplify<
195
+ PathParams<Path> & MergePart<TParams, RouteChainField<Path, TMethod, Acc, "params">>
196
+ >;
197
+ body: Simplify<MergePart<TBody, RouteChainField<Path, TMethod, Acc, "body">>>;
198
+ state: Simplify<RouteChainField<Path, TMethod, Acc, "state">>;
199
+ headers: TaserHeaders;
200
+ cookies: TaserCookieJar;
201
+ }
202
+ >;
181
203
 
182
204
  export type RouteHandleContext<
183
205
  Path extends RoutePath,
184
206
  TMethod extends Method,
185
207
  Acc extends readonly unknown[],
186
208
  Validators extends {
187
- query?: unknown
188
- params?: unknown
189
- body?: unknown
209
+ query?: unknown;
210
+ params?: unknown;
211
+ body?: unknown;
190
212
  },
191
213
  TAppContext extends Record<string, unknown> = AppContext,
192
214
  > = Simplify<
193
- TAppContext
194
- & UnitRuntimeContext
195
- & RouteResolvedField<Path, TMethod, Acc, 'ctx'>
196
- & {
197
- path: Path
198
- method: TMethod
199
- query: Simplify<MergePart<
200
- Validators extends { query?: infer Q } ? Q : unknown,
201
- RouteResolvedField<Path, TMethod, Acc, 'query'>
202
- >>
203
- params: Simplify<PathParams<Path> & MergePart<
204
- Validators extends { params?: infer P } ? P : unknown,
205
- RouteResolvedField<Path, TMethod, Acc, 'params'>
206
- >>
207
- body: Simplify<MergePart<
208
- Validators extends { body?: infer B } ? B : unknown,
209
- RouteResolvedField<Path, TMethod, Acc, 'body'>
210
- >>
211
- state: Simplify<RouteResolvedField<Path, TMethod, Acc, 'state'>>
212
- headers: TaserHeaders
213
- cookies: TaserCookieJar
214
- }
215
- >
215
+ TAppContext &
216
+ UnitRuntimeContext & {
217
+ path: Path;
218
+ method: TMethod;
219
+ query: Simplify<
220
+ MergePart<
221
+ Validators extends { query?: infer Q } ? Q : unknown,
222
+ RouteResolvedField<Path, TMethod, Acc, "query">
223
+ >
224
+ >;
225
+ params: Simplify<
226
+ PathParams<Path> &
227
+ MergePart<
228
+ Validators extends { params?: infer P } ? P : unknown,
229
+ RouteResolvedField<Path, TMethod, Acc, "params">
230
+ >
231
+ >;
232
+ body: Simplify<
233
+ MergePart<
234
+ Validators extends { body?: infer B } ? B : unknown,
235
+ RouteResolvedField<Path, TMethod, Acc, "body">
236
+ >
237
+ >;
238
+ state: Simplify<RouteResolvedField<Path, TMethod, Acc, "state">>;
239
+ headers: TaserHeaders;
240
+ cookies: TaserCookieJar;
241
+ }
242
+ >;
216
243
 
217
244
  export type RouteHandleContextWithoutBody<
218
245
  Path extends RoutePath,
219
246
  TMethod extends Method,
220
247
  Acc extends readonly unknown[],
221
248
  Validators extends {
222
- query?: unknown
223
- params?: unknown
249
+ query?: unknown;
250
+ params?: unknown;
224
251
  },
225
252
  TAppContext extends Record<string, unknown> = AppContext,
226
253
  > = Simplify<
227
- TAppContext
228
- & UnitRuntimeContext
229
- & RouteResolvedField<Path, TMethod, Acc, 'ctx'>
230
- & {
231
- path: Path
232
- method: TMethod
233
- query: Simplify<MergePart<
234
- Validators extends { query?: infer Q } ? Q : unknown,
235
- RouteResolvedField<Path, TMethod, Acc, 'query'>
236
- >>
237
- params: Simplify<PathParams<Path> & MergePart<
238
- Validators extends { params?: infer P } ? P : unknown,
239
- RouteResolvedField<Path, TMethod, Acc, 'params'>
240
- >>
241
- body: never
242
- state: Simplify<RouteResolvedField<Path, TMethod, Acc, 'state'>>
243
- headers: TaserHeaders
244
- cookies: TaserCookieJar
245
- }
246
- >
254
+ TAppContext &
255
+ UnitRuntimeContext & {
256
+ path: Path;
257
+ method: TMethod;
258
+ query: Simplify<
259
+ MergePart<
260
+ Validators extends { query?: infer Q } ? Q : unknown,
261
+ RouteResolvedField<Path, TMethod, Acc, "query">
262
+ >
263
+ >;
264
+ params: Simplify<
265
+ PathParams<Path> &
266
+ MergePart<
267
+ Validators extends { params?: infer P } ? P : unknown,
268
+ RouteResolvedField<Path, TMethod, Acc, "params">
269
+ >
270
+ >;
271
+ body: never;
272
+ state: Simplify<RouteResolvedField<Path, TMethod, Acc, "state">>;
273
+ headers: TaserHeaders;
274
+ cookies: TaserCookieJar;
275
+ }
276
+ >;
247
277
 
248
278
  type RouteResolvedInputField<
249
279
  Path extends RoutePath,
250
280
  TMethod extends Method,
251
281
  Acc extends readonly unknown[],
252
- Field extends 'query' | 'params' | 'body',
282
+ Field extends "query" | "params" | "body",
253
283
  > = MergeMiddlewareInputField<
254
284
  ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>,
255
285
  Field
256
- > & MergeMiddlewareInputField<Acc, Field>
257
-
258
- type IsNever<T> = [T] extends [never] ? true : false
259
-
260
- type IsEmptyObject<T> = [keyof T] extends [never] ? true : false
261
-
262
- type InputFacet<T, K extends string> = IsNever<T> extends true
263
- ? {}
264
- : IsEmptyObject<T> extends true
265
- ? {}
266
- : { [Key in K]: T }
286
+ > &
287
+ MergeMiddlewareInputField<Acc, Field>;
288
+
289
+ type IsNever<T> = [T] extends [never] ? true : false;
290
+
291
+ type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
292
+
293
+ export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
294
+ TRequiredLayouts,
295
+ ] extends [never]
296
+ ? true
297
+ : [unknown] extends [TRequiredLayouts]
298
+ ? true
299
+ : [null] extends [TRequiredLayouts]
300
+ ? true
301
+ : [undefined] extends [TRequiredLayouts]
302
+ ? true
303
+ : TRequiredLayouts extends LayoutId
304
+ ? TRequiredLayouts extends TChain[number]
305
+ ? true
306
+ : false
307
+ : TRequiredLayouts extends readonly LayoutId[]
308
+ ? [TRequiredLayouts[number] & TChain[number]] extends [never]
309
+ ? false
310
+ : true
311
+ : true;
312
+
313
+ export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never]
314
+ ? true
315
+ : [unknown] extends [TRequiredState]
316
+ ? true
317
+ : [null] extends [TRequiredState]
318
+ ? true
319
+ : [undefined] extends [TRequiredState]
320
+ ? true
321
+ : [IsEmptyObject<TRequiredState>] extends [true]
322
+ ? true
323
+ : [TActualState] extends [TRequiredState]
324
+ ? true
325
+ : false;
326
+
327
+ type InputFacet<T, K extends string> =
328
+ IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : { [Key in K]: T };
267
329
 
268
330
  type RouteQueryInput<
269
331
  Path extends RoutePath,
@@ -276,9 +338,9 @@ type RouteQueryInput<
276
338
  Validators extends { queryIn?: infer QI } ? QI : unknown,
277
339
  Validators extends { query?: infer Q } ? Q : unknown
278
340
  >,
279
- RouteResolvedInputField<Path, TMethod, Acc, 'query'>
341
+ RouteResolvedInputField<Path, TMethod, Acc, "query">
280
342
  >
281
- >
343
+ >;
282
344
 
283
345
  type RouteParamsInput<
284
346
  Path extends RoutePath,
@@ -286,14 +348,15 @@ type RouteParamsInput<
286
348
  Acc extends readonly unknown[],
287
349
  Validators extends ValidatorParts,
288
350
  > = Simplify<
289
- PathParams<Path> & MergePart<
290
- RequestShape<
291
- Validators extends { paramsIn?: infer PI } ? PI : unknown,
292
- Validators extends { params?: infer P } ? P : unknown
293
- >,
294
- RouteResolvedInputField<Path, TMethod, Acc, 'params'>
295
- >
296
- >
351
+ PathParams<Path> &
352
+ MergePart<
353
+ RequestShape<
354
+ Validators extends { paramsIn?: infer PI } ? PI : unknown,
355
+ Validators extends { params?: infer P } ? P : unknown
356
+ >,
357
+ RouteResolvedInputField<Path, TMethod, Acc, "params">
358
+ >
359
+ >;
297
360
 
298
361
  type RouteBodyInput<
299
362
  Path extends RoutePath,
@@ -306,9 +369,9 @@ type RouteBodyInput<
306
369
  Validators extends { bodyIn?: infer BI } ? BI : unknown,
307
370
  Validators extends { body?: infer B } ? B : unknown
308
371
  >,
309
- RouteResolvedInputField<Path, TMethod, Acc, 'body'>
372
+ RouteResolvedInputField<Path, TMethod, Acc, "body">
310
373
  >
311
- >
374
+ >;
312
375
 
313
376
  export type RouteHandleInputWithoutBody<
314
377
  Path extends RoutePath,
@@ -316,9 +379,9 @@ export type RouteHandleInputWithoutBody<
316
379
  Acc extends readonly unknown[],
317
380
  Validators extends ValidatorParts = {},
318
381
  > = Simplify<
319
- InputFacet<RouteQueryInput<Path, TMethod, Acc, Validators>, 'query'>
320
- & InputFacet<RouteParamsInput<Path, TMethod, Acc, Validators>, 'params'>
321
- >
382
+ InputFacet<RouteQueryInput<Path, TMethod, Acc, Validators>, "query"> &
383
+ InputFacet<RouteParamsInput<Path, TMethod, Acc, Validators>, "params">
384
+ >;
322
385
 
323
386
  export type RouteHandleInput<
324
387
  Path extends RoutePath,
@@ -326,22 +389,23 @@ export type RouteHandleInput<
326
389
  Acc extends readonly unknown[],
327
390
  Validators extends ValidatorParts = {},
328
391
  > = Simplify<
329
- RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators>
330
- & InputFacet<RouteBodyInput<Path, TMethod, Acc, Validators>, 'body'>
331
- >
392
+ RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators> &
393
+ InputFacet<RouteBodyInput<Path, TMethod, Acc, Validators>, "body">
394
+ >;
332
395
 
333
- export type InferRouteInput<
334
- Path extends RoutePath,
335
- TMethod extends Method,
336
- > = RouteEntry<Path, TMethod> extends { route: infer Route }
337
- ? Route extends { $Infer: { Input: infer I } } ? I : never
338
- : never
396
+ export type InferRouteInput<Path extends RoutePath, TMethod extends Method> =
397
+ RouteEntry<Path, TMethod> extends { route: infer Route }
398
+ ? Route extends { $Infer: { Input: infer I } }
399
+ ? I
400
+ : never
401
+ : never;
339
402
 
340
403
  type MiddlewareChainField<
341
404
  Layout extends LayoutId,
342
405
  Acc extends readonly unknown[],
343
- Field extends 'query' | 'params' | 'body' | 'state' | 'ctx',
344
- > = MiddlewareCtxField<Layout, Field> & MergeMiddlewareField<Acc, Field>
406
+ Field extends "query" | "params" | "body" | "state",
407
+ > = MergeMiddlewareField<ResolveLayoutMiddlewares<LayoutParent<Layout>>, Field> &
408
+ MergeMiddlewareField<Acc, Field>;
345
409
 
346
410
  export type MiddlewareChainContext<
347
411
  Layout extends LayoutId,
@@ -351,227 +415,44 @@ export type MiddlewareChainContext<
351
415
  TBody,
352
416
  TAppContext extends Record<string, unknown> = AppContext,
353
417
  > = Simplify<
354
- TAppContext
355
- & UnitRuntimeContext
356
- & MiddlewareChainField<Layout, Acc, 'ctx'>
357
- & {
358
- query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, 'query'>>>
359
- params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, 'params'>>>
360
- body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, 'body'>>>
361
- state: Simplify<MiddlewareChainField<Layout, Acc, 'state'>>
362
- headers: TaserHeaders
363
- cookies: TaserCookieJar
364
- }
365
- >
366
-
367
- type StatefulUseOptions<
368
- Ctx,
369
- TState,
370
- TQuery,
371
- TParams,
372
- TBody,
373
- TReturns extends ReturnsMap = {},
374
- TQueryIn = unknown,
375
- TParamsIn = unknown,
376
- TBodyIn = unknown,
377
- > = {
378
- state: Schema<TState>
379
- query?: Schema<TQuery, TQueryIn>
380
- params?: Schema<TParams, TParamsIn>
381
- body?: Schema<TBody, TBodyIn>
382
- returns?: TReturns
383
- handler: (
384
- ctx: Ctx,
385
- next: (args: { state: TState }) => Promise<ReplyResult>,
386
- ) => Awaitable<ReplyResult | Response | unknown>
387
- }
388
-
389
- type CtxUseOptions<
390
- Ctx,
391
- TCtx,
392
- TQuery,
393
- TParams,
394
- TBody,
395
- TReturns extends ReturnsMap = {},
396
- TQueryIn = unknown,
397
- TParamsIn = unknown,
398
- TBodyIn = unknown,
399
- > = {
400
- ctx: Schema<TCtx>
401
- query?: Schema<TQuery, TQueryIn>
402
- params?: Schema<TParams, TParamsIn>
403
- body?: Schema<TBody, TBodyIn>
404
- returns?: TReturns
405
- handler: (
406
- ctx: Ctx,
407
- next: (args: { ctx: TCtx }) => Promise<ReplyResult>,
408
- ) => Awaitable<ReplyResult | Response | unknown>
409
- }
410
-
411
- type StateAndCtxUseOptions<
412
- Ctx,
413
- TState,
414
- TCtx,
415
- TQuery,
416
- TParams,
417
- TBody,
418
- TReturns extends ReturnsMap = {},
419
- TQueryIn = unknown,
420
- TParamsIn = unknown,
421
- TBodyIn = unknown,
422
- > = {
423
- state: Schema<TState>
424
- ctx: Schema<TCtx>
425
- query?: Schema<TQuery, TQueryIn>
426
- params?: Schema<TParams, TParamsIn>
427
- body?: Schema<TBody, TBodyIn>
428
- returns?: TReturns
429
- handler: (
430
- ctx: Ctx,
431
- next: (args: { state: TState, ctx: TCtx }) => Promise<ReplyResult>,
432
- ) => Awaitable<ReplyResult | Response | unknown>
433
- }
434
-
435
- type StatelessUseOptions<
436
- Ctx,
437
- TQuery,
438
- TParams,
439
- TBody,
440
- TReturns extends ReturnsMap = {},
441
- TQueryIn = unknown,
442
- TParamsIn = unknown,
443
- TBodyIn = unknown,
444
- > = {
445
- query?: Schema<TQuery, TQueryIn>
446
- params?: Schema<TParams, TParamsIn>
447
- body?: Schema<TBody, TBodyIn>
448
- returns?: TReturns
449
- handler: (
450
- ctx: Ctx,
451
- next: () => Promise<ReplyResult>,
452
- ) => Awaitable<ReplyResult | Response | unknown>
453
- }
418
+ TAppContext &
419
+ UnitRuntimeContext & {
420
+ query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
421
+ params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
422
+ body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, "body">>>;
423
+ state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
424
+ headers: TaserHeaders;
425
+ cookies: TaserCookieJar;
426
+ }
427
+ >;
454
428
 
455
429
  export type MiddlewareBuilder<
456
430
  Layout extends LayoutId,
457
431
  Acc extends readonly unknown[] = readonly [],
458
432
  TAppContext extends Record<string, unknown> = AppContext,
459
433
  > = Acc & {
460
- readonly layout: Layout
461
- readonly middlewares: readonly MiddlewareDefinition[]
434
+ readonly layout: Layout;
435
+ readonly middlewares: readonly MiddlewareDefinition[];
462
436
  readonly $Infer: {
463
- Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>
464
- }
465
- use<TAcc, TReturns extends ReturnsMap = {}>(
466
- unit: MiddlewareUnit<TAcc, TReturns>,
467
- ): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>
468
- use<
469
- TState,
470
- TCtx,
471
- TQuery = unknown,
472
- TParams = unknown,
473
- TBody = unknown,
474
- TReturns extends ReturnsMap = {},
475
- TQueryIn = unknown,
476
- TParamsIn = unknown,
477
- TBodyIn = unknown,
478
- >(
479
- options: StateAndCtxUseOptions<
480
- MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>,
481
- TState,
482
- TCtx,
483
- TQuery,
484
- TParams,
485
- TBody,
486
- TReturns,
487
- TQueryIn,
488
- TParamsIn,
489
- TBodyIn
490
- >,
491
- ): MiddlewareBuilder<
492
- Layout,
493
- readonly [...Acc, MiddlewareReturnFromParts<
494
- TQuery,
495
- TParams,
496
- TBody,
497
- TState,
498
- TCtx,
499
- TQueryIn,
500
- TParamsIn,
501
- TBodyIn
502
- >],
503
- TAppContext
504
- >
505
- use<
506
- TState,
507
- TQuery = unknown,
508
- TParams = unknown,
509
- TBody = unknown,
510
- TReturns extends ReturnsMap = {},
511
- TQueryIn = unknown,
512
- TParamsIn = unknown,
513
- TBodyIn = unknown,
514
- >(
515
- options: StatefulUseOptions<
516
- MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>,
517
- TState,
518
- TQuery,
519
- TParams,
520
- TBody,
521
- TReturns,
522
- TQueryIn,
523
- TParamsIn,
524
- TBodyIn
525
- >,
526
- ): MiddlewareBuilder<
527
- Layout,
528
- readonly [...Acc, MiddlewareReturnFromParts<
529
- TQuery,
530
- TParams,
531
- TBody,
532
- TState,
533
- unknown,
534
- TQueryIn,
535
- TParamsIn,
536
- TBodyIn
537
- >],
538
- TAppContext
539
- >
540
- use<
541
- TCtx,
542
- TQuery = unknown,
543
- TParams = unknown,
544
- TBody = unknown,
545
- TReturns extends ReturnsMap = {},
546
- TQueryIn = unknown,
547
- TParamsIn = unknown,
548
- TBodyIn = unknown,
549
- >(
550
- options: CtxUseOptions<
551
- MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>,
552
- TCtx,
553
- TQuery,
554
- TParams,
555
- TBody,
556
- TReturns,
557
- TQueryIn,
558
- TParamsIn,
559
- TBodyIn
560
- >,
561
- ): MiddlewareBuilder<
562
- Layout,
563
- readonly [...Acc, MiddlewareReturnFromParts<
564
- TQuery,
565
- TParams,
566
- TBody,
567
- {},
568
- TCtx,
569
- TQueryIn,
570
- TParamsIn,
571
- TBodyIn
572
- >],
573
- TAppContext
574
- >
437
+ Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
438
+ };
439
+ use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
440
+ unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>,
441
+ ..._assert: [
442
+ IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
443
+ IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>,
444
+ ] extends [true, true]
445
+ ? []
446
+ : [
447
+ {
448
+ error: "Middleware cannot be attached to this layout";
449
+ requiredLayouts: TRequiredLayouts;
450
+ layoutChain: ResolveLayoutIdChain<Layout>;
451
+ requiredState: TRequiredState;
452
+ actualState: MiddlewareChainField<Layout, Acc, "state">;
453
+ },
454
+ ]
455
+ ): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
575
456
  use<
576
457
  TQuery = unknown,
577
458
  TParams = unknown,
@@ -580,8 +461,9 @@ export type MiddlewareBuilder<
580
461
  TQueryIn = unknown,
581
462
  TParamsIn = unknown,
582
463
  TBodyIn = unknown,
464
+ R = unknown,
583
465
  >(
584
- options: StatelessUseOptions<
466
+ options: InlineMiddlewareOptions<
585
467
  MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>,
586
468
  TQuery,
587
469
  TParams,
@@ -589,23 +471,26 @@ export type MiddlewareBuilder<
589
471
  TReturns,
590
472
  TQueryIn,
591
473
  TParamsIn,
592
- TBodyIn
474
+ TBodyIn,
475
+ R
593
476
  >,
594
477
  ): MiddlewareBuilder<
595
478
  Layout,
596
- readonly [...Acc, MiddlewareReturnFromParts<
597
- TQuery,
598
- TParams,
599
- TBody,
600
- {},
601
- unknown,
602
- TQueryIn,
603
- TParamsIn,
604
- TBodyIn
605
- >],
479
+ readonly [
480
+ ...Acc,
481
+ MiddlewareReturnFromParts<
482
+ TQuery,
483
+ TParams,
484
+ TBody,
485
+ ExtractState<R>,
486
+ TQueryIn,
487
+ TParamsIn,
488
+ TBodyIn
489
+ >,
490
+ ],
606
491
  TAppContext
607
- >
608
- }
492
+ >;
493
+ };
609
494
 
610
495
  export type RouteExport<
611
496
  Path extends RoutePath,
@@ -614,27 +499,27 @@ export type RouteExport<
614
499
  TReturns extends ReturnsMap = {},
615
500
  TOutput = Response,
616
501
  > = Acc & {
617
- readonly path: Path
618
- readonly method: TMethod | 'ANY' | 'ALL'
619
- readonly methods?: readonly Method[]
620
- readonly middlewares: readonly MiddlewareDefinition[]
621
- readonly handlerMiddlewares: readonly MiddlewareDefinition[]
622
- readonly returns?: TReturns
623
- handler: (ctx: unknown) => Awaitable<Response>
502
+ readonly path: Path;
503
+ readonly method: TMethod | "ANY" | "ALL";
504
+ readonly methods?: readonly Method[];
505
+ readonly middlewares: readonly MiddlewareDefinition[];
506
+ readonly handlerMiddlewares: readonly MiddlewareDefinition[];
507
+ readonly returns?: TReturns;
508
+ handler: (ctx: unknown) => Awaitable<Response>;
624
509
  readonly $Infer: {
625
- Context: TMethod extends 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS'
510
+ Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
626
511
  ? RouteHandleContextWithoutBody<Path, TMethod, Acc, {}>
627
- : RouteHandleContext<Path, TMethod, Acc, {}>
512
+ : RouteHandleContext<Path, TMethod, Acc, {}>;
628
513
  /** Concrete handler reply (`ReplyOf` union) for client inference. */
629
- Output: TOutput
630
- }
631
- query?: Schema<unknown>
632
- params?: Schema<unknown>
633
- body?: Schema<unknown>
634
- handlerQuery?: Schema<unknown>
635
- handlerParams?: Schema<unknown>
636
- handlerBody?: Schema<unknown>
637
- }
514
+ Output: TOutput;
515
+ };
516
+ query?: Schema<unknown>;
517
+ params?: Schema<unknown>;
518
+ body?: Schema<unknown>;
519
+ handlerQuery?: Schema<unknown>;
520
+ handlerParams?: Schema<unknown>;
521
+ handlerBody?: Schema<unknown>;
522
+ };
638
523
 
639
524
  type RouteHandleResult<
640
525
  Path extends RoutePath,
@@ -644,17 +529,17 @@ type RouteHandleResult<
644
529
  TReturns extends ReturnsMap = {},
645
530
  TOutput = Response,
646
531
  TAppContext extends Record<string, unknown> = AppContext,
647
- > = Omit<RouteExport<Path, TMethod, Acc, TReturns, TOutput>, '$Infer'> & {
532
+ > = Omit<RouteExport<Path, TMethod, Acc, TReturns, TOutput>, "$Infer"> & {
648
533
  readonly $Infer: {
649
- Context: TMethod extends 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS'
534
+ Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
650
535
  ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext>
651
- : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>
652
- Input: TMethod extends 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS'
536
+ : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>;
537
+ Input: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
653
538
  ? RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators>
654
- : RouteHandleInput<Path, TMethod, Acc, Validators>
655
- Output: TOutput
656
- }
657
- }
539
+ : RouteHandleInput<Path, TMethod, Acc, Validators>;
540
+ Output: TOutput;
541
+ };
542
+ };
658
543
 
659
544
  export type RouteBuilder<
660
545
  Path extends RoutePath,
@@ -664,18 +549,32 @@ export type RouteBuilder<
664
549
  TReturns extends ReturnsMap = {},
665
550
  TAppContext extends Record<string, unknown> = AppContext,
666
551
  > = {
667
- readonly path: Path
668
- readonly method: TMethod
552
+ readonly path: Path;
553
+ readonly method: TMethod;
669
554
  readonly $Infer: {
670
- Context: TMethod extends 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS'
555
+ Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
671
556
  ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext>
672
- : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>
673
- }
557
+ : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>;
558
+ };
674
559
  returns<const M extends ReturnsMap>(
675
560
  map: M,
676
- ): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>
677
- use<TAcc, UReturns extends ReturnsMap = {}>(
678
- unit: MiddlewareUnit<TAcc, UReturns>,
561
+ ): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
562
+ use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
563
+ unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
564
+ ..._assert: [
565
+ IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
566
+ IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>,
567
+ ] extends [true, true]
568
+ ? []
569
+ : [
570
+ {
571
+ error: "Middleware cannot be attached to this route";
572
+ requiredLayouts: TRequiredLayouts;
573
+ routeLayoutChain: RouteLayoutChain<Path, TMethod>;
574
+ requiredState: TRequiredState;
575
+ actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
576
+ },
577
+ ]
679
578
  ): RouteBuilder<
680
579
  Path,
681
580
  TMethod,
@@ -683,10 +582,8 @@ export type RouteBuilder<
683
582
  Validators,
684
583
  Omit<TReturns, keyof UReturns> & UReturns,
685
584
  TAppContext
686
- >
585
+ >;
687
586
  use<
688
- TState,
689
- TCtx,
690
587
  TQuery = unknown,
691
588
  TParams = unknown,
692
589
  TBody = unknown,
@@ -694,169 +591,53 @@ export type RouteBuilder<
694
591
  TQueryIn = unknown,
695
592
  TParamsIn = unknown,
696
593
  TBodyIn = unknown,
594
+ R = unknown,
697
595
  >(
698
- options: StateAndCtxUseOptions<
596
+ options: InlineMiddlewareOptions<
699
597
  RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>,
700
- TState,
701
- TCtx,
702
598
  TQuery,
703
599
  TParams,
704
600
  TBody,
705
601
  UReturns,
706
602
  TQueryIn,
707
603
  TParamsIn,
708
- TBodyIn
604
+ TBodyIn,
605
+ R
709
606
  >,
710
607
  ): RouteBuilder<
711
608
  Path,
712
609
  TMethod,
713
- readonly [...Acc, MiddlewareReturnFromParts<
714
- TQuery,
715
- TParams,
716
- TBody,
717
- TState,
718
- TCtx,
719
- TQueryIn,
720
- TParamsIn,
721
- TBodyIn
722
- >],
723
- Validators,
724
- Omit<TReturns, keyof UReturns> & UReturns,
725
- TAppContext
726
- >
727
- use<
728
- TState,
729
- TQuery = unknown,
730
- TParams = unknown,
731
- TBody = unknown,
732
- UReturns extends ReturnsMap = {},
733
- TQueryIn = unknown,
734
- TParamsIn = unknown,
735
- TBodyIn = unknown,
736
- >(
737
- options: StatefulUseOptions<
738
- RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>,
739
- TState,
740
- TQuery,
741
- TParams,
742
- TBody,
743
- UReturns,
744
- TQueryIn,
745
- TParamsIn,
746
- TBodyIn
747
- >,
748
- ): RouteBuilder<
749
- Path,
750
- TMethod,
751
- readonly [...Acc, MiddlewareReturnFromParts<
752
- TQuery,
753
- TParams,
754
- TBody,
755
- TState,
756
- unknown,
757
- TQueryIn,
758
- TParamsIn,
759
- TBodyIn
760
- >],
761
- Validators,
762
- Omit<TReturns, keyof UReturns> & UReturns,
763
- TAppContext
764
- >
765
- use<
766
- TCtx,
767
- TQuery = unknown,
768
- TParams = unknown,
769
- TBody = unknown,
770
- UReturns extends ReturnsMap = {},
771
- TQueryIn = unknown,
772
- TParamsIn = unknown,
773
- TBodyIn = unknown,
774
- >(
775
- options: CtxUseOptions<
776
- RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>,
777
- TCtx,
778
- TQuery,
779
- TParams,
780
- TBody,
781
- UReturns,
782
- TQueryIn,
783
- TParamsIn,
784
- TBodyIn
785
- >,
786
- ): RouteBuilder<
787
- Path,
788
- TMethod,
789
- readonly [...Acc, MiddlewareReturnFromParts<
790
- TQuery,
791
- TParams,
792
- TBody,
793
- {},
794
- TCtx,
795
- TQueryIn,
796
- TParamsIn,
797
- TBodyIn
798
- >],
799
- Validators,
800
- Omit<TReturns, keyof UReturns> & UReturns,
801
- TAppContext
802
- >
803
- use<
804
- TQuery = unknown,
805
- TParams = unknown,
806
- TBody = unknown,
807
- UReturns extends ReturnsMap = {},
808
- TQueryIn = unknown,
809
- TParamsIn = unknown,
810
- TBodyIn = unknown,
811
- >(
812
- options: StatelessUseOptions<
813
- RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>,
814
- TQuery,
815
- TParams,
816
- TBody,
817
- UReturns,
818
- TQueryIn,
819
- TParamsIn,
820
- TBodyIn
821
- >,
822
- ): RouteBuilder<
823
- Path,
824
- TMethod,
825
- readonly [...Acc, MiddlewareReturnFromParts<
826
- TQuery,
827
- TParams,
828
- TBody,
829
- {},
830
- unknown,
831
- TQueryIn,
832
- TParamsIn,
833
- TBodyIn
834
- >],
610
+ readonly [
611
+ ...Acc,
612
+ MiddlewareReturnFromParts<
613
+ TQuery,
614
+ TParams,
615
+ TBody,
616
+ ExtractState<R>,
617
+ TQueryIn,
618
+ TParamsIn,
619
+ TBodyIn
620
+ >,
621
+ ],
835
622
  Validators,
836
623
  Omit<TReturns, keyof UReturns> & UReturns,
837
624
  TAppContext
838
- >
625
+ >;
839
626
  handler<R extends Response = Response>(
840
627
  fn: (
841
- ctx: TMethod extends 'GET' | 'DELETE' | 'HEAD' | 'OPTIONS'
628
+ ctx: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS"
842
629
  ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext>
843
630
  : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>,
844
631
  ) => Awaitable<R>,
845
632
  ..._assert: [R] extends [ValidHandlerReply<R, TReturns>]
846
633
  ? []
847
- : [{
848
- expected: ValidHandlerReply<R, TReturns>
849
- actual: R
850
- }]
851
- ): RouteHandleResult<
852
- Path,
853
- TMethod,
854
- Acc,
855
- Validators,
856
- TReturns,
857
- R,
858
- TAppContext
859
- >
634
+ : [
635
+ {
636
+ expected: ValidHandlerReply<R, TReturns>;
637
+ actual: R;
638
+ },
639
+ ]
640
+ ): RouteHandleResult<Path, TMethod, Acc, Validators, TReturns, R, TAppContext>;
860
641
  handler<
861
642
  HandlerAcc extends readonly unknown[] = readonly [],
862
643
  HandlerValidators extends ValidatorParts = ValidatorParts,
@@ -872,8 +653,8 @@ export type RouteBuilder<
872
653
  Omit<TReturns, keyof HReturns> & HReturns,
873
654
  HOutput,
874
655
  TAppContext
875
- >
876
- }
656
+ >;
657
+ };
877
658
 
878
659
  export type HandlerBuilder<
879
660
  Acc extends readonly unknown[] = readonly [],
@@ -883,18 +664,27 @@ export type HandlerBuilder<
883
664
  > = {
884
665
  returns<const M extends ReturnsMap>(
885
666
  map: M,
886
- ): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>
887
- use<TAcc, UReturns extends ReturnsMap = {}>(
888
- unit: MiddlewareUnit<TAcc, UReturns>,
667
+ ): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
668
+ use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
669
+ unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
670
+ ..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
671
+ true,
672
+ ]
673
+ ? []
674
+ : [
675
+ {
676
+ error: "Middleware cannot be attached to this handler";
677
+ requiredState: TRequiredState;
678
+ actualState: MergeMiddlewareField<Acc, "state">;
679
+ },
680
+ ]
889
681
  ): HandlerBuilder<
890
682
  readonly [...Acc, TAcc],
891
683
  Validators,
892
684
  Omit<TReturns, keyof UReturns> & UReturns,
893
685
  TAppContext
894
- >
686
+ >;
895
687
  use<
896
- TState,
897
- TCtx,
898
688
  TQuery = unknown,
899
689
  TParams = unknown,
900
690
  TBody = unknown,
@@ -902,163 +692,45 @@ export type HandlerBuilder<
902
692
  TQueryIn = unknown,
903
693
  TParamsIn = unknown,
904
694
  TBodyIn = unknown,
695
+ R = unknown,
905
696
  >(
906
- options: StateAndCtxUseOptions<
907
- HandlerContext<
908
- Acc,
909
- { query: TQuery, params: TParams, body: TBody },
910
- TAppContext
911
- >,
912
- TState,
913
- TCtx,
697
+ options: InlineMiddlewareOptions<
698
+ HandlerContext<Acc, { query: TQuery; params: TParams; body: TBody }, TAppContext>,
914
699
  TQuery,
915
700
  TParams,
916
701
  TBody,
917
702
  UReturns,
918
703
  TQueryIn,
919
704
  TParamsIn,
920
- TBodyIn
705
+ TBodyIn,
706
+ R
921
707
  >,
922
708
  ): HandlerBuilder<
923
- readonly [...Acc, MiddlewareReturnFromParts<
924
- TQuery,
925
- TParams,
926
- TBody,
927
- TState,
928
- TCtx,
929
- TQueryIn,
930
- TParamsIn,
931
- TBodyIn
932
- >],
933
- Validators,
934
- Omit<TReturns, keyof UReturns> & UReturns,
935
- TAppContext
936
- >
937
- use<
938
- TState,
939
- TQuery = unknown,
940
- TParams = unknown,
941
- TBody = unknown,
942
- UReturns extends ReturnsMap = {},
943
- TQueryIn = unknown,
944
- TParamsIn = unknown,
945
- TBodyIn = unknown,
946
- >(
947
- options: StatefulUseOptions<
948
- HandlerContext<
949
- Acc,
950
- { query: TQuery, params: TParams, body: TBody },
951
- TAppContext
952
- >,
953
- TState,
954
- TQuery,
955
- TParams,
956
- TBody,
957
- UReturns,
958
- TQueryIn,
959
- TParamsIn,
960
- TBodyIn
961
- >,
962
- ): HandlerBuilder<
963
- readonly [...Acc, MiddlewareReturnFromParts<
964
- TQuery,
965
- TParams,
966
- TBody,
967
- TState,
968
- unknown,
969
- TQueryIn,
970
- TParamsIn,
971
- TBodyIn
972
- >],
973
- Validators,
974
- Omit<TReturns, keyof UReturns> & UReturns,
975
- TAppContext
976
- >
977
- use<
978
- TCtx,
979
- TQuery = unknown,
980
- TParams = unknown,
981
- TBody = unknown,
982
- UReturns extends ReturnsMap = {},
983
- TQueryIn = unknown,
984
- TParamsIn = unknown,
985
- TBodyIn = unknown,
986
- >(
987
- options: CtxUseOptions<
988
- HandlerContext<
989
- Acc,
990
- { query: TQuery, params: TParams, body: TBody },
991
- TAppContext
709
+ readonly [
710
+ ...Acc,
711
+ MiddlewareReturnFromParts<
712
+ TQuery,
713
+ TParams,
714
+ TBody,
715
+ ExtractState<R>,
716
+ TQueryIn,
717
+ TParamsIn,
718
+ TBodyIn
992
719
  >,
993
- TCtx,
994
- TQuery,
995
- TParams,
996
- TBody,
997
- UReturns,
998
- TQueryIn,
999
- TParamsIn,
1000
- TBodyIn
1001
- >,
1002
- ): HandlerBuilder<
1003
- readonly [...Acc, MiddlewareReturnFromParts<
1004
- TQuery,
1005
- TParams,
1006
- TBody,
1007
- {},
1008
- TCtx,
1009
- TQueryIn,
1010
- TParamsIn,
1011
- TBodyIn
1012
- >],
1013
- Validators,
1014
- Omit<TReturns, keyof UReturns> & UReturns,
1015
- TAppContext
1016
- >
1017
- use<
1018
- TQuery = unknown,
1019
- TParams = unknown,
1020
- TBody = unknown,
1021
- UReturns extends ReturnsMap = {},
1022
- TQueryIn = unknown,
1023
- TParamsIn = unknown,
1024
- TBodyIn = unknown,
1025
- >(
1026
- options: StatelessUseOptions<
1027
- HandlerContext<
1028
- Acc,
1029
- { query: TQuery, params: TParams, body: TBody },
1030
- TAppContext
1031
- >,
1032
- TQuery,
1033
- TParams,
1034
- TBody,
1035
- UReturns,
1036
- TQueryIn,
1037
- TParamsIn,
1038
- TBodyIn
1039
- >,
1040
- ): HandlerBuilder<
1041
- readonly [...Acc, MiddlewareReturnFromParts<
1042
- TQuery,
1043
- TParams,
1044
- TBody,
1045
- {},
1046
- unknown,
1047
- TQueryIn,
1048
- TParamsIn,
1049
- TBodyIn
1050
- >],
720
+ ],
1051
721
  Validators,
1052
722
  Omit<TReturns, keyof UReturns> & UReturns,
1053
723
  TAppContext
1054
- >
724
+ >;
1055
725
  handler<R extends Response = Response>(
1056
726
  fn: (ctx: HandlerContext<Acc, Validators, TAppContext>) => Awaitable<R>,
1057
727
  ..._assert: [R] extends [ValidHandlerReply<R, TReturns>]
1058
728
  ? []
1059
- : [{
1060
- expected: ValidHandlerReply<R, TReturns>
1061
- actual: R
1062
- }]
1063
- ): HandlerUnit<Acc, Validators, TReturns, R>
1064
- }
729
+ : [
730
+ {
731
+ expected: ValidHandlerReply<R, TReturns>;
732
+ actual: R;
733
+ },
734
+ ]
735
+ ): HandlerUnit<Acc, Validators, TReturns, R>;
736
+ };