@mpen/routekit 0.1.0 → 0.1.2

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 (133) hide show
  1. package/dist/bin.d.mts +4 -0
  2. package/dist/client/react.d.mts +178 -0
  3. package/dist/client/react.mjs +142 -0
  4. package/dist/client.d.mts +433 -0
  5. package/dist/client.mjs +264 -0
  6. package/dist/content-BuDOmhH_.mjs +102 -0
  7. package/dist/core-CzUCxvGk.d.mts +140 -0
  8. package/dist/core-DbmQauwS.mjs +81 -0
  9. package/dist/handlers.d.mts +72 -0
  10. package/dist/handlers.mjs +153 -0
  11. package/dist/index.d.mts +3 -0
  12. package/dist/index.mjs +1152 -0
  13. package/dist/middleware.d.mts +388 -0
  14. package/dist/middleware.mjs +1222 -0
  15. package/dist/request-Dn0zc-xm.mjs +1025 -0
  16. package/dist/response/content.d.mts +79 -0
  17. package/dist/response/content.mjs +2 -0
  18. package/dist/response/json-rpc.d.mts +1 -0
  19. package/dist/response/json-rpc.mjs +1 -0
  20. package/dist/response/problem/valibot.d.mts +230 -0
  21. package/dist/response/problem/valibot.mjs +258 -0
  22. package/dist/response/problem.d.mts +415 -0
  23. package/dist/response/problem.mjs +183 -0
  24. package/dist/response/status.d.mts +45 -0
  25. package/dist/response/status.mjs +2 -0
  26. package/dist/responses-B379Ep9Y.d.mts +296 -0
  27. package/dist/responses-BpVrgeYi.mjs +101 -0
  28. package/dist/router-Cwb7ak0J.d.mts +1819 -0
  29. package/dist/routes.d.mts +282 -0
  30. package/dist/routes.mjs +311 -0
  31. package/dist/status-C-8mw-FB.mjs +59 -0
  32. package/dist/valibot-D7liFYyB.d.mts +290 -0
  33. package/dist/valibot-Du97X-TS.mjs +326 -0
  34. package/package.json +8 -2
  35. package/src/bin/gen-api-client.test.ts +0 -70
  36. package/src/bin/gen-api-client.ts +0 -986
  37. package/src/client/headers.ts +0 -31
  38. package/src/client/index.ts +0 -8
  39. package/src/client/promise.ts +0 -11
  40. package/src/client/react/index.test.tsx +0 -266
  41. package/src/client/react/index.ts +0 -431
  42. package/src/client/responses.test.ts +0 -151
  43. package/src/client/responses.ts +0 -278
  44. package/src/client/transport.ts +0 -74
  45. package/src/client/transports/body-codec.ts +0 -61
  46. package/src/client/transports/fetch.ts +0 -113
  47. package/src/client/tsconfig.json +0 -9
  48. package/src/client/types.ts +0 -15
  49. package/src/client/url.ts +0 -31
  50. package/src/index.ts +0 -63
  51. package/src/router/fetch-types.ts +0 -13
  52. package/src/router/handlers/index.ts +0 -2
  53. package/src/router/handlers/openapi/index.ts +0 -2
  54. package/src/router/handlers/openapi/openapi.ts +0 -293
  55. package/src/router/integration/zod-openapi.test.ts +0 -74
  56. package/src/router/lib/charset.test.ts +0 -22
  57. package/src/router/lib/charset.ts +0 -133
  58. package/src/router/lib/collections.ts +0 -3
  59. package/src/router/lib/format.test.ts +0 -67
  60. package/src/router/lib/format.ts +0 -35
  61. package/src/router/lib/host.ts +0 -4
  62. package/src/router/lib/json-schema.ts +0 -6
  63. package/src/router/lib/media-type.test.ts +0 -122
  64. package/src/router/lib/media-type.ts +0 -289
  65. package/src/router/lib/pathname.test.ts +0 -18
  66. package/src/router/lib/pathname.ts +0 -19
  67. package/src/router/lib/route-names.ts +0 -70
  68. package/src/router/lib/route-normalize.test.ts +0 -36
  69. package/src/router/lib/route-normalize.ts +0 -67
  70. package/src/router/lib/schema-merge.ts +0 -56
  71. package/src/router/middleware/accept-ctx.test.ts +0 -33
  72. package/src/router/middleware/accept-ctx.ts +0 -12
  73. package/src/router/middleware/body-limit.test.ts +0 -112
  74. package/src/router/middleware/body-limit.ts +0 -121
  75. package/src/router/middleware/content-type-context.ts +0 -0
  76. package/src/router/middleware/cors.test.ts +0 -269
  77. package/src/router/middleware/cors.ts +0 -490
  78. package/src/router/middleware/csrf.test.ts +0 -106
  79. package/src/router/middleware/csrf.ts +0 -192
  80. package/src/router/middleware/define.ts +0 -249
  81. package/src/router/middleware/index.ts +0 -34
  82. package/src/router/middleware/jsxhtml-response.ts +0 -0
  83. package/src/router/middleware/oas-swagger.ts +0 -0
  84. package/src/router/middleware/rate-limit.test.ts +0 -886
  85. package/src/router/middleware/rate-limit.ts +0 -920
  86. package/src/router/middleware/request-id-ctx.test.ts +0 -183
  87. package/src/router/middleware/request-id-ctx.ts +0 -135
  88. package/src/router/middleware/request-logger-format.test.ts +0 -16
  89. package/src/router/middleware/request-logger-format.ts +0 -269
  90. package/src/router/middleware/request-logger.test.ts +0 -267
  91. package/src/router/middleware/request-logger.ts +0 -131
  92. package/src/router/middleware/start-time-ctx.ts +0 -5
  93. package/src/router/request.ts +0 -611
  94. package/src/router/response/core.ts +0 -181
  95. package/src/router/response/directives.ts +0 -233
  96. package/src/router/response/formats/content/bodyless.ts +0 -54
  97. package/src/router/response/formats/content/content.ts +0 -79
  98. package/src/router/response/formats/content/index.ts +0 -2
  99. package/src/router/response/formats/json-rpc/index.ts +0 -2
  100. package/src/router/response/formats/problem/badRequest.ts +0 -90
  101. package/src/router/response/formats/problem/conflict.ts +0 -90
  102. package/src/router/response/formats/problem/created.ts +0 -40
  103. package/src/router/response/formats/problem/index.ts +0 -27
  104. package/src/router/response/formats/problem/notFound.ts +0 -90
  105. package/src/router/response/formats/problem/permissionDenied.ts +0 -90
  106. package/src/router/response/formats/problem/problem.test.ts +0 -888
  107. package/src/router/response/formats/problem/rateLimited.ts +0 -90
  108. package/src/router/response/formats/problem/responses.ts +0 -219
  109. package/src/router/response/formats/problem/root-errors.ts +0 -48
  110. package/src/router/response/formats/problem/sessionExpired.ts +0 -90
  111. package/src/router/response/formats/problem/types.ts +0 -170
  112. package/src/router/response/formats/problem/unauthenticated.ts +0 -90
  113. package/src/router/response/formats/problem/valibot.ts +0 -410
  114. package/src/router/response/formats/status/index.ts +0 -1
  115. package/src/router/response/formats/status/responses.ts +0 -59
  116. package/src/router/response/formats/status/status.test.ts +0 -21
  117. package/src/router/response/framers.ts +0 -85
  118. package/src/router/response/index.ts +0 -28
  119. package/src/router/response/openapi.test.ts +0 -96
  120. package/src/router/response/openapi.ts +0 -1
  121. package/src/router/response/serializers.ts +0 -66
  122. package/src/router/response/stream.ts +0 -35
  123. package/src/router/router.test.ts +0 -1571
  124. package/src/router/router.ts +0 -1965
  125. package/src/router/routes/index.ts +0 -46
  126. package/src/router/routes/valibot/index.ts +0 -18
  127. package/src/router/routes/valibot/valibot.ts +0 -1393
  128. package/src/router/routes/valibot.test.ts +0 -286
  129. package/src/router/routes/zod/index.ts +0 -18
  130. package/src/router/routes/zod/zod.ts +0 -1318
  131. package/src/router/routes/zod.test.ts +0 -280
  132. package/src/router/server-interface.ts +0 -31
  133. package/src/router/types.ts +0 -657
@@ -1,657 +0,0 @@
1
- import type { HttpMethod } from '@mpen/http'
2
- import type { Logger } from '@mpen/logger'
3
- import type { Router } from './router'
4
- import type { RouterBodyInit } from './fetch-types'
5
- import type { DeclaredMiddleware } from './middleware/define'
6
- import type { RequestBodyParser, RoutekitRequest } from './request'
7
- import type {
8
- ResponseBodySerializer,
9
- RoutekitBody,
10
- RoutekitResponse,
11
- RoutekitYield,
12
- } from './response'
13
-
14
- export type NonEmptyArray<T> = [T, ...T[]]
15
- export type OneOrMany<T> = T | NonEmptyArray<T>
16
- export type MaybePromise<T> = T | Promise<T>
17
- export type RoutePath = string | URLPattern
18
-
19
- /**
20
- * JSON Schema value used for runtime request and response metadata.
21
- */
22
- export type JsonSchema = boolean | Record<string, unknown>
23
-
24
- /**
25
- * JSON Schema object used for path and query parameter declarations.
26
- */
27
- export type JsonObjectSchema = Record<string, unknown>
28
-
29
- /**
30
- * Schema metadata used to describe route request inputs and response bodies.
31
- *
32
- * @example
33
- * ```ts
34
- * const schema: RouteSchema = {
35
- * request: {
36
- * query: {
37
- * type: 'object',
38
- * properties: {
39
- * page: {type: 'integer'},
40
- * },
41
- * },
42
- * path: {
43
- * type: 'object',
44
- * properties: {
45
- * id: {type: 'string'},
46
- * },
47
- * required: ['id'],
48
- * },
49
- * body: {
50
- * type: 'object',
51
- * properties: {
52
- * name: {type: 'string'},
53
- * },
54
- * required: ['name'],
55
- * },
56
- * },
57
- * response: {
58
- * body: {
59
- * 200: {
60
- * type: 'object',
61
- * properties: {
62
- * ok: {type: 'boolean'},
63
- * },
64
- * required: ['ok'],
65
- * },
66
- * },
67
- * },
68
- * }
69
- * ```
70
- */
71
- export interface RouteSchema {
72
- request?: {
73
- query?: JsonObjectSchema
74
- path?: JsonObjectSchema
75
- body?: JsonSchema
76
- }
77
- response?: {
78
- body?: Partial<Record<number | 'default', JsonSchema>>
79
- }
80
- }
81
-
82
- /**
83
- * Custom request matcher used when a route needs logic beyond pathname, method, or `accept`.
84
- *
85
- * @example
86
- * ```ts
87
- * const match: RouteMatch = request => request.headers.get('x-internal') === 'true'
88
- * ```
89
- *
90
- * @param request - Incoming request to test.
91
- * @returns `true` when the route should handle the request.
92
- */
93
- export type RouteMatch = (request: RoutekitRequest) => boolean
94
-
95
- /**
96
- * Route metadata used by tooling like OpenAPI generation.
97
- */
98
- export interface RouteMeta {
99
- /**
100
- * OpenAPI operation metadata for this route.
101
- */
102
- openapi?: Record<string, unknown>
103
- [key: string]: unknown
104
- }
105
-
106
- type AddedContextOf<Middleware> =
107
- Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<infer AddedCtx, any>
108
- ? AddedCtx
109
- : Exclude<Middleware, null | undefined | false> extends ContextMiddleware<
110
- infer AddedCtx,
111
- any
112
- >
113
- ? AddedCtx
114
- : Exclude<Middleware, null | undefined | false> extends RequestMiddleware<
115
- infer AddedCtx,
116
- any
117
- >
118
- ? AddedCtx
119
- : {}
120
-
121
- type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends (
122
- value: infer Intersection,
123
- ) => void
124
- ? Intersection
125
- : never
126
-
127
- type AddedContextFromList<List extends readonly unknown[]> = List extends readonly [
128
- infer First,
129
- ...infer Rest,
130
- ]
131
- ? AddedContextOf<First> & AddedContextFromList<Rest>
132
- : number extends List['length']
133
- ? UnionToIntersection<AddedContextOf<List[number]>>
134
- : {}
135
-
136
- type ContextOf<Middleware> =
137
- Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<any, infer Ctx>
138
- ? Ctx
139
- : Exclude<Middleware, null | undefined | false> extends ContextMiddleware<any, infer Ctx>
140
- ? Ctx
141
- : Exclude<Middleware, null | undefined | false> extends RequestMiddleware<any, infer Ctx>
142
- ? Ctx
143
- : object
144
-
145
- type ContextFromList<List extends readonly unknown[]> = List extends readonly [
146
- infer First,
147
- ...infer Rest,
148
- ]
149
- ? ContextOf<First> & ContextFromList<Rest>
150
- : number extends List['length']
151
- ? UnionToIntersection<ContextOf<List[number]>>
152
- : object
153
-
154
- /**
155
- * Context added by a middleware value or middleware list.
156
- *
157
- * @example
158
- * ```ts
159
- * type AuthContext = AddedContextFromMiddlewareInput<typeof requireAuth>
160
- * ```
161
- *
162
- * @typeParam Middleware - Middleware value or list whose added context should be inferred.
163
- */
164
- export type AddedContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[]
165
- ? AddedContextFromList<Middleware>
166
- : AddedContextOf<Middleware>
167
-
168
- /**
169
- * Base context expected by a middleware value or middleware list.
170
- *
171
- * @example
172
- * ```ts
173
- * type ServicesContext = ContextFromMiddlewareInput<typeof requireAuth>
174
- * ```
175
- *
176
- * @typeParam Middleware - Middleware value or list whose base context should be inferred.
177
- */
178
- export type ContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[]
179
- ? ContextFromList<Middleware>
180
- : ContextOf<Middleware>
181
-
182
- /**
183
- * Declarative route definition that the router can normalize and register.
184
- *
185
- * @example
186
- * ```ts
187
- * const route: Route = {
188
- * name: 'user.detail',
189
- * method: HttpMethod.GET,
190
- * path: '/users/:id',
191
- * handler: async ({request}) => new Response(await request.body.text()),
192
- * }
193
- * ```
194
- */
195
- export interface Route<
196
- Ctx extends object = AnyContext,
197
- RouteMiddleware extends MiddlewareInput<Ctx> = undefined,
198
- HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>,
199
- > {
200
- name?: OneOrMany<string>
201
- /**
202
- * Path pattern matched by the default route matcher.
203
- */
204
- path: RoutePath
205
- handler: Handler<any, HandlerCtx>
206
- method?: OneOrMany<HttpMethod>
207
- /**
208
- * Middleware applied only to this route after router and mount middleware.
209
- *
210
- * @example
211
- * ```ts
212
- * const route: Route = {
213
- * path: '/me',
214
- * middleware: auth(),
215
- * handler: ({userId}) => new Response(userId),
216
- * }
217
- * ```
218
- */
219
- middleware?: RouteMiddleware
220
- /**
221
- * Optional custom matcher. When omitted, the router matches using `path`, `method`, and `accept`.
222
- */
223
- match?: RouteMatch
224
- /**
225
- * Arbitrary metadata attached to the route.
226
- *
227
- * @example
228
- * ```ts
229
- * const route: Route = {
230
- * path: '/pets',
231
- * method: HttpMethod.GET,
232
- * meta: {
233
- * openapi: {
234
- * description: 'Returns all pets from the system that the user has access to',
235
- * responses: {
236
- * 200: {description: 'A list of pets'},
237
- * },
238
- * },
239
- * },
240
- * handler: () => new Response('ok'),
241
- * }
242
- * ```
243
- */
244
- meta?: RouteMeta
245
- /**
246
- * Expected media type(s) for the incoming request body. When provided, the router compares each
247
- * entry against the incoming `Content-Type` header.
248
- *
249
- * @example
250
- * ```ts
251
- * const route: Route = {
252
- * path: '/upload',
253
- * method: HttpMethod.POST,
254
- * accept: ['multipart/form-data', {type: 'application/json'}],
255
- * handler: async () => new Response('ok'),
256
- * }
257
- * ```
258
- */
259
- accept?: OneOrMany<string | MediaType>
260
- /**
261
- * Runtime request and response schemas used by tooling such as OpenAPI generation and API client codegen.
262
- */
263
- schema?: RouteSchema
264
- }
265
-
266
- /**
267
- * Route definition fields accepted by method-specific router helpers.
268
- *
269
- * @example
270
- * ```ts
271
- * const options: RouteOptions = {
272
- * name: 'user.detail',
273
- * handler: async ({request}) => new Response(request.url),
274
- * }
275
- * router.get('/users/:id', options)
276
- * ```
277
- */
278
- export type RouteOptions<
279
- Ctx extends object = AnyContext,
280
- RouteMiddleware extends MiddlewareInput<Ctx> = undefined,
281
- HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>,
282
- > = Omit<Route<Ctx, RouteMiddleware, HandlerCtx>, 'method' | 'path'>
283
-
284
- /**
285
- * Normalized route metadata used internally by the router.
286
- *
287
- * @example
288
- * ```ts
289
- * const route: NormalizedRoute = {
290
- * name: ['user', 'detail'],
291
- * method: HttpMethod.GET,
292
- * path: new URLPattern({pathname: '/users/:id'}),
293
- * handler: async ({request}) => new Response(await request.body.text()),
294
- * }
295
- * ```
296
- */
297
- export interface NormalizedRoute<Ctx extends object = AnyContext> {
298
- name: string[]
299
- path: URLPattern
300
- handler: Handler<any, Ctx>
301
- method?: HttpMethod | HttpMethod[]
302
- accept?: MediaType[]
303
- match?: RouteMatch
304
- meta?: RouteMeta
305
- schema?: RouteSchema
306
- }
307
-
308
- /**
309
- * Parameterized HTTP `Content-Type` media type.
310
- *
311
- * @example
312
- * ```ts
313
- * const contentType: ContentType = {type: 'application/json', charset: 'utf-8'}
314
- * ```
315
- */
316
- export type ContentType = {
317
- type: string
318
- charset?: string
319
- boundary?: string
320
- parameters?: Record<string, string>
321
- }
322
-
323
- /**
324
- * Backwards-compatible alias for a concrete media type.
325
- *
326
- * @example
327
- * ```ts
328
- * const media: MediaType = {type: 'application/json'}
329
- * ```
330
- */
331
- export type MediaType = ContentType
332
-
333
- /**
334
- * Media range parsed from an HTTP `Accept` header.
335
- *
336
- * @example
337
- * ```ts
338
- * const accept: AcceptMediaRange = {type: 'application/json', q: 1}
339
- * ```
340
- */
341
- export type AcceptMediaRange = ContentType & {
342
- q: number
343
- }
344
-
345
- /**
346
- * Generic context dictionary used when no custom context type is provided.
347
- *
348
- * @example
349
- * ```ts
350
- * const ctx: AnyContext = {featureFlag: true}
351
- * ```
352
- */
353
- export type AnyContext = Record<string, any>
354
-
355
- /**
356
- * Extension hook that intentionally configures a router instance.
357
- *
358
- * @example
359
- * ```ts
360
- * const extension: RouterExtension = router => {
361
- * router.onNotFound(() => new Response('missing', {status: 404}))
362
- * }
363
- *
364
- * new Router().install(extension)
365
- * ```
366
- *
367
- * @typeParam Ctx - Context carried by the router being configured.
368
- */
369
- export type RouterExtension<Ctx extends object = AnyContext> = (router: Router<Ctx>) => void
370
-
371
- /**
372
- * Request context made available to middleware.
373
- * Extended data can be attached by middleware via the generic parameter.
374
- *
375
- * @example
376
- * ```ts
377
- * const middleware: ContextMiddleware<{userId: string}> = ctx => {
378
- * ctx.userId = 'user-123'
379
- * }
380
- * ```
381
- */
382
- export type RequestContext<Ctx extends object = AnyContext> = {
383
- /**
384
- * Routekit request wrapper for the current request.
385
- */
386
- request: RoutekitRequest
387
- /**
388
- * Contextual logger selected for the current request.
389
- */
390
- logger: Logger
391
- } & Ctx
392
-
393
- /**
394
- * Context object provided to route handlers.
395
- * Includes request metadata as well as any context extensions added by middleware.
396
- *
397
- * @example
398
- * ```ts
399
- * const handler: HandlerContext = {
400
- * request,
401
- * url: new URL('https://example.com/users/123'),
402
- * path: {id: '123'},
403
- * }
404
- * ```
405
- */
406
- export type HandlerContext<Ctx extends object = AnyContext> = RequestContext<Ctx> & {
407
- /**
408
- * Parsed request URL for convenience.
409
- */
410
- url: URL
411
- /**
412
- * Route path parameters extracted from the matched URL pattern.
413
- */
414
- path: unknown
415
- }
416
-
417
- /**
418
- * Values yielded by generator-style handlers.
419
- *
420
- * @example
421
- * ```ts
422
- * async function* handler() {
423
- * yield head(HttpStatus.OK, {'cache-control': 'no-store'})
424
- * return {ok: true}
425
- * }
426
- * ```
427
- */
428
- export type HandlerYield = RoutekitYield
429
-
430
- /**
431
- * Native body value that can be passed to the Fetch [`Response`]{@link Response} constructor.
432
- *
433
- * @example
434
- * ```ts
435
- * const body: HandlerBody = 'ok'
436
- * ```
437
- */
438
- export type HandlerBody = RouterBodyInit | null | undefined
439
-
440
- /**
441
- * Final value a handler or generator may return.
442
- */
443
- export type HandlerFinalResult<TOkRes = unknown> =
444
- | Response
445
- | RoutekitResponse<TOkRes>
446
- | RoutekitBody<TOkRes>
447
- | TOkRes
448
- | HandlerBody
449
-
450
- /**
451
- * Allowed handler return values.
452
- *
453
- * @example
454
- * ```ts
455
- * const handler: Handler = async ({request}) => new Response(await request.body.text())
456
- * ```
457
- */
458
- export type HandlerResult<TOkRes = unknown> =
459
- | HandlerFinalResult<TOkRes>
460
- | Promise<HandlerFinalResult<TOkRes> | AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>>
461
- | AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>
462
-
463
- /**
464
- * Route handler signature that preserves generic type parameters for API generation.
465
- *
466
- * @example
467
- * ```ts
468
- * const handler: Handler = ({path}) => {
469
- * return JSON.stringify(path)
470
- * }
471
- * ```
472
- *
473
- * The handler is invoked with `this` bound to the active [`Router`]{@link Router}.
474
- *
475
- * @param ctx - Handler context containing the incoming [`RoutekitRequest`]{@link RoutekitRequest}, parsed [`URL`]{@link URL}, path parameters, and middleware extensions.
476
- * @returns A response, a serializable value handled by middleware, or a streaming generator that yields response metadata.
477
- */
478
- export type Handler<TOkRes = unknown, Ctx extends object = AnyContext> = (
479
- this: Router<any>,
480
- ctx: HandlerContext<Ctx>,
481
- ) => HandlerResult<TOkRes>
482
-
483
- /**
484
- * Middleware that extends request context and then continues routing.
485
- *
486
- * @example
487
- * ```ts
488
- * const addRequestId = (): ContextMiddleware<{requestId: number}> => ctx => {
489
- * ctx.requestId = 123
490
- * }
491
- * ```
492
- *
493
- * @param ctx - Request context for the current request, including any added fields.
494
- * @returns Nothing, or a promise resolved after context initialization.
495
- */
496
- export type ContextMiddleware<
497
- AddedCtx extends object = AnyContext,
498
- Ctx extends object = AnyContext,
499
- > = (ctx: RequestContext<Ctx & AddedCtx>) => void | Promise<void>
500
-
501
- /**
502
- * Middleware that surrounds final response production for every incoming request.
503
- *
504
- * @example
505
- * ```ts
506
- * const timing: RequestMiddleware = async (ctx, next) => {
507
- * const started = performance.now()
508
- * const response = await next()
509
- * ctx.logger.info('completed', {duration: performance.now() - started})
510
- * return response
511
- * }
512
- * ```
513
- *
514
- * @param ctx - Request context shared with downstream middleware and handlers.
515
- * @param next - Continue processing and obtain the final response.
516
- * @returns The final response, optionally decorated by the middleware.
517
- * @typeParam AddedCtx - Context fields made available to downstream processing.
518
- * @typeParam Ctx - Context required before this middleware executes.
519
- */
520
- export type RequestMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext> = (
521
- ctx: HandlerContext<Ctx & AddedCtx>,
522
- next: () => Promise<Response>,
523
- ) => Response | Promise<Response>
524
-
525
- /**
526
- * Middleware entry accepted inside typed middleware lists.
527
- *
528
- * @example
529
- * ```ts
530
- * const middleware = [auth(), false] satisfies MiddlewareEntry[]
531
- * ```
532
- *
533
- * @typeParam Ctx - Base context available before this middleware runs.
534
- */
535
- export type MiddlewareEntry<Ctx extends object = AnyContext> =
536
- | ContextMiddleware<any, Ctx>
537
- | DeclaredMiddleware<any, Ctx>
538
- | null
539
- | undefined
540
- | false
541
-
542
- /**
543
- * Middleware that performs context-only request initialization.
544
- *
545
- * @example
546
- * ```ts
547
- * const middleware: Middleware = ctx => {
548
- * ctx.request.headers.get('accept')
549
- * }
550
- * ```
551
- *
552
- * @param ctx - Request context for the current request.
553
- * @returns Nothing, or a promise resolved after context initialization.
554
- */
555
- export type Middleware<Ctx extends object = AnyContext> = ContextMiddleware<{}, Ctx>
556
-
557
- /**
558
- * Middleware list container for registering multiple middleware entries.
559
- *
560
- * @example
561
- * ```ts
562
- * const middleware: MiddlewareList = [auth(), logging()]
563
- * ```
564
- *
565
- * @param list - Collection of middleware entries, optionally including falsy values.
566
- * @returns A list of middleware compatible with `Router.use`.
567
- */
568
- export type MiddlewareList<Ctx extends object = AnyContext> = ReadonlyArray<MiddlewareEntry<Ctx>>
569
-
570
- /**
571
- * Middleware value accepted by router middleware registration APIs.
572
- *
573
- * @example
574
- * ```ts
575
- * const input: MiddlewareInput = [auth(), logging()]
576
- * ```
577
- *
578
- * @typeParam Ctx - Base context available before this middleware runs.
579
- */
580
- export type MiddlewareInput<Ctx extends object = AnyContext> =
581
- | OneOrMany<MiddlewareEntry<Ctx>>
582
- | MiddlewareList<Ctx>
583
- | null
584
- | undefined
585
- | false
586
-
587
- /**
588
- * Request-boundary middleware entry accepted by [`Router.useRequest`]{@link Router#useRequest}.
589
- *
590
- * @typeParam Ctx - Base context available before this middleware runs.
591
- */
592
- export type RequestMiddlewareEntry<Ctx extends object = AnyContext> =
593
- | RequestMiddleware<any, Ctx>
594
- | null
595
- | undefined
596
- | false
597
-
598
- /**
599
- * Request-boundary middleware input accepted by [`Router.useRequest`]{@link Router#useRequest}.
600
- *
601
- * @typeParam Ctx - Base context available before this middleware runs.
602
- */
603
- export type RequestMiddlewareInput<Ctx extends object = AnyContext> =
604
- | OneOrMany<RequestMiddlewareEntry<Ctx>>
605
- | ReadonlyArray<RequestMiddlewareEntry<Ctx>>
606
- | null
607
- | undefined
608
- | false
609
-
610
- /**
611
- * Request body parser value accepted by router request body parser APIs.
612
- *
613
- * @example
614
- * ```ts
615
- * const input: RequestBodyParserInput = [jsonRequestBodyParser()]
616
- * ```
617
- */
618
- export type RequestBodyParserInput =
619
- | RequestBodyParser
620
- | ReadonlyArray<RequestBodyParser | null | undefined | false>
621
- | null
622
- | undefined
623
- | false
624
-
625
- /**
626
- * Response body serializer value accepted by router response body serializer APIs.
627
- *
628
- * @example
629
- * ```ts
630
- * const input: ResponseBodySerializerInput = [jsonResponseBodySerializer()]
631
- * ```
632
- */
633
- export type ResponseBodySerializerInput =
634
- | ResponseBodySerializer
635
- | ReadonlyArray<ResponseBodySerializer | null | undefined | false>
636
- | null
637
- | undefined
638
- | false
639
-
640
- /**
641
- * Options for mounting a router or configuring a scoped inline router.
642
- *
643
- * @example
644
- * ```ts
645
- * const options: RouterMountOptions = {prefix: '/admin', middleware: auth()}
646
- * ```
647
- */
648
- export interface RouterMountOptions<Ctx extends object = AnyContext> {
649
- /**
650
- * Optional pathname prefix for the mounted routes.
651
- */
652
- prefix?: string
653
- /**
654
- * Middleware applied to the mounted router scope.
655
- */
656
- middleware?: MiddlewareInput<Ctx>
657
- }