@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
@@ -0,0 +1,1819 @@
1
+ import { l as RouterBodyInit, n as RoutekitResponse, t as RoutekitBody, u as RouterHeadersInit } from "./core-CzUCxvGk.mjs";
2
+ import { HttpMethod, HttpStatus } from "@mpen/http";
3
+ import { Logger } from "@mpen/logger";
4
+
5
+ //#region src/router/server-interface.d.ts
6
+ interface SimpleServerInterface {
7
+ fetch(request: Request): Promise<Response>;
8
+ }
9
+ //#endregion
10
+ //#region src/router/response/framers.d.ts
11
+ type MaybePromise$2<T> = T | Promise<T>;
12
+ type BodyChunk = string | Uint8Array | Buffer;
13
+ /**
14
+ * Framer used by streaming generators to encode structured chunks.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * yield stream(sseFramer())
19
+ * yield chunk({event: 'ready'})
20
+ * ```
21
+ */
22
+ interface StreamFramer<T = unknown> {
23
+ /**
24
+ * Content type for the stream.
25
+ */
26
+ contentType: string;
27
+ /**
28
+ * Headers to add when this stream starts.
29
+ */
30
+ headers?: RouterHeadersInit;
31
+ /**
32
+ * Return `true` when this framer can encode the provided chunk.
33
+ *
34
+ * @param value - Stream chunk to inspect.
35
+ * @returns Whether `value` can be framed.
36
+ */
37
+ canFrame?: (value: unknown) => value is T;
38
+ /**
39
+ * Encode one logical stream chunk.
40
+ *
41
+ * @param value - Stream chunk to encode.
42
+ * @returns Encoded stream bytes or text.
43
+ */
44
+ frame(value: T): MaybePromise$2<BodyChunk>;
45
+ /**
46
+ * Optional final stream bytes emitted when the generator completes.
47
+ *
48
+ * @returns Encoded closing bytes or text.
49
+ */
50
+ close?(): MaybePromise$2<BodyChunk | undefined>;
51
+ }
52
+ /**
53
+ * Create an SSE stream framer.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * yield stream(sseFramer())
58
+ * yield chunk({event: 'ready'})
59
+ * ```
60
+ *
61
+ * @returns Stream framer for `text/event-stream`.
62
+ */
63
+ declare function sseFramer(): StreamFramer<unknown>;
64
+ /**
65
+ * Create a JSON Lines stream framer.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * yield stream(jsonLinesFramer())
70
+ * yield chunk({event: 'ready'})
71
+ * ```
72
+ *
73
+ * @returns Stream framer for `application/jsonl`.
74
+ */
75
+ declare function jsonLinesFramer(): StreamFramer<unknown>;
76
+ //#endregion
77
+ //#region src/router/response/directives.d.ts
78
+ declare const routekitDirectiveBrand: unique symbol;
79
+ interface BaseDirective {
80
+ readonly [routekitDirectiveBrand]: true;
81
+ }
82
+ /**
83
+ * Generator directive that sets the response status.
84
+ */
85
+ interface StatusDirective extends BaseDirective {
86
+ kind: 'status';
87
+ status: number | HttpStatus;
88
+ }
89
+ /**
90
+ * Generator directive that merges response headers.
91
+ */
92
+ interface HeadersDirective extends BaseDirective {
93
+ kind: 'headers';
94
+ headers: Headers;
95
+ }
96
+ /**
97
+ * Generator directive that sets response status and merges response headers.
98
+ */
99
+ interface HeadDirective extends BaseDirective {
100
+ kind: 'head';
101
+ status: number | HttpStatus;
102
+ headers: Headers;
103
+ }
104
+ /**
105
+ * Generator directive that starts structured streaming with a framer.
106
+ */
107
+ interface StreamDirective<T = unknown> extends BaseDirective {
108
+ kind: 'stream';
109
+ framer: StreamFramer<T>;
110
+ headers: Headers;
111
+ }
112
+ /**
113
+ * Generator directive that emits one stream chunk.
114
+ */
115
+ interface ChunkDirective<T = unknown> extends BaseDirective {
116
+ kind: 'chunk';
117
+ value: T;
118
+ }
119
+ /**
120
+ * Values that generator-style handlers may yield.
121
+ */
122
+ type RoutekitYield = StatusDirective | HeadersDirective | HeadDirective | StreamDirective | ChunkDirective | undefined;
123
+ /**
124
+ * Test whether a value is a generator directive.
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * if (isRoutekitDirective(value)) console.log(value.kind)
129
+ * ```
130
+ *
131
+ * @param value - Value to inspect.
132
+ * @returns Whether `value` is a Routekit generator directive.
133
+ */
134
+ declare function isRoutekitDirective(value: unknown): value is Exclude<RoutekitYield, undefined>;
135
+ /**
136
+ * Test whether a value is a status directive.
137
+ *
138
+ * @param value - Value to inspect.
139
+ * @returns Whether `value` was created by [`status`]{@link status}.
140
+ */
141
+ declare function isStatusDirective(value: unknown): value is StatusDirective;
142
+ /**
143
+ * Test whether a value is a headers directive.
144
+ *
145
+ * @param value - Value to inspect.
146
+ * @returns Whether `value` was created by [`headers`]{@link headers}.
147
+ */
148
+ declare function isHeadersDirective(value: unknown): value is HeadersDirective;
149
+ /**
150
+ * Test whether a value is a head directive.
151
+ *
152
+ * @param value - Value to inspect.
153
+ * @returns Whether `value` was created by [`head`]{@link head}.
154
+ */
155
+ declare function isHeadDirective(value: unknown): value is HeadDirective;
156
+ /**
157
+ * Test whether a value is a stream directive.
158
+ *
159
+ * @param value - Value to inspect.
160
+ * @returns Whether `value` was created by [`stream`]{@link stream}.
161
+ */
162
+ declare function isStreamDirective(value: unknown): value is StreamDirective;
163
+ /**
164
+ * Test whether a value is a chunk directive.
165
+ *
166
+ * @param value - Value to inspect.
167
+ * @returns Whether `value` was created by [`chunk`]{@link chunk}.
168
+ */
169
+ declare function isChunkDirective(value: unknown): value is ChunkDirective;
170
+ /**
171
+ * Create a generator directive that sets the response status.
172
+ *
173
+ * @example
174
+ * ```ts
175
+ * yield status(HttpStatus.ACCEPTED)
176
+ * ```
177
+ *
178
+ * @param statusCode - HTTP status code to use.
179
+ * @returns Status directive.
180
+ */
181
+ declare function status(statusCode: number | HttpStatus): StatusDirective;
182
+ /**
183
+ * Create a generator directive that merges response headers.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * yield headers({'cache-control': 'no-store'})
188
+ * ```
189
+ *
190
+ * @param init - Headers to merge into the response.
191
+ * @returns Headers directive.
192
+ */
193
+ declare function headers(init: RouterHeadersInit): HeadersDirective;
194
+ /**
195
+ * Create a generator directive that sets response status and headers.
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * yield head(HttpStatus.OK, {'cache-control': 'no-store'})
200
+ * ```
201
+ *
202
+ * @param statusCode - HTTP status code to use.
203
+ * @param init - Headers to merge into the response.
204
+ * @returns Head directive.
205
+ */
206
+ declare function head(statusCode: number | HttpStatus, init?: RouterHeadersInit): HeadDirective;
207
+ /**
208
+ * Create a generator directive that selects a structured stream framer.
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * yield stream(sseFramer())
213
+ * ```
214
+ *
215
+ * @param framer - Stream framer to use for subsequent chunks.
216
+ * @param init - Additional stream headers.
217
+ * @returns Stream directive.
218
+ */
219
+ declare function stream<const T>(framer: StreamFramer<T>, init?: RouterHeadersInit): StreamDirective<T>;
220
+ /**
221
+ * Create a generator directive that emits one stream chunk.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * yield chunk({event: 'ready'})
226
+ * ```
227
+ *
228
+ * @param value - Chunk value to stream.
229
+ * @returns Chunk directive.
230
+ */
231
+ declare function chunk<const T>(value: T): ChunkDirective<T>;
232
+ //#endregion
233
+ //#region src/router/response/serializers.d.ts
234
+ type MaybePromise$1<T> = T | Promise<T>;
235
+ /**
236
+ * Serializer used by the router when a logical response has no explicit `Content-Type`.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * const json = jsonResponseBodySerializer()
241
+ * ```
242
+ */
243
+ interface ResponseBodySerializer<T = unknown> {
244
+ /**
245
+ * Media types this serializer can produce. Entries may include an Accept-style
246
+ * `q` parameter for server-side preference during content negotiation.
247
+ */
248
+ mediaTypes: readonly string[];
249
+ /**
250
+ * Return `true` when this serializer can encode the provided value.
251
+ *
252
+ * @param value - Logical response body to inspect.
253
+ * @returns Whether `value` can be serialized by this serializer.
254
+ */
255
+ canSerialize?(value: unknown): value is T;
256
+ /**
257
+ * Encode a logical response body into a native Fetch response body.
258
+ *
259
+ * @param value - Logical response body to encode.
260
+ * @returns Native response body data.
261
+ */
262
+ serialize(value: T): MaybePromise$1<RouterBodyInit | null>;
263
+ }
264
+ /**
265
+ * Create the default JSON response body serializer.
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * const router = new Router().setResponseBodySerializers([jsonResponseBodySerializer()])
270
+ * ```
271
+ *
272
+ * @returns Serializer for `application/json`.
273
+ */
274
+ declare function jsonResponseBodySerializer(): ResponseBodySerializer<unknown>;
275
+ /**
276
+ * Create the default response body serializer list.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * const serializers = defaultResponseBodySerializers()
281
+ * ```
282
+ *
283
+ * @returns Default response body serializers.
284
+ */
285
+ declare function defaultResponseBodySerializers(): ResponseBodySerializer[];
286
+ //#endregion
287
+ //#region src/router/response/stream.d.ts
288
+ declare function createStartStream<R = any>(fn: (controller: ReadableStreamDefaultController<R>) => void | Promise<void>): ReadableStream<any>;
289
+ interface StreamWriter<R = any> {
290
+ write(chunk: R): void;
291
+ }
292
+ declare function createAsyncStream<R = any>(fn: (controller: StreamWriter<R>) => void | Promise<void>): ReadableStream<any>;
293
+ //#endregion
294
+ //#region src/router/request.d.ts
295
+ /**
296
+ * Request body stream exposed by Routekit request bodies.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * const stream = request.body.stream()
301
+ * ```
302
+ */
303
+ type RequestBodyStream = ReadableStream<Uint8Array<ArrayBufferLike>> | null;
304
+ /**
305
+ * FormData type returned by the active Fetch runtime.
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * const form: RequestBodyFormData = await request.body.formData()
310
+ * ```
311
+ */
312
+ type RequestBodyFormData = Awaited<ReturnType<Response['formData']>>;
313
+ /**
314
+ * Error thrown when Routekit cannot read or parse a request body.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * throw new RequestBodyError('Unsupported body', HttpStatus.UNSUPPORTED_MEDIA_TYPE)
319
+ * ```
320
+ */
321
+ declare class RequestBodyError extends Error {
322
+ /**
323
+ * HTTP status code that should be returned for this request body failure.
324
+ */
325
+ readonly status: HttpStatus;
326
+ /**
327
+ * Create a request body error.
328
+ *
329
+ * @param message - Error message.
330
+ * @param status - HTTP status code for the failure.
331
+ */
332
+ constructor(message: string, status: HttpStatus);
333
+ }
334
+ /**
335
+ * Error thrown when no registered parser accepts the request `Content-Type`.
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * throw new UnsupportedRequestBodyMediaTypeError('image/png')
340
+ * ```
341
+ */
342
+ declare class UnsupportedRequestBodyMediaTypeError extends RequestBodyError {
343
+ /**
344
+ * Incoming `Content-Type` value that was rejected.
345
+ */
346
+ readonly contentType: string | null;
347
+ /**
348
+ * Create an unsupported media type error.
349
+ *
350
+ * @param contentType - Incoming content type, when present.
351
+ */
352
+ constructor(contentType: string | null);
353
+ }
354
+ /**
355
+ * Error thrown when a request body exceeds a configured byte limit.
356
+ *
357
+ * @example
358
+ * ```ts
359
+ * throw new RequestBodyTooLargeError(1024, 2048)
360
+ * ```
361
+ */
362
+ declare class RequestBodyTooLargeError extends RequestBodyError {
363
+ /**
364
+ * Maximum allowed body size in bytes.
365
+ */
366
+ readonly maxSize: number;
367
+ /**
368
+ * Number of bytes received before the limit failed.
369
+ */
370
+ readonly received: number;
371
+ /**
372
+ * Create a body-too-large error.
373
+ *
374
+ * @param maxSize - Maximum allowed body size in bytes.
375
+ * @param received - Number of bytes received.
376
+ */
377
+ constructor(maxSize: number, received: number);
378
+ }
379
+ /**
380
+ * Error thrown when `Content-Length` does not match the streamed body size.
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * throw new RequestBodyLengthMismatchError(4, 3)
385
+ * ```
386
+ */
387
+ declare class RequestBodyLengthMismatchError extends RequestBodyError {
388
+ /**
389
+ * Expected byte count from `Content-Length`.
390
+ */
391
+ readonly expected: number;
392
+ /**
393
+ * Actual byte count read from the stream.
394
+ */
395
+ readonly received: number;
396
+ /**
397
+ * Create a content-length mismatch error.
398
+ *
399
+ * @param expected - Expected byte count.
400
+ * @param received - Actual byte count.
401
+ */
402
+ constructor(expected: number, received: number);
403
+ }
404
+ /**
405
+ * Body reader context passed to request body parsers.
406
+ *
407
+ * @example
408
+ * ```ts
409
+ * const parser = {
410
+ * mediaTypes: ['text/plain'],
411
+ * parse: (ctx: RequestBodyParseContext) => ctx.text(),
412
+ * }
413
+ * ```
414
+ */
415
+ interface RequestBodyParseContext {
416
+ /**
417
+ * Parsed request `Content-Type`, when present and valid.
418
+ */
419
+ readonly contentType: ContentType | null;
420
+ /**
421
+ * Request headers.
422
+ */
423
+ readonly headers: Headers;
424
+ /**
425
+ * Return the current body stream.
426
+ *
427
+ * @returns Body stream, or `null` when the request has no body.
428
+ */
429
+ stream(): RequestBodyStream;
430
+ /**
431
+ * Read the body as UTF-8 text.
432
+ *
433
+ * @returns Body text.
434
+ */
435
+ text(): Promise<string>;
436
+ /**
437
+ * Read the body as raw bytes.
438
+ *
439
+ * @returns Body bytes.
440
+ */
441
+ arrayBuffer(): Promise<ArrayBuffer>;
442
+ /**
443
+ * Read the body as form data.
444
+ *
445
+ * @returns Parsed form data.
446
+ */
447
+ formData(): Promise<RequestBodyFormData>;
448
+ }
449
+ /**
450
+ * Parser used by [`RoutekitRequestBody.parse`]{@link RoutekitRequestBody#parse}.
451
+ *
452
+ * @example
453
+ * ```ts
454
+ * const jsonParser: RequestBodyParser = {
455
+ * mediaTypes: ['application/json'],
456
+ * parse: async ctx => JSON.parse(await ctx.text()),
457
+ * }
458
+ * ```
459
+ */
460
+ interface RequestBodyParser<T = unknown> {
461
+ /**
462
+ * Media ranges this parser can consume. Entries may include an Accept-style
463
+ * `q` parameter to prefer more specific parsers over broader media ranges.
464
+ */
465
+ readonly mediaTypes: readonly string[];
466
+ /**
467
+ * Return `true` when this parser should handle the content type.
468
+ *
469
+ * @param contentType - Parsed request content type.
470
+ * @returns Whether this parser can parse the request body.
471
+ */
472
+ canParse?(contentType: ContentType | null): boolean;
473
+ /**
474
+ * Parse the request body.
475
+ *
476
+ * @param ctx - Lazy body reader context.
477
+ * @returns Parsed request body.
478
+ */
479
+ parse(ctx: RequestBodyParseContext): MaybePromise<T>;
480
+ }
481
+ /**
482
+ * Lazy request body reader exposed to handlers and middleware.
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * const body = await request.body.parse()
487
+ * ```
488
+ */
489
+ interface RoutekitRequestBody {
490
+ /**
491
+ * Parsed request `Content-Type`, when present and valid.
492
+ */
493
+ readonly contentType: ContentType | null;
494
+ /**
495
+ * Return the current body stream.
496
+ *
497
+ * @returns Body stream, or `null` when the request has no body.
498
+ */
499
+ stream(): RequestBodyStream;
500
+ /**
501
+ * Return a body wrapper that reads from another stream.
502
+ *
503
+ * @param stream - Replacement body stream.
504
+ * @returns Request body wrapper using the replacement stream.
505
+ */
506
+ withStream(stream: RequestBodyStream): RoutekitRequestBody;
507
+ /**
508
+ * Parse the body with the first matching registered body parser.
509
+ *
510
+ * @returns Parsed request body.
511
+ * @typeParam T - Expected parsed body type.
512
+ */
513
+ parse<T = unknown>(): Promise<T>;
514
+ /**
515
+ * Read the body as JSON.
516
+ *
517
+ * @returns Parsed JSON body.
518
+ * @typeParam T - Expected JSON body type.
519
+ */
520
+ json<T = unknown>(): Promise<T>;
521
+ /**
522
+ * Read the body as UTF-8 text.
523
+ *
524
+ * @returns Body text.
525
+ */
526
+ text(): Promise<string>;
527
+ /**
528
+ * Read the body as raw bytes.
529
+ *
530
+ * @returns Body bytes.
531
+ */
532
+ arrayBuffer(): Promise<ArrayBuffer>;
533
+ /**
534
+ * Read the body as form data.
535
+ *
536
+ * @returns Parsed form data.
537
+ */
538
+ formData(): Promise<RequestBodyFormData>;
539
+ }
540
+ /**
541
+ * Routekit request wrapper exposed to handlers and middleware.
542
+ *
543
+ * @example
544
+ * ```ts
545
+ * const method = request.method
546
+ * const body = await request.body.parse()
547
+ * ```
548
+ */
549
+ interface RoutekitRequest {
550
+ /**
551
+ * Native Fetch request for low-level escape hatches.
552
+ */
553
+ readonly raw: Request;
554
+ /**
555
+ * Parsed request URL.
556
+ */
557
+ readonly url: URL;
558
+ /**
559
+ * Request method.
560
+ */
561
+ readonly method: string;
562
+ /**
563
+ * Request headers.
564
+ */
565
+ readonly headers: Headers;
566
+ /**
567
+ * Request abort signal.
568
+ */
569
+ readonly signal: AbortSignal;
570
+ /**
571
+ * Lazy request body reader.
572
+ */
573
+ readonly body: RoutekitRequestBody;
574
+ /**
575
+ * Return a request wrapper with another body reader.
576
+ *
577
+ * @param body - Replacement body reader.
578
+ * @returns Request wrapper using the replacement body reader.
579
+ */
580
+ withBody(body: RoutekitRequestBody): RoutekitRequest;
581
+ }
582
+ /**
583
+ * Create the default JSON request body parser.
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * const router = new Router().setRequestBodyParsers([jsonRequestBodyParser()])
588
+ * ```
589
+ *
590
+ * @returns Parser for `application/json` and `application/*+json` request bodies.
591
+ */
592
+ declare function jsonRequestBodyParser(): RequestBodyParser<unknown>;
593
+ /**
594
+ * Create the default text request body parser.
595
+ *
596
+ * @example
597
+ * ```ts
598
+ * const router = new Router().setRequestBodyParsers([textRequestBodyParser()])
599
+ * ```
600
+ *
601
+ * @returns Parser for `text/*` request bodies.
602
+ */
603
+ declare function textRequestBodyParser(): RequestBodyParser<string>;
604
+ /**
605
+ * Create the default URL-encoded form request body parser.
606
+ *
607
+ * @example
608
+ * ```ts
609
+ * const router = new Router().setRequestBodyParsers([urlEncodedRequestBodyParser()])
610
+ * ```
611
+ *
612
+ * @returns Parser for `application/x-www-form-urlencoded` request bodies.
613
+ */
614
+ declare function urlEncodedRequestBodyParser(): RequestBodyParser<Record<string, string | string[]>>;
615
+ /**
616
+ * Create the default multipart form request body parser.
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * const router = new Router().setRequestBodyParsers([formDataRequestBodyParser()])
621
+ * ```
622
+ *
623
+ * @returns Parser for `multipart/form-data` request bodies.
624
+ */
625
+ declare function formDataRequestBodyParser(): RequestBodyParser<RequestBodyFormData>;
626
+ /**
627
+ * Create the default Routekit request body parser list.
628
+ *
629
+ * @example
630
+ * ```ts
631
+ * const parsers = defaultRequestBodyParsers()
632
+ * ```
633
+ *
634
+ * @returns Default parser list.
635
+ */
636
+ declare function defaultRequestBodyParsers(): RequestBodyParser[];
637
+ /**
638
+ * Create a Routekit request wrapper for a native Fetch request.
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * const request = createRoutekitRequest(new Request('https://example.com'), new URL('https://example.com'), defaultRequestBodyParsers())
643
+ * ```
644
+ *
645
+ * @param raw - Native Fetch request.
646
+ * @param url - Parsed request URL.
647
+ * @param parsers - Request body parsers.
648
+ * @returns Routekit request wrapper.
649
+ */
650
+ declare function createRoutekitRequest(raw: Request, url: URL, parsers: readonly RequestBodyParser[]): RoutekitRequest;
651
+ /**
652
+ * Create a plain response for a request body error.
653
+ *
654
+ * @example
655
+ * ```ts
656
+ * const response = responseFromRequestBodyError(error)
657
+ * ```
658
+ *
659
+ * @param error - Request body error to convert.
660
+ * @returns HTTP response for the body error.
661
+ */
662
+ declare function responseFromRequestBodyError(error: RequestBodyError): Response;
663
+ //#endregion
664
+ //#region src/router/types.d.ts
665
+ type NonEmptyArray<T> = [T, ...T[]];
666
+ type OneOrMany<T> = T | NonEmptyArray<T>;
667
+ type MaybePromise<T> = T | Promise<T>;
668
+ type RoutePath = string | URLPattern;
669
+ /**
670
+ * JSON Schema value used for runtime request and response metadata.
671
+ */
672
+ type JsonSchema = boolean | Record<string, unknown>;
673
+ /**
674
+ * JSON Schema object used for path and query parameter declarations.
675
+ */
676
+ type JsonObjectSchema = Record<string, unknown>;
677
+ /**
678
+ * Schema metadata used to describe route request inputs and response bodies.
679
+ *
680
+ * @example
681
+ * ```ts
682
+ * const schema: RouteSchema = {
683
+ * request: {
684
+ * query: {
685
+ * type: 'object',
686
+ * properties: {
687
+ * page: {type: 'integer'},
688
+ * },
689
+ * },
690
+ * path: {
691
+ * type: 'object',
692
+ * properties: {
693
+ * id: {type: 'string'},
694
+ * },
695
+ * required: ['id'],
696
+ * },
697
+ * body: {
698
+ * type: 'object',
699
+ * properties: {
700
+ * name: {type: 'string'},
701
+ * },
702
+ * required: ['name'],
703
+ * },
704
+ * },
705
+ * response: {
706
+ * body: {
707
+ * 200: {
708
+ * type: 'object',
709
+ * properties: {
710
+ * ok: {type: 'boolean'},
711
+ * },
712
+ * required: ['ok'],
713
+ * },
714
+ * },
715
+ * },
716
+ * }
717
+ * ```
718
+ */
719
+ interface RouteSchema {
720
+ request?: {
721
+ query?: JsonObjectSchema;
722
+ path?: JsonObjectSchema;
723
+ body?: JsonSchema;
724
+ };
725
+ response?: {
726
+ body?: Partial<Record<number | 'default', JsonSchema>>;
727
+ };
728
+ }
729
+ /**
730
+ * Custom request matcher used when a route needs logic beyond pathname, method, or `accept`.
731
+ *
732
+ * @example
733
+ * ```ts
734
+ * const match: RouteMatch = request => request.headers.get('x-internal') === 'true'
735
+ * ```
736
+ *
737
+ * @param request - Incoming request to test.
738
+ * @returns `true` when the route should handle the request.
739
+ */
740
+ type RouteMatch = (request: RoutekitRequest) => boolean;
741
+ /**
742
+ * Route metadata used by tooling like OpenAPI generation.
743
+ */
744
+ interface RouteMeta {
745
+ /**
746
+ * OpenAPI operation metadata for this route.
747
+ */
748
+ openapi?: Record<string, unknown>;
749
+ [key: string]: unknown;
750
+ }
751
+ type AddedContextOf<Middleware> = Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<infer AddedCtx, any> ? AddedCtx : Exclude<Middleware, null | undefined | false> extends ContextMiddleware<infer AddedCtx, any> ? AddedCtx : Exclude<Middleware, null | undefined | false> extends RequestMiddleware<infer AddedCtx, any> ? AddedCtx : {};
752
+ type UnionToIntersection<Union> = (Union extends unknown ? (value: Union) => void : never) extends ((value: infer Intersection) => void) ? Intersection : never;
753
+ type AddedContextFromList<List extends readonly unknown[]> = List extends readonly [infer First, ...infer Rest] ? AddedContextOf<First> & AddedContextFromList<Rest> : number extends List['length'] ? UnionToIntersection<AddedContextOf<List[number]>> : {};
754
+ type ContextOf<Middleware> = Exclude<Middleware, null | undefined | false> extends DeclaredMiddleware<any, infer Ctx> ? Ctx : Exclude<Middleware, null | undefined | false> extends ContextMiddleware<any, infer Ctx> ? Ctx : Exclude<Middleware, null | undefined | false> extends RequestMiddleware<any, infer Ctx> ? Ctx : object;
755
+ type ContextFromList<List extends readonly unknown[]> = List extends readonly [infer First, ...infer Rest] ? ContextOf<First> & ContextFromList<Rest> : number extends List['length'] ? UnionToIntersection<ContextOf<List[number]>> : object;
756
+ /**
757
+ * Context added by a middleware value or middleware list.
758
+ *
759
+ * @example
760
+ * ```ts
761
+ * type AuthContext = AddedContextFromMiddlewareInput<typeof requireAuth>
762
+ * ```
763
+ *
764
+ * @typeParam Middleware - Middleware value or list whose added context should be inferred.
765
+ */
766
+ type AddedContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[] ? AddedContextFromList<Middleware> : AddedContextOf<Middleware>;
767
+ /**
768
+ * Base context expected by a middleware value or middleware list.
769
+ *
770
+ * @example
771
+ * ```ts
772
+ * type ServicesContext = ContextFromMiddlewareInput<typeof requireAuth>
773
+ * ```
774
+ *
775
+ * @typeParam Middleware - Middleware value or list whose base context should be inferred.
776
+ */
777
+ type ContextFromMiddlewareInput<Middleware> = Middleware extends readonly unknown[] ? ContextFromList<Middleware> : ContextOf<Middleware>;
778
+ /**
779
+ * Declarative route definition that the router can normalize and register.
780
+ *
781
+ * @example
782
+ * ```ts
783
+ * const route: Route = {
784
+ * name: 'user.detail',
785
+ * method: HttpMethod.GET,
786
+ * path: '/users/:id',
787
+ * handler: async ({request}) => new Response(await request.body.text()),
788
+ * }
789
+ * ```
790
+ */
791
+ interface Route<Ctx extends object = AnyContext, RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>> {
792
+ name?: OneOrMany<string>;
793
+ /**
794
+ * Path pattern matched by the default route matcher.
795
+ */
796
+ path: RoutePath;
797
+ handler: Handler<any, HandlerCtx>;
798
+ method?: OneOrMany<HttpMethod>;
799
+ /**
800
+ * Middleware applied only to this route after router and mount middleware.
801
+ *
802
+ * @example
803
+ * ```ts
804
+ * const route: Route = {
805
+ * path: '/me',
806
+ * middleware: auth(),
807
+ * handler: ({userId}) => new Response(userId),
808
+ * }
809
+ * ```
810
+ */
811
+ middleware?: RouteMiddleware;
812
+ /**
813
+ * Optional custom matcher. When omitted, the router matches using `path`, `method`, and `accept`.
814
+ */
815
+ match?: RouteMatch;
816
+ /**
817
+ * Arbitrary metadata attached to the route.
818
+ *
819
+ * @example
820
+ * ```ts
821
+ * const route: Route = {
822
+ * path: '/pets',
823
+ * method: HttpMethod.GET,
824
+ * meta: {
825
+ * openapi: {
826
+ * description: 'Returns all pets from the system that the user has access to',
827
+ * responses: {
828
+ * 200: {description: 'A list of pets'},
829
+ * },
830
+ * },
831
+ * },
832
+ * handler: () => new Response('ok'),
833
+ * }
834
+ * ```
835
+ */
836
+ meta?: RouteMeta;
837
+ /**
838
+ * Expected media type(s) for the incoming request body. When provided, the router compares each
839
+ * entry against the incoming `Content-Type` header.
840
+ *
841
+ * @example
842
+ * ```ts
843
+ * const route: Route = {
844
+ * path: '/upload',
845
+ * method: HttpMethod.POST,
846
+ * accept: ['multipart/form-data', {type: 'application/json'}],
847
+ * handler: async () => new Response('ok'),
848
+ * }
849
+ * ```
850
+ */
851
+ accept?: OneOrMany<string | MediaType>;
852
+ /**
853
+ * Runtime request and response schemas used by tooling such as OpenAPI generation and API client codegen.
854
+ */
855
+ schema?: RouteSchema;
856
+ }
857
+ /**
858
+ * Route definition fields accepted by method-specific router helpers.
859
+ *
860
+ * @example
861
+ * ```ts
862
+ * const options: RouteOptions = {
863
+ * name: 'user.detail',
864
+ * handler: async ({request}) => new Response(request.url),
865
+ * }
866
+ * router.get('/users/:id', options)
867
+ * ```
868
+ */
869
+ type RouteOptions<Ctx extends object = AnyContext, RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>> = Omit<Route<Ctx, RouteMiddleware, HandlerCtx>, 'method' | 'path'>;
870
+ /**
871
+ * Normalized route metadata used internally by the router.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * const route: NormalizedRoute = {
876
+ * name: ['user', 'detail'],
877
+ * method: HttpMethod.GET,
878
+ * path: new URLPattern({pathname: '/users/:id'}),
879
+ * handler: async ({request}) => new Response(await request.body.text()),
880
+ * }
881
+ * ```
882
+ */
883
+ interface NormalizedRoute<Ctx extends object = AnyContext> {
884
+ name: string[];
885
+ path: URLPattern;
886
+ handler: Handler<any, Ctx>;
887
+ method?: HttpMethod | HttpMethod[];
888
+ accept?: MediaType[];
889
+ match?: RouteMatch;
890
+ meta?: RouteMeta;
891
+ schema?: RouteSchema;
892
+ }
893
+ /**
894
+ * Parameterized HTTP `Content-Type` media type.
895
+ *
896
+ * @example
897
+ * ```ts
898
+ * const contentType: ContentType = {type: 'application/json', charset: 'utf-8'}
899
+ * ```
900
+ */
901
+ type ContentType = {
902
+ type: string;
903
+ charset?: string;
904
+ boundary?: string;
905
+ parameters?: Record<string, string>;
906
+ };
907
+ /**
908
+ * Backwards-compatible alias for a concrete media type.
909
+ *
910
+ * @example
911
+ * ```ts
912
+ * const media: MediaType = {type: 'application/json'}
913
+ * ```
914
+ */
915
+ type MediaType = ContentType;
916
+ /**
917
+ * Media range parsed from an HTTP `Accept` header.
918
+ *
919
+ * @example
920
+ * ```ts
921
+ * const accept: AcceptMediaRange = {type: 'application/json', q: 1}
922
+ * ```
923
+ */
924
+ type AcceptMediaRange = ContentType & {
925
+ q: number;
926
+ };
927
+ /**
928
+ * Generic context dictionary used when no custom context type is provided.
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * const ctx: AnyContext = {featureFlag: true}
933
+ * ```
934
+ */
935
+ type AnyContext = Record<string, any>;
936
+ /**
937
+ * Extension hook that intentionally configures a router instance.
938
+ *
939
+ * @example
940
+ * ```ts
941
+ * const extension: RouterExtension = router => {
942
+ * router.onNotFound(() => new Response('missing', {status: 404}))
943
+ * }
944
+ *
945
+ * new Router().install(extension)
946
+ * ```
947
+ *
948
+ * @typeParam Ctx - Context carried by the router being configured.
949
+ */
950
+ type RouterExtension<Ctx extends object = AnyContext> = (router: Router<Ctx>) => void;
951
+ /**
952
+ * Request context made available to middleware.
953
+ * Extended data can be attached by middleware via the generic parameter.
954
+ *
955
+ * @example
956
+ * ```ts
957
+ * const middleware: ContextMiddleware<{userId: string}> = ctx => {
958
+ * ctx.userId = 'user-123'
959
+ * }
960
+ * ```
961
+ */
962
+ type RequestContext<Ctx extends object = AnyContext> = {
963
+ /**
964
+ * Routekit request wrapper for the current request.
965
+ */
966
+ request: RoutekitRequest;
967
+ /**
968
+ * Contextual logger selected for the current request.
969
+ */
970
+ logger: Logger;
971
+ } & Ctx;
972
+ /**
973
+ * Context object provided to route handlers.
974
+ * Includes request metadata as well as any context extensions added by middleware.
975
+ *
976
+ * @example
977
+ * ```ts
978
+ * const handler: HandlerContext = {
979
+ * request,
980
+ * url: new URL('https://example.com/users/123'),
981
+ * path: {id: '123'},
982
+ * }
983
+ * ```
984
+ */
985
+ type HandlerContext<Ctx extends object = AnyContext> = RequestContext<Ctx> & {
986
+ /**
987
+ * Parsed request URL for convenience.
988
+ */
989
+ url: URL;
990
+ /**
991
+ * Route path parameters extracted from the matched URL pattern.
992
+ */
993
+ path: unknown;
994
+ };
995
+ /**
996
+ * Values yielded by generator-style handlers.
997
+ *
998
+ * @example
999
+ * ```ts
1000
+ * async function* handler() {
1001
+ * yield head(HttpStatus.OK, {'cache-control': 'no-store'})
1002
+ * return {ok: true}
1003
+ * }
1004
+ * ```
1005
+ */
1006
+ type HandlerYield = RoutekitYield;
1007
+ /**
1008
+ * Native body value that can be passed to the Fetch [`Response`]{@link Response} constructor.
1009
+ *
1010
+ * @example
1011
+ * ```ts
1012
+ * const body: HandlerBody = 'ok'
1013
+ * ```
1014
+ */
1015
+ type HandlerBody = RouterBodyInit | null | undefined;
1016
+ /**
1017
+ * Final value a handler or generator may return.
1018
+ */
1019
+ type HandlerFinalResult<TOkRes = unknown> = Response | RoutekitResponse<TOkRes> | RoutekitBody<TOkRes> | TOkRes | HandlerBody;
1020
+ /**
1021
+ * Allowed handler return values.
1022
+ *
1023
+ * @example
1024
+ * ```ts
1025
+ * const handler: Handler = async ({request}) => new Response(await request.body.text())
1026
+ * ```
1027
+ */
1028
+ type HandlerResult<TOkRes = unknown> = HandlerFinalResult<TOkRes> | Promise<HandlerFinalResult<TOkRes> | AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>> | AsyncGenerator<HandlerYield, HandlerFinalResult<TOkRes>>;
1029
+ /**
1030
+ * Route handler signature that preserves generic type parameters for API generation.
1031
+ *
1032
+ * @example
1033
+ * ```ts
1034
+ * const handler: Handler = ({path}) => {
1035
+ * return JSON.stringify(path)
1036
+ * }
1037
+ * ```
1038
+ *
1039
+ * The handler is invoked with `this` bound to the active [`Router`]{@link Router}.
1040
+ *
1041
+ * @param ctx - Handler context containing the incoming [`RoutekitRequest`]{@link RoutekitRequest}, parsed [`URL`]{@link URL}, path parameters, and middleware extensions.
1042
+ * @returns A response, a serializable value handled by middleware, or a streaming generator that yields response metadata.
1043
+ */
1044
+ type Handler<TOkRes = unknown, Ctx extends object = AnyContext> = (this: Router<any>, ctx: HandlerContext<Ctx>) => HandlerResult<TOkRes>;
1045
+ /**
1046
+ * Middleware that extends request context and then continues routing.
1047
+ *
1048
+ * @example
1049
+ * ```ts
1050
+ * const addRequestId = (): ContextMiddleware<{requestId: number}> => ctx => {
1051
+ * ctx.requestId = 123
1052
+ * }
1053
+ * ```
1054
+ *
1055
+ * @param ctx - Request context for the current request, including any added fields.
1056
+ * @returns Nothing, or a promise resolved after context initialization.
1057
+ */
1058
+ type ContextMiddleware<AddedCtx extends object = AnyContext, Ctx extends object = AnyContext> = (ctx: RequestContext<Ctx & AddedCtx>) => void | Promise<void>;
1059
+ /**
1060
+ * Middleware that surrounds final response production for every incoming request.
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * const timing: RequestMiddleware = async (ctx, next) => {
1065
+ * const started = performance.now()
1066
+ * const response = await next()
1067
+ * ctx.logger.info('completed', {duration: performance.now() - started})
1068
+ * return response
1069
+ * }
1070
+ * ```
1071
+ *
1072
+ * @param ctx - Request context shared with downstream middleware and handlers.
1073
+ * @param next - Continue processing and obtain the final response.
1074
+ * @returns The final response, optionally decorated by the middleware.
1075
+ * @typeParam AddedCtx - Context fields made available to downstream processing.
1076
+ * @typeParam Ctx - Context required before this middleware executes.
1077
+ */
1078
+ type RequestMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext> = (ctx: HandlerContext<Ctx & AddedCtx>, next: () => Promise<Response>) => Response | Promise<Response>;
1079
+ /**
1080
+ * Middleware entry accepted inside typed middleware lists.
1081
+ *
1082
+ * @example
1083
+ * ```ts
1084
+ * const middleware = [auth(), false] satisfies MiddlewareEntry[]
1085
+ * ```
1086
+ *
1087
+ * @typeParam Ctx - Base context available before this middleware runs.
1088
+ */
1089
+ type MiddlewareEntry<Ctx extends object = AnyContext> = ContextMiddleware<any, Ctx> | DeclaredMiddleware<any, Ctx> | null | undefined | false;
1090
+ /**
1091
+ * Middleware that performs context-only request initialization.
1092
+ *
1093
+ * @example
1094
+ * ```ts
1095
+ * const middleware: Middleware = ctx => {
1096
+ * ctx.request.headers.get('accept')
1097
+ * }
1098
+ * ```
1099
+ *
1100
+ * @param ctx - Request context for the current request.
1101
+ * @returns Nothing, or a promise resolved after context initialization.
1102
+ */
1103
+ type Middleware<Ctx extends object = AnyContext> = ContextMiddleware<{}, Ctx>;
1104
+ /**
1105
+ * Middleware list container for registering multiple middleware entries.
1106
+ *
1107
+ * @example
1108
+ * ```ts
1109
+ * const middleware: MiddlewareList = [auth(), logging()]
1110
+ * ```
1111
+ *
1112
+ * @param list - Collection of middleware entries, optionally including falsy values.
1113
+ * @returns A list of middleware compatible with `Router.use`.
1114
+ */
1115
+ type MiddlewareList<Ctx extends object = AnyContext> = ReadonlyArray<MiddlewareEntry<Ctx>>;
1116
+ /**
1117
+ * Middleware value accepted by router middleware registration APIs.
1118
+ *
1119
+ * @example
1120
+ * ```ts
1121
+ * const input: MiddlewareInput = [auth(), logging()]
1122
+ * ```
1123
+ *
1124
+ * @typeParam Ctx - Base context available before this middleware runs.
1125
+ */
1126
+ type MiddlewareInput<Ctx extends object = AnyContext> = OneOrMany<MiddlewareEntry<Ctx>> | MiddlewareList<Ctx> | null | undefined | false;
1127
+ /**
1128
+ * Request-boundary middleware entry accepted by [`Router.useRequest`]{@link Router#useRequest}.
1129
+ *
1130
+ * @typeParam Ctx - Base context available before this middleware runs.
1131
+ */
1132
+ type RequestMiddlewareEntry<Ctx extends object = AnyContext> = RequestMiddleware<any, Ctx> | null | undefined | false;
1133
+ /**
1134
+ * Request-boundary middleware input accepted by [`Router.useRequest`]{@link Router#useRequest}.
1135
+ *
1136
+ * @typeParam Ctx - Base context available before this middleware runs.
1137
+ */
1138
+ type RequestMiddlewareInput<Ctx extends object = AnyContext> = OneOrMany<RequestMiddlewareEntry<Ctx>> | ReadonlyArray<RequestMiddlewareEntry<Ctx>> | null | undefined | false;
1139
+ /**
1140
+ * Request body parser value accepted by router request body parser APIs.
1141
+ *
1142
+ * @example
1143
+ * ```ts
1144
+ * const input: RequestBodyParserInput = [jsonRequestBodyParser()]
1145
+ * ```
1146
+ */
1147
+ type RequestBodyParserInput = RequestBodyParser | ReadonlyArray<RequestBodyParser | null | undefined | false> | null | undefined | false;
1148
+ /**
1149
+ * Response body serializer value accepted by router response body serializer APIs.
1150
+ *
1151
+ * @example
1152
+ * ```ts
1153
+ * const input: ResponseBodySerializerInput = [jsonResponseBodySerializer()]
1154
+ * ```
1155
+ */
1156
+ type ResponseBodySerializerInput = ResponseBodySerializer | ReadonlyArray<ResponseBodySerializer | null | undefined | false> | null | undefined | false;
1157
+ /**
1158
+ * Options for mounting a router or configuring a scoped inline router.
1159
+ *
1160
+ * @example
1161
+ * ```ts
1162
+ * const options: RouterMountOptions = {prefix: '/admin', middleware: auth()}
1163
+ * ```
1164
+ */
1165
+ interface RouterMountOptions<Ctx extends object = AnyContext> {
1166
+ /**
1167
+ * Optional pathname prefix for the mounted routes.
1168
+ */
1169
+ prefix?: string;
1170
+ /**
1171
+ * Middleware applied to the mounted router scope.
1172
+ */
1173
+ middleware?: MiddlewareInput<Ctx>;
1174
+ }
1175
+ //#endregion
1176
+ //#region src/router/middleware/define.d.ts
1177
+ declare const declaredMiddlewareBrand: unique symbol;
1178
+ declare const middlewareActionBrand: unique symbol;
1179
+ /**
1180
+ * A response declaration owned by middleware.
1181
+ *
1182
+ * @example
1183
+ * ```ts
1184
+ * const forbidden = {
1185
+ * schema: { type: 'string' },
1186
+ * parse: value => String(value),
1187
+ * }
1188
+ * ```
1189
+ *
1190
+ * @typeParam Body - Parsed response body produced by the declaration.
1191
+ */
1192
+ interface MiddlewareResponseDeclaration<Body = unknown> {
1193
+ /**
1194
+ * JSON Schema emitted for metadata consumers such as OpenAPI and client generation.
1195
+ */
1196
+ readonly schema: JsonSchema;
1197
+ /**
1198
+ * Validate and optionally parse a locally originated response body.
1199
+ *
1200
+ * @param value - Body supplied through `respond(...)`.
1201
+ * @returns The validated response body.
1202
+ */
1203
+ parse(value: unknown): Body;
1204
+ }
1205
+ /**
1206
+ * Status-keyed response declarations owned by middleware.
1207
+ */
1208
+ type MiddlewareResponseDeclarations = Partial<Record<number | 'default', MiddlewareResponseDeclaration<any>>>;
1209
+ type DeclaredBody<Declaration> = Declaration extends MiddlewareResponseDeclaration<infer Body> ? Body : never;
1210
+ type DeclaredResponse<Declarations extends MiddlewareResponseDeclarations> = { [Status in keyof Declarations]-?: NonNullable<Declarations[Status]> extends MiddlewareResponseDeclaration<any> ? RoutekitResponse<DeclaredBody<NonNullable<Declarations[Status]>>, Status extends number ? Status : number> : never }[keyof Declarations];
1211
+ /** @internal */
1212
+ interface MiddlewareAction {
1213
+ readonly [middlewareActionBrand]: true;
1214
+ readonly result: HandlerResult;
1215
+ }
1216
+ /**
1217
+ * Controls passed to a declared middleware implementation.
1218
+ *
1219
+ * @typeParam Declarations - Locally originated response declarations.
1220
+ */
1221
+ interface MiddlewareControls<Declarations extends MiddlewareResponseDeclarations> {
1222
+ /**
1223
+ * Invoke downstream middleware and the route handler.
1224
+ *
1225
+ * @returns The downstream result before it is finalized into a Fetch response.
1226
+ */
1227
+ next(): Promise<HandlerResult>;
1228
+ /**
1229
+ * Forward an unchanged or decorated downstream result.
1230
+ *
1231
+ * @param result - Result obtained from [`MiddlewareControls.next`]{@link MiddlewareControls#next}.
1232
+ * @returns A middleware action accepted by the declaring factory.
1233
+ */
1234
+ forward(result: HandlerResult): MiddlewareAction;
1235
+ /**
1236
+ * Return a response originated by this middleware.
1237
+ *
1238
+ * @param result - Logical response matching a declared body and exact status.
1239
+ * @returns A validated terminal middleware action.
1240
+ */
1241
+ respond(result: DeclaredResponse<Declarations>): MiddlewareAction;
1242
+ }
1243
+ /**
1244
+ * Callable middleware carrying schema declarations for router metadata.
1245
+ *
1246
+ * @typeParam AddedCtx - Context values made available to downstream handlers.
1247
+ * @typeParam Ctx - Context required before this middleware executes.
1248
+ */
1249
+ interface DeclaredMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext> {
1250
+ readonly [declaredMiddlewareBrand]: true;
1251
+ readonly schema?: RouteSchema;
1252
+ readonly schemaAppliesTo?: (route: {
1253
+ readonly method?: string | readonly string[];
1254
+ }) => boolean;
1255
+ (ctx: HandlerContext<Ctx & AddedCtx>, next: () => Promise<HandlerResult>): Promise<HandlerResult>;
1256
+ }
1257
+ /**
1258
+ * Options for [`defineMiddleware`]{@link defineMiddleware}.
1259
+ *
1260
+ * @typeParam AddedCtx - Context values made available to downstream handlers.
1261
+ * @typeParam Ctx - Context required before this middleware executes.
1262
+ * @typeParam Declarations - Status-keyed locally originated responses.
1263
+ */
1264
+ interface DefineMiddlewareOptions<AddedCtx extends object, Ctx extends object, Declarations extends MiddlewareResponseDeclarations> {
1265
+ /**
1266
+ * Additional metadata contributed by the middleware, such as request schemas or
1267
+ * downstream response boundary schemas.
1268
+ */
1269
+ schema?: RouteSchema;
1270
+ /**
1271
+ * Limit this middleware's schema contribution to matching flattened routes.
1272
+ *
1273
+ * @param route - Route metadata being flattened by the router.
1274
+ * @returns Whether this middleware's schema applies to that route.
1275
+ */
1276
+ schemaAppliesTo?: (route: {
1277
+ readonly method?: string | readonly string[];
1278
+ }) => boolean;
1279
+ /**
1280
+ * Responses that this middleware may originate through `respond(...)`.
1281
+ */
1282
+ responses?: Declarations;
1283
+ /**
1284
+ * Execute middleware behavior.
1285
+ *
1286
+ * @param ctx - Request and route context available at execution time.
1287
+ * @param controls - Continuation, forwarding, and terminal response operations.
1288
+ * @returns A terminal/forward action, or void to continue automatically.
1289
+ */
1290
+ run(ctx: HandlerContext<Ctx & AddedCtx>, controls: MiddlewareControls<Declarations>): MiddlewareAction | void | Promise<MiddlewareAction | void>;
1291
+ }
1292
+ /**
1293
+ * Create middleware that declares and validates every response it originates.
1294
+ *
1295
+ * @example
1296
+ * ```ts
1297
+ * const auth = defineMiddleware({
1298
+ * responses: {
1299
+ * 401: {
1300
+ * schema: { type: 'string' },
1301
+ * parse: value => String(value),
1302
+ * },
1303
+ * },
1304
+ * run: async (_ctx, { respond }) => respond(response('Sign in', { status: 401 })),
1305
+ * })
1306
+ * ```
1307
+ *
1308
+ * @param options - Schema declarations and middleware implementation.
1309
+ * @returns Executable middleware carrying its metadata contribution.
1310
+ * @typeParam AddedCtx - Context values made available to downstream handlers.
1311
+ * @typeParam Ctx - Context required before this middleware executes.
1312
+ * @typeParam Declarations - Status-keyed locally originated responses.
1313
+ */
1314
+ declare function defineMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext, const Declarations extends MiddlewareResponseDeclarations = {}>(options: DefineMiddlewareOptions<AddedCtx, Ctx, Declarations>): DeclaredMiddleware<AddedCtx, Ctx>;
1315
+ //#endregion
1316
+ //#region src/router/router.d.ts
1317
+ /**
1318
+ * Router that matches requests against registered routes and executes middleware.
1319
+ *
1320
+ * @example
1321
+ * ```ts
1322
+ * const router = new Router()
1323
+ * router.add({method: HttpMethod.GET, path: '/', handler: async ({request}) => new Response(request.url)})
1324
+ * ```
1325
+ */
1326
+ declare class Router<Ctx extends object = AnyContext> implements SimpleServerInterface {
1327
+ private _entries;
1328
+ private _middleware;
1329
+ private _requestMiddleware;
1330
+ private _responseBodySerializers;
1331
+ private _responseBodySerializersMode;
1332
+ private _requestBodyParsers;
1333
+ private _requestBodyParsersMode;
1334
+ private _logger?;
1335
+ private readonly _defaultLogger;
1336
+ private _onNotFoundHandler?;
1337
+ private _onMethodNotAllowedHandler?;
1338
+ private _onUnsupportedMediaTypeHandler?;
1339
+ private _onInternalErrorHandler?;
1340
+ /**
1341
+ * Create a new router instance.
1342
+ */
1343
+ constructor();
1344
+ /**
1345
+ * Install an extension that configures this router instance.
1346
+ *
1347
+ * @example
1348
+ * ```ts
1349
+ * router.install(problemRootErrors())
1350
+ * ```
1351
+ *
1352
+ * @param extension - Extension function that mutates or configures this router.
1353
+ * @returns The router instance for chaining.
1354
+ */
1355
+ install(extension: RouterExtension<Ctx>): this;
1356
+ /**
1357
+ * Register a handler for requests that do not match any route.
1358
+ *
1359
+ * @example
1360
+ * ```ts
1361
+ * router.onNotFound(() => new Response('missing', {status: 404}))
1362
+ * ```
1363
+ *
1364
+ * @param handler - Handler invoked when no route matches.
1365
+ * @returns The router instance for chaining.
1366
+ */
1367
+ onNotFound(handler: Handler<any, Ctx>): this;
1368
+ /**
1369
+ * Register a handler for requests that match a path but use an unsupported method.
1370
+ *
1371
+ * @example
1372
+ * ```ts
1373
+ * router.onMethodNotAllowed(() => new Response('nope', {status: 405}))
1374
+ * ```
1375
+ *
1376
+ * @param handler - Handler invoked when a route exists but the method does not match.
1377
+ * @returns The router instance for chaining.
1378
+ */
1379
+ onMethodNotAllowed(handler: Handler<any, Ctx>): this;
1380
+ /**
1381
+ * Register a handler for requests with unsupported request body media types.
1382
+ *
1383
+ * @example
1384
+ * ```ts
1385
+ * router.onUnsupportedMediaType(() => new Response('unsupported', {status: 415}))
1386
+ * ```
1387
+ *
1388
+ * @param handler - Handler invoked when the incoming `Content-Type` is not accepted.
1389
+ * @returns The router instance for chaining.
1390
+ */
1391
+ onUnsupportedMediaType(handler: Handler<any, Ctx>): this;
1392
+ /**
1393
+ * Register a handler for unhandled errors thrown by route handlers.
1394
+ *
1395
+ * @example
1396
+ * ```ts
1397
+ * router.onInternalError(() => new Response('oops', {status: 500}))
1398
+ * ```
1399
+ *
1400
+ * @param handler - Handler invoked when a route handler throws.
1401
+ * @returns The router instance for chaining.
1402
+ */
1403
+ onInternalError(handler: Handler<any, Ctx>): this;
1404
+ /**
1405
+ * Add a request body parser to the inherited parser list.
1406
+ *
1407
+ * @example
1408
+ * ```ts
1409
+ * router.addRequestBodyParser(jsonRequestBodyParser())
1410
+ * ```
1411
+ *
1412
+ * @param parser - Request body parser to append.
1413
+ * @returns The router instance for chaining.
1414
+ */
1415
+ addRequestBodyParser(parser: RequestBodyParser): this;
1416
+ /**
1417
+ * Add request body parsers to the inherited parser list.
1418
+ *
1419
+ * @example
1420
+ * ```ts
1421
+ * router.addRequestBodyParsers([jsonRequestBodyParser(), textRequestBodyParser()])
1422
+ * ```
1423
+ *
1424
+ * @param parsers - Request body parsers to append.
1425
+ * @returns The router instance for chaining.
1426
+ */
1427
+ addRequestBodyParsers(parsers: RequestBodyParserInput): this;
1428
+ /**
1429
+ * Replace the inherited request body parser list for this router subtree.
1430
+ *
1431
+ * @example
1432
+ * ```ts
1433
+ * router.setRequestBodyParsers([jsonRequestBodyParser()])
1434
+ * ```
1435
+ *
1436
+ * @param parsers - Exact request body parsers to use for this router subtree.
1437
+ * @returns The router instance for chaining.
1438
+ */
1439
+ setRequestBodyParsers(parsers: RequestBodyParserInput): this;
1440
+ /**
1441
+ * Add a response body serializer to the inherited serializer list.
1442
+ *
1443
+ * @example
1444
+ * ```ts
1445
+ * router.addResponseBodySerializer(jsonResponseBodySerializer())
1446
+ * ```
1447
+ *
1448
+ * @param serializer - Response body serializer to append.
1449
+ * @returns The router instance for chaining.
1450
+ */
1451
+ addResponseBodySerializer(serializer: ResponseBodySerializer): this;
1452
+ /**
1453
+ * Add response body serializers to the inherited serializer list.
1454
+ *
1455
+ * @example
1456
+ * ```ts
1457
+ * router.addResponseBodySerializers([jsonResponseBodySerializer(), yamlSerializer])
1458
+ * ```
1459
+ *
1460
+ * @param serializers - Response body serializers to append.
1461
+ * @returns The router instance for chaining.
1462
+ */
1463
+ addResponseBodySerializers(serializers: ResponseBodySerializerInput): this;
1464
+ /**
1465
+ * Replace the inherited response body serializer list for this router subtree.
1466
+ *
1467
+ * @example
1468
+ * ```ts
1469
+ * router.setResponseBodySerializers([jsonResponseBodySerializer()])
1470
+ * ```
1471
+ *
1472
+ * @param serializers - Exact response body serializers to use for this router subtree.
1473
+ * @returns The router instance for chaining.
1474
+ */
1475
+ setResponseBodySerializers(serializers: ResponseBodySerializerInput): this;
1476
+ /**
1477
+ * Set the logger for this router subtree.
1478
+ *
1479
+ * @example
1480
+ * ```ts
1481
+ * router.setLogger(logger)
1482
+ * ```
1483
+ *
1484
+ * @param logger - Logger exposed through request contexts and used for internal server errors.
1485
+ * @returns The router instance for chaining.
1486
+ */
1487
+ setLogger(logger: Logger): this;
1488
+ /**
1489
+ * Register middleware on the current router.
1490
+ *
1491
+ * @example
1492
+ * ```ts
1493
+ * router.use(ctx => {
1494
+ * ctx.traceId = crypto.randomUUID()
1495
+ * })
1496
+ * ```
1497
+ *
1498
+ * @param middleware - Middleware or a list of middleware to register.
1499
+ * @returns The router instance for chaining.
1500
+ */
1501
+ use<AddedCtx extends object>(middleware: ContextMiddleware<AddedCtx, Ctx> | null | undefined | false): Router<Ctx & AddedCtx>;
1502
+ use<AddedCtx extends object>(middleware: DeclaredMiddleware<AddedCtx, Ctx>): Router<Ctx & AddedCtx>;
1503
+ /**
1504
+ * Register middleware on the current router.
1505
+ *
1506
+ * @example
1507
+ * ```ts
1508
+ * router.use([auth(), logging()])
1509
+ * ```
1510
+ *
1511
+ * @param middleware - Middleware list to register.
1512
+ * @returns The router instance for chaining.
1513
+ */
1514
+ use<List extends readonly MiddlewareEntry<Ctx>[]>(middleware: List): Router<Ctx & AddedContextFromMiddlewareInput<List>>;
1515
+ /**
1516
+ * Register middleware that surrounds final response production for every request.
1517
+ *
1518
+ * @example
1519
+ * ```ts
1520
+ * router.useRequest(requestIdCtx())
1521
+ * router.useRequest(requestLogger())
1522
+ * ```
1523
+ *
1524
+ * @param middleware - Request-boundary middleware or a middleware list.
1525
+ * @returns The router instance with added request context fields.
1526
+ */
1527
+ useRequest<AddedCtx extends object>(middleware: RequestMiddleware<AddedCtx, Ctx> | null | undefined | false): Router<Ctx & AddedCtx>;
1528
+ useRequest<List extends readonly RequestMiddlewareEntry<Ctx>[]>(middleware: List): Router<Ctx & AddedContextFromMiddlewareInput<List>>;
1529
+ /**
1530
+ * Mount a router at the current path.
1531
+ *
1532
+ * @example
1533
+ * ```ts
1534
+ * router.mount(apiRouter)
1535
+ * ```
1536
+ *
1537
+ * @param router - Router to mount.
1538
+ * @returns The router instance for chaining.
1539
+ */
1540
+ mount(router: Router<any>): this;
1541
+ /**
1542
+ * Mount an inline router at the current path.
1543
+ *
1544
+ * @example
1545
+ * ```ts
1546
+ * router.mount(admin => {
1547
+ * admin.get('/admin/users', handler)
1548
+ * })
1549
+ * ```
1550
+ *
1551
+ * @param configure - Callback used to register routes on the mounted router.
1552
+ * @returns The router instance for chaining.
1553
+ */
1554
+ mount(configure: (router: Router<Ctx>) => void): this;
1555
+ /**
1556
+ * Mount a router under a pathname prefix.
1557
+ *
1558
+ * @example
1559
+ * ```ts
1560
+ * router.mount('/api', apiRouter)
1561
+ * ```
1562
+ *
1563
+ * @param prefix - Pathname prefix to strip before routing.
1564
+ * @param router - Router to mount.
1565
+ * @returns The router instance for chaining.
1566
+ */
1567
+ mount(prefix: string, router: Router<any>): this;
1568
+ /**
1569
+ * Mount an inline router under a pathname prefix.
1570
+ *
1571
+ * @example
1572
+ * ```ts
1573
+ * router.mount('/api', api => {
1574
+ * api.get('/items', handler)
1575
+ * })
1576
+ * ```
1577
+ *
1578
+ * @param prefix - Pathname prefix to strip before routing.
1579
+ * @param configure - Callback used to register routes on the mounted router.
1580
+ * @returns The router instance for chaining.
1581
+ */
1582
+ mount(prefix: string, configure: (router: Router<Ctx>) => void): this;
1583
+ /**
1584
+ * Mount an inline router with additional middleware.
1585
+ *
1586
+ * @example
1587
+ * ```ts
1588
+ * router.mount({prefix: '/admin', middleware: auth()}, admin => {
1589
+ * admin.get('/users', ({userId}) => ok({userId}))
1590
+ * })
1591
+ * ```
1592
+ *
1593
+ * @param options - Mount options for the inline router.
1594
+ * @param configure - Callback used to register routes on the mounted router.
1595
+ * @returns The router instance for chaining.
1596
+ */
1597
+ mount<AddedCtx extends object>(options: RouterMountOptions<Ctx> & {
1598
+ middleware: ContextMiddleware<AddedCtx, Ctx> | DeclaredMiddleware<AddedCtx, Ctx> | null | undefined | false;
1599
+ }, configure: (router: Router<Ctx & AddedCtx>) => void): this;
1600
+ /**
1601
+ * Mount an inline router with a middleware list.
1602
+ *
1603
+ * @example
1604
+ * ```ts
1605
+ * router.mount({middleware: [auth(), logging()] as const}, scoped => {
1606
+ * scoped.get('/me', handler)
1607
+ * })
1608
+ * ```
1609
+ *
1610
+ * @param options - Mount options for the inline router.
1611
+ * @param configure - Callback used to register routes on the mounted router.
1612
+ * @returns The router instance for chaining.
1613
+ */
1614
+ mount<List extends readonly MiddlewareEntry<Ctx>[]>(options: RouterMountOptions<Ctx> & {
1615
+ middleware: List;
1616
+ }, configure: (router: Router<Ctx & AddedContextFromMiddlewareInput<List>>) => void): this;
1617
+ /**
1618
+ * Mount an inline router with options and no additional typed middleware.
1619
+ *
1620
+ * @example
1621
+ * ```ts
1622
+ * router.mount({prefix: '/reports'}, reports => {
1623
+ * reports.get('/export', handler)
1624
+ * })
1625
+ * ```
1626
+ *
1627
+ * @param options - Mount options for the inline router.
1628
+ * @param configure - Callback used to register routes on the mounted router.
1629
+ * @returns The router instance for chaining.
1630
+ */
1631
+ mount(options: RouterMountOptions<Ctx>, configure: (router: Router<Ctx>) => void): this;
1632
+ /**
1633
+ * Mount an existing router with options.
1634
+ *
1635
+ * @example
1636
+ * ```ts
1637
+ * router.mount({prefix: '/api', middleware: logging()}, apiRouter)
1638
+ * ```
1639
+ *
1640
+ * @param options - Mount options for the existing router.
1641
+ * @param router - Router to mount.
1642
+ * @returns The router instance for chaining.
1643
+ */
1644
+ mount(options: RouterMountOptions<Ctx>, router: Router<any>): this;
1645
+ /**
1646
+ * Add a route definition to this router.
1647
+ *
1648
+ * @example
1649
+ * ```ts
1650
+ * router.add({method: HttpMethod.POST, path: '/items', handler: ({request}) => new Response(request.url)})
1651
+ * ```
1652
+ *
1653
+ * @param route - Route definition to normalize and register.
1654
+ * @returns The router instance for chaining.
1655
+ */
1656
+ add<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(route: Route<Ctx, RouteMiddleware, HandlerCtx>): this;
1657
+ private _addMethod;
1658
+ /**
1659
+ * Add a GET route handler to this router.
1660
+ *
1661
+ * @param path - URL path pattern to match.
1662
+ * @param handler - Handler invoked when the route matches.
1663
+ * @returns The router instance for chaining.
1664
+ */
1665
+ get(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1666
+ /**
1667
+ * Add a GET route definition to this router.
1668
+ *
1669
+ * @param path - URL path pattern to match.
1670
+ * @param options - Route options registered with the GET method.
1671
+ * @returns The router instance for chaining.
1672
+ */
1673
+ get<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1674
+ /**
1675
+ * Add a HEAD route handler to this router.
1676
+ *
1677
+ * @param path - URL path pattern to match.
1678
+ * @param handler - Handler invoked when the route matches.
1679
+ * @returns The router instance for chaining.
1680
+ */
1681
+ head(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1682
+ /**
1683
+ * Add a HEAD route definition to this router.
1684
+ *
1685
+ * @param path - URL path pattern to match.
1686
+ * @param options - Route options registered with the HEAD method.
1687
+ * @returns The router instance for chaining.
1688
+ */
1689
+ head<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1690
+ /**
1691
+ * Add a POST route handler to this router.
1692
+ *
1693
+ * @param path - URL path pattern to match.
1694
+ * @param handler - Handler invoked when the route matches.
1695
+ * @returns The router instance for chaining.
1696
+ */
1697
+ post(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1698
+ /**
1699
+ * Add a POST route definition to this router.
1700
+ *
1701
+ * @param path - URL path pattern to match.
1702
+ * @param options - Route options registered with the POST method.
1703
+ * @returns The router instance for chaining.
1704
+ */
1705
+ post<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1706
+ /**
1707
+ * Add a PUT route handler to this router.
1708
+ *
1709
+ * @param path - URL path pattern to match.
1710
+ * @param handler - Handler invoked when the route matches.
1711
+ * @returns The router instance for chaining.
1712
+ */
1713
+ put(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1714
+ /**
1715
+ * Add a PUT route definition to this router.
1716
+ *
1717
+ * @param path - URL path pattern to match.
1718
+ * @param options - Route options registered with the PUT method.
1719
+ * @returns The router instance for chaining.
1720
+ */
1721
+ put<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1722
+ /**
1723
+ * Add a DELETE route handler to this router.
1724
+ *
1725
+ * @param path - URL path pattern to match.
1726
+ * @param handler - Handler invoked when the route matches.
1727
+ * @returns The router instance for chaining.
1728
+ */
1729
+ delete(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1730
+ /**
1731
+ * Add a DELETE route definition to this router.
1732
+ *
1733
+ * @param path - URL path pattern to match.
1734
+ * @param options - Route options registered with the DELETE method.
1735
+ * @returns The router instance for chaining.
1736
+ */
1737
+ delete<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1738
+ /**
1739
+ * Add a PATCH route handler to this router.
1740
+ *
1741
+ * @param path - URL path pattern to match.
1742
+ * @param handler - Handler invoked when the route matches.
1743
+ * @returns The router instance for chaining.
1744
+ */
1745
+ patch(path: NonNullable<Route<Ctx>['path']>, handler: Handler<any, Ctx>): this;
1746
+ /**
1747
+ * Add a PATCH route definition to this router.
1748
+ *
1749
+ * @param path - URL path pattern to match.
1750
+ * @param options - Route options registered with the PATCH method.
1751
+ * @returns The router instance for chaining.
1752
+ */
1753
+ patch<RouteMiddleware extends MiddlewareInput<Ctx> = undefined, HandlerCtx extends object = Ctx & AddedContextFromMiddlewareInput<RouteMiddleware>>(path: NonNullable<Route<Ctx>['path']>, options: RouteOptions<Ctx, RouteMiddleware, HandlerCtx>): this;
1754
+ /**
1755
+ * Return a flattened list of registered routes.
1756
+ *
1757
+ * @example
1758
+ * ```ts
1759
+ * const routes = router.getRoutes()
1760
+ * ```
1761
+ *
1762
+ * @returns Array of normalized routes.
1763
+ */
1764
+ getRoutes(): NormalizedRoute<any>[];
1765
+ private _getRoutes;
1766
+ private _defaultRuntimeConfig;
1767
+ private _handlerRegistration;
1768
+ private _resolveRuntimeConfig;
1769
+ private _match;
1770
+ private _collectAllowedMethods;
1771
+ private _acceptMatches;
1772
+ private _formatAllowMethods;
1773
+ private _buildHandlerContext;
1774
+ private _runRequestMiddleware;
1775
+ private _executeHandler;
1776
+ private _statusResponse;
1777
+ private _logInternalServerError;
1778
+ private _finalizeResult;
1779
+ private _responseFromRoutekitResponse;
1780
+ private _appendVary;
1781
+ private _selectSerializer;
1782
+ private _isBetterSerializerCandidate;
1783
+ private _tryCustomHandler;
1784
+ private _requestWithBodyParsers;
1785
+ private _handleNotFound;
1786
+ private _handleMethodNotAllowed;
1787
+ private _handleInternalError;
1788
+ private _handleUnsupportedMediaType;
1789
+ private _handleMatch;
1790
+ private _methodMatches;
1791
+ private _withRoutePrefix;
1792
+ private _matchWithMethodCheck;
1793
+ private _run;
1794
+ private _isAsyncGenerator;
1795
+ private _closeGenerator;
1796
+ private _toResponseBody;
1797
+ private _setContentLength;
1798
+ private _getBodyByteLength;
1799
+ private _isBodyChunk;
1800
+ private _toBodyChunk;
1801
+ private _mergeHeaders;
1802
+ private _frameChunk;
1803
+ private _responseFromGenerator;
1804
+ private _handleRequest;
1805
+ /**
1806
+ * Handle an incoming request by matching routes and executing middleware.
1807
+ *
1808
+ * @example
1809
+ * ```ts
1810
+ * const response = await router.fetch(new Request('https://example.com/'))
1811
+ * ```
1812
+ *
1813
+ * @param request - Incoming request to route.
1814
+ * @returns The response produced by the matched handler.
1815
+ */
1816
+ fetch: (request: Request) => Promise<Response>;
1817
+ }
1818
+ //#endregion
1819
+ export { formDataRequestBodyParser as $, RequestMiddlewareEntry as A, RouterMountOptions as B, MiddlewareInput as C, isStreamDirective as Ct, RequestBodyParserInput as D, jsonLinesFramer as Dt, OneOrMany as E, StreamFramer as Et, RouteMeta as F, RequestBodyParser as G, RequestBodyFormData as H, RouteOptions as I, RoutekitRequest as J, RequestBodyStream as K, RoutePath as L, ResponseBodySerializerInput as M, Route as N, RequestContext as O, sseFramer as Ot, RouteMatch as P, defaultRequestBodyParsers as Q, RouteSchema as R, MiddlewareEntry as S, isStatusDirective as St, NormalizedRoute as T, stream as Tt, RequestBodyLengthMismatchError as U, RequestBodyError as V, RequestBodyParseContext as W, UnsupportedRequestBodyMediaTypeError as X, RoutekitRequestBody as Y, createRoutekitRequest as Z, JsonObjectSchema as _, headers as _t, MiddlewareResponseDeclaration as a, createStartStream as at, MediaType as b, isHeadersDirective as bt, AcceptMediaRange as c, jsonResponseBodySerializer as ct, ContentType as d, HeadersDirective as dt, jsonRequestBodyParser as et, ContextFromMiddlewareInput as f, RoutekitYield as ft, HandlerResult as g, head as gt, HandlerContext as h, chunk as ht, MiddlewareControls as i, createAsyncStream as it, RequestMiddlewareInput as j, RequestMiddleware as k, AddedContextFromMiddlewareInput as l, ChunkDirective as lt, Handler as m, StreamDirective as mt, DeclaredMiddleware as n, textRequestBodyParser as nt, MiddlewareResponseDeclarations as o, ResponseBodySerializer as ot, ContextMiddleware as p, StatusDirective as pt, RequestBodyTooLargeError as q, DefineMiddlewareOptions as r, urlEncodedRequestBodyParser as rt, defineMiddleware as s, defaultResponseBodySerializers as st, Router as t, responseFromRequestBodyError as tt, AnyContext as u, HeadDirective as ut, JsonSchema as v, isChunkDirective as vt, MiddlewareList as w, status as wt, Middleware as x, isRoutekitDirective as xt, MaybePromise as y, isHeadDirective as yt, RouterExtension as z };