@mpen/routekit 0.1.0 → 0.1.1

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,282 @@
1
+ import { C as MiddlewareInput, F as RouteMeta, I as RouteOptions, N as Route, P as RouteMatch, R as RouteSchema, S as MiddlewareEntry, a as MiddlewareResponseDeclaration, f as ContextFromMiddlewareInput, g as HandlerResult, h as HandlerContext, l as AddedContextFromMiddlewareInput, n as DeclaredMiddleware, r as DefineMiddlewareOptions, t as Router, u as AnyContext } from "./router-Cwb7ak0J.mjs";
2
+ import { n as RoutekitResponse } from "./core-CzUCxvGk.mjs";
3
+ import { a as ValibotRouteHandler, c as ValibotSchemaMiddlewareOptions, d as ValibotValidationErrorHandler, f as createValibotRouteBuilder, i as ValibotRouteBuilder, l as ValibotValidationError, m as valibotSchemaMiddleware, n as ValibotHandlerContext, o as ValibotRouteHelperDefaults, p as defineValibotMiddleware, r as ValibotHandlerParams, s as ValibotRouteSchemaInput, t as DefineValibotMiddlewareOptions, u as ValibotValidationErrorBody } from "./valibot-D7liFYyB.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/router/routes/zod/zod.d.ts
7
+ /**
8
+ * Validation error component identifiers for Zod-backed routes.
9
+ */
10
+ declare const enum ValidationError {
11
+ REQUEST_BODY = 0,
12
+ URL_PATH = 1,
13
+ QUERY_PARAMETERS = 2
14
+ }
15
+ type ErrorTree = ReturnType<typeof z.treeifyError>;
16
+ type ZodSchema = z.ZodTypeAny | undefined;
17
+ type AnyZodResponseBodySchemas = Partial<Record<number | 'default', z.ZodTypeAny>>;
18
+ type ZodResponseBodySchemas = AnyZodResponseBodySchemas | undefined;
19
+ type ResponseValidationMode = false | 'strict' | 'parse';
20
+ type ResponseValidationOption = boolean | ResponseValidationMode;
21
+ type ZodRouteContext<Ctx extends object, BuilderMiddleware, RouteMiddleware> = Ctx & AddedContextFromMiddlewareInput<BuilderMiddleware> & AddedContextFromMiddlewareInput<RouteMiddleware>;
22
+ type ZodBuilderMiddlewareInput<Ctx extends object, BuilderMiddleware extends MiddlewareInput<Ctx>, RouteMiddleware extends MiddlewareInput<Ctx>> = [BuilderMiddleware] extends [undefined] ? RouteMiddleware : [RouteMiddleware] extends [undefined] ? BuilderMiddleware : MiddlewareInput<Ctx>;
23
+ /**
24
+ * Default validation error payload returned by Zod-backed routes.
25
+ */
26
+ type ZodValidationErrorBody = {
27
+ component: 'request_body' | 'url_path' | 'query_parameters';
28
+ errorTree: ErrorTree;
29
+ message: string;
30
+ };
31
+ /**
32
+ * Zod schema input that mirrors the core route `schema` shape.
33
+ */
34
+ type ZodRouteSchemaInput<BodySchema extends ZodSchema = undefined, PathSchema extends ZodSchema = undefined, QuerySchema extends ZodSchema = undefined, ResponseBodySchemas extends ZodResponseBodySchemas = undefined> = {
35
+ request?: {
36
+ query?: QuerySchema;
37
+ path?: PathSchema;
38
+ body?: BodySchema;
39
+ };
40
+ response?: {
41
+ body?: ResponseBodySchemas;
42
+ };
43
+ };
44
+ type InferSchema<Schema extends ZodSchema> = Schema extends z.ZodTypeAny ? z.infer<Schema> : unknown;
45
+ type InferResponseBodySchemaUnion<ResponseBodySchemas extends AnyZodResponseBodySchemas> = [keyof ResponseBodySchemas] extends [never] ? unknown : { [Status in keyof ResponseBodySchemas]: NonNullable<ResponseBodySchemas[Status]> extends z.ZodTypeAny ? z.infer<NonNullable<ResponseBodySchemas[Status]>> : never }[keyof ResponseBodySchemas];
46
+ type InferResponseBody<ResponseBodySchemas extends ZodResponseBodySchemas> = ResponseBodySchemas extends AnyZodResponseBodySchemas ? 200 extends keyof ResponseBodySchemas ? InferResponseBodySchemaUnion<ResponseBodySchemas> : 'default' extends keyof ResponseBodySchemas ? InferResponseBodySchemaUnion<ResponseBodySchemas> : unknown : unknown;
47
+ type NormalizeSchema<Schema> = Schema extends ZodRouteSchemaInput<any, any, any, any> ? Schema : ZodRouteSchemaInput<undefined, undefined, undefined, undefined>;
48
+ type ExtractBodySchema<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = NormalizeSchema<Schema> extends ZodRouteSchemaInput<infer BodySchema, any, any, any> ? BodySchema : undefined;
49
+ type ExtractPathSchema<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = NormalizeSchema<Schema> extends ZodRouteSchemaInput<any, infer PathSchema, any, any> ? PathSchema : undefined;
50
+ type ExtractQuerySchema<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = NormalizeSchema<Schema> extends ZodRouteSchemaInput<any, any, infer QuerySchema, any> ? QuerySchema : undefined;
51
+ type ExtractResponseBodySchemas<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = NormalizeSchema<Schema> extends ZodRouteSchemaInput<any, any, any, infer ResponseBodySchemas> ? ResponseBodySchemas : undefined;
52
+ type ZodMiddlewareDeclarations<Schemas extends AnyZodResponseBodySchemas> = { [Status in keyof Schemas]: NonNullable<Schemas[Status]> extends z.ZodTypeAny ? MiddlewareResponseDeclaration<z.infer<NonNullable<Schemas[Status]>>> : never };
53
+ type ZodDeclaredResponse<Schemas extends AnyZodResponseBodySchemas> = { [Status in keyof Schemas]-?: NonNullable<Schemas[Status]> extends z.ZodTypeAny ? RoutekitResponse<z.infer<NonNullable<Schemas[Status]>>, Status extends number ? Status : number> : never }[keyof Schemas];
54
+ type ZodSchemaMiddlewareContext<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = {
55
+ params: ZodHandlerParams<ExtractBodySchema<Schema>, ExtractPathSchema<Schema>, ExtractQuerySchema<Schema>>;
56
+ };
57
+ /**
58
+ * Validated request inputs exposed to a Zod-backed handler.
59
+ */
60
+ type ZodHandlerParams<BodySchema extends ZodSchema, PathSchema extends ZodSchema, QuerySchema extends ZodSchema> = {
61
+ path: InferSchema<PathSchema>;
62
+ query: InferSchema<QuerySchema>;
63
+ body: InferSchema<BodySchema>;
64
+ };
65
+ /**
66
+ * Context object exposed to a Zod-backed handler.
67
+ */
68
+ type ZodHandlerContext<BodySchema extends ZodSchema, PathSchema extends ZodSchema, QuerySchema extends ZodSchema, Ctx extends object> = Omit<HandlerContext<Ctx>, 'path'> & {
69
+ params: ZodHandlerParams<BodySchema, PathSchema, QuerySchema>;
70
+ };
71
+ /**
72
+ * Validation error handler used when request parsing fails.
73
+ *
74
+ * @param component - Request component that failed validation.
75
+ * @param error - The Zod validation error.
76
+ * @returns A handler result that should be returned to the client.
77
+ */
78
+ type ValidationErrorHandler<Responses extends AnyZodResponseBodySchemas = AnyZodResponseBodySchemas> = (component: ValidationError, error: z.ZodError) => ZodDeclaredResponse<Responses>;
79
+ /**
80
+ * Shared defaults that can be applied to Zod handler helpers.
81
+ */
82
+ type ZodHandlerDefaults = {
83
+ /**
84
+ * Route schema fragments that should be merged into every factory-built route.
85
+ * Route-level schemas override matching request fields and response status codes.
86
+ */
87
+ schema?: ZodRouteSchemaInput<any, any, any, any>;
88
+ /**
89
+ * Whether and how to apply `schema.response.body` to handler responses.
90
+ * `false` disables response validation, `true` and `'strict'` validate without changing the
91
+ * response body, and `'parse'` returns the parsed response body. Defaults to `'parse'`.
92
+ */
93
+ validateResponse?: ResponseValidationOption;
94
+ } & ({
95
+ onRequestValidationError?: undefined;
96
+ validationResponses?: undefined;
97
+ } | {
98
+ /**
99
+ * Override the default request validation error response.
100
+ */
101
+ onRequestValidationError: ValidationErrorHandler;
102
+ /**
103
+ * Response schemas returned by `onRequestValidationError`.
104
+ */
105
+ validationResponses: AnyZodResponseBodySchemas;
106
+ });
107
+ /**
108
+ * Shared defaults that can be applied to Zod route helpers.
109
+ */
110
+ type ZodRouteHelperDefaults<BuilderCtx extends object = AnyContext, BuilderMiddleware extends MiddlewareInput<BuilderCtx> = undefined> = ZodHandlerDefaults & {
111
+ /**
112
+ * Middleware applied to every route built by the helper.
113
+ */
114
+ middleware?: BuilderMiddleware;
115
+ };
116
+ /**
117
+ * Handler signature used by Zod schema boundaries and route builders.
118
+ */
119
+ type ZodRouteHandler<BodySchema extends ZodSchema, PathSchema extends ZodSchema, QuerySchema extends ZodSchema, ResponseBodySchemas extends ZodResponseBodySchemas, Ctx extends object = AnyContext> = (this: Router<any>, ctx: ZodHandlerContext<BodySchema, PathSchema, QuerySchema, Ctx>) => HandlerResult<InferResponseBody<ResponseBodySchemas>>;
120
+ /**
121
+ * Shared options used by Zod route builders.
122
+ */
123
+ type ZodHandlerOptions<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, Ctx extends object = AnyContext> = ZodHandlerDefaults & {
124
+ schema?: Schema;
125
+ handler: ZodRouteHandler<ExtractBodySchema<Schema>, ExtractPathSchema<Schema>, ExtractQuerySchema<Schema>, ExtractResponseBodySchemas<Schema>, Ctx>;
126
+ };
127
+ /**
128
+ * Full route options used by Zod route builders.
129
+ */
130
+ type ZodRouteOptions<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, Ctx extends object = AnyContext, BuilderMiddleware extends MiddlewareInput<Ctx> = undefined, RouteMiddleware extends MiddlewareInput<Ctx> = undefined> = Omit<Route<Ctx, RouteMiddleware, ZodRouteContext<Ctx, BuilderMiddleware, RouteMiddleware>>, 'handler' | 'schema' | 'middleware'> & ZodHandlerOptions<Schema, ZodRouteContext<Ctx, BuilderMiddleware, RouteMiddleware>> & {
131
+ middleware?: RouteMiddleware;
132
+ };
133
+ /**
134
+ * Method-specific route options used by Zod route builders.
135
+ */
136
+ type WithZodOptions<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, Ctx extends object = AnyContext, BuilderMiddleware extends MiddlewareInput<Ctx> = undefined, RouteMiddleware extends MiddlewareInput<Ctx> = undefined> = Omit<RouteOptions<Ctx, RouteMiddleware, ZodRouteContext<Ctx, BuilderMiddleware, RouteMiddleware>>, 'handler' | 'schema' | 'middleware'> & ZodHandlerOptions<Schema, ZodRouteContext<Ctx, BuilderMiddleware, RouteMiddleware>> & {
137
+ middleware?: RouteMiddleware;
138
+ };
139
+ /**
140
+ * Zod route builder created by [`createZodRouteBuilder`]{@link createZodRouteBuilder}.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * const route = createZodRouteBuilder()
145
+ *
146
+ * router.get('/users/:id', route({
147
+ * schema: {
148
+ * request: {
149
+ * path: z.object({id: z.string()}),
150
+ * },
151
+ * },
152
+ * handler: ({params}) => ({id: params.path.id}),
153
+ * }))
154
+ *
155
+ * router.add(route({
156
+ * method: HttpMethod.GET,
157
+ * path: '/health',
158
+ * handler: () => ({ok: true}),
159
+ * }))
160
+ * ```
161
+ */
162
+ type ZodRouteBuilder<BuilderCtx extends object = AnyContext, BuilderMiddleware extends MiddlewareInput<BuilderCtx> = undefined> = {
163
+ /**
164
+ * Build a full route definition that includes its own path.
165
+ *
166
+ * @param options - Full route options including `path`.
167
+ * @returns A full route definition compatible with [`Router.add`]{@link Router#add}.
168
+ */
169
+ <Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, RouteMiddleware extends MiddlewareInput<BuilderCtx> = undefined>(options: ZodRouteOptions<Schema, BuilderCtx, BuilderMiddleware, RouteMiddleware>): Route<BuilderCtx, ZodBuilderMiddlewareInput<BuilderCtx, BuilderMiddleware, RouteMiddleware>, ZodRouteContext<BuilderCtx, BuilderMiddleware, RouteMiddleware>>;
170
+ /**
171
+ * Build method-specific route options that leave the path to the registering router.
172
+ *
173
+ * @param options - Method route options without a route path.
174
+ * @returns Route options compatible with helpers like [`Router.get`]{@link Router#get}.
175
+ */
176
+ <Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, RouteMiddleware extends MiddlewareInput<BuilderCtx> = undefined>(options: WithZodOptions<Schema, BuilderCtx, BuilderMiddleware, RouteMiddleware>): RouteOptions<BuilderCtx, ZodBuilderMiddlewareInput<BuilderCtx, BuilderMiddleware, RouteMiddleware>, ZodRouteContext<BuilderCtx, BuilderMiddleware, RouteMiddleware>>;
177
+ };
178
+ /**
179
+ * Options for [`defineZodMiddleware`]{@link defineZodMiddleware}.
180
+ *
181
+ * @typeParam AddedCtx - Context made available to downstream handlers.
182
+ * @typeParam Ctx - Context required by the middleware.
183
+ * @typeParam Responses - Status-keyed Zod schemas for locally originated responses.
184
+ */
185
+ type DefineZodMiddlewareOptions<AddedCtx extends object, Ctx extends object, Responses extends AnyZodResponseBodySchemas> = {
186
+ responses: Responses;
187
+ run: DefineMiddlewareOptions<AddedCtx, Ctx, ZodMiddlewareDeclarations<Responses>>['run'];
188
+ };
189
+ /**
190
+ * Create response-declaring middleware backed by Zod response schemas.
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * const requireAuth = defineZodMiddleware({
195
+ * responses: { 401: z.object({ message: z.string() }) },
196
+ * run: (_ctx, { respond }) => respond(response({ message: 'Sign in' }, { status: 401 })),
197
+ * })
198
+ * ```
199
+ *
200
+ * @param options - Locally originated response schemas and middleware implementation.
201
+ * @returns Declared middleware with inferred, runtime-validated terminal responses.
202
+ * @typeParam AddedCtx - Context made available to downstream handlers.
203
+ * @typeParam Ctx - Context required by the middleware.
204
+ * @typeParam Responses - Status-keyed Zod schemas for locally originated responses.
205
+ */
206
+ declare function defineZodMiddleware<AddedCtx extends object = {}, Ctx extends object = AnyContext, const Responses extends AnyZodResponseBodySchemas = {}>(options: DefineZodMiddlewareOptions<AddedCtx, Ctx, Responses>): DeclaredMiddleware<AddedCtx, Ctx>;
207
+ /**
208
+ * Options for [`zodSchemaMiddleware`]{@link zodSchemaMiddleware}.
209
+ *
210
+ * @typeParam Schema - Zod request and downstream response schema declaration.
211
+ */
212
+ type ZodSchemaMiddlewareBaseOptions<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined> = {
213
+ schema?: Schema;
214
+ validateResponse?: ResponseValidationOption;
215
+ };
216
+ /**
217
+ * Options for a Zod request/response schema boundary.
218
+ *
219
+ * A custom request-validation callback must declare the response schemas it can originate.
220
+ *
221
+ * @typeParam Schema - Zod request and downstream response schema declaration.
222
+ * @typeParam ValidationResponses - Schemas owned by a custom validation-error callback.
223
+ */
224
+ type ZodSchemaMiddlewareOptions<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, ValidationResponses extends AnyZodResponseBodySchemas | undefined = undefined> = ZodSchemaMiddlewareBaseOptions<Schema> & ([ValidationResponses] extends [undefined] ? {
225
+ onRequestValidationError?: undefined;
226
+ validationResponses?: undefined;
227
+ } : {
228
+ onRequestValidationError: ValidationErrorHandler<Extract<ValidationResponses, AnyZodResponseBodySchemas>>;
229
+ validationResponses: ValidationResponses;
230
+ });
231
+ /**
232
+ * Create Zod middleware that parses request inputs and validates downstream responses.
233
+ *
234
+ * @example
235
+ * ```ts
236
+ * const parseUserId = zodSchemaMiddleware({
237
+ * schema: { request: { path: z.object({ id: z.string() }) } },
238
+ * })
239
+ * ```
240
+ *
241
+ * @param options - Request, response, and validation-error schema behavior.
242
+ * @returns Declared middleware exposing parsed request values to downstream handlers.
243
+ * @typeParam Schema - Zod request and downstream response schema declaration.
244
+ * @typeParam Ctx - Context required before this middleware executes.
245
+ */
246
+ declare function zodSchemaMiddleware<Schema extends ZodRouteSchemaInput<any, any, any, any> | undefined, const ValidationResponses extends AnyZodResponseBodySchemas | undefined = undefined, Ctx extends object = AnyContext>(options: ZodSchemaMiddlewareOptions<Schema, ValidationResponses>): DeclaredMiddleware<ZodSchemaMiddlewareContext<Schema>, Ctx>;
247
+ /**
248
+ * Create a Zod route builder with shared defaults.
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * const route = createZodRouteBuilder({
253
+ * validateResponse: false,
254
+ * schema: {
255
+ * response: {
256
+ * body: {
257
+ * 400: z.object({message: z.string()}),
258
+ * },
259
+ * },
260
+ * },
261
+ * })
262
+ *
263
+ * router.post('/users/:id', route({
264
+ * name: 'user.update',
265
+ * schema: {
266
+ * request: {
267
+ * path: z.object({id: z.string()}),
268
+ * },
269
+ * },
270
+ * handler: ({params}) => ({id: params.path.id}),
271
+ * }))
272
+ * ```
273
+ *
274
+ * @param defaults - Default schema fragments, response validation, and request validation error handling.
275
+ * @returns A route builder compatible with method-specific router helpers and full route definitions.
276
+ */
277
+ declare function createZodRouteBuilder<BuilderMiddleware extends MiddlewareInput<any>, BuilderCtx extends object = ContextFromMiddlewareInput<BuilderMiddleware>>(defaults: ZodRouteHelperDefaults<BuilderCtx, BuilderMiddleware> & {
278
+ middleware: BuilderMiddleware;
279
+ }): ZodRouteBuilder<BuilderCtx, BuilderMiddleware>;
280
+ declare function createZodRouteBuilder<BuilderCtx extends object = AnyContext, BuilderMiddleware extends MiddlewareInput<BuilderCtx> = undefined>(defaults?: ZodRouteHelperDefaults<BuilderCtx, BuilderMiddleware>): ZodRouteBuilder<BuilderCtx, BuilderMiddleware>;
281
+ //#endregion
282
+ export { type AddedContextFromMiddlewareInput, type ContextFromMiddlewareInput, type DefineValibotMiddlewareOptions, type DefineZodMiddlewareOptions, type MiddlewareEntry, type Route, type RouteMatch, type RouteMeta, type RouteOptions, type RouteSchema, type ValibotHandlerContext, type ValibotHandlerParams, type ValibotRouteBuilder, type ValibotRouteHandler, type ValibotRouteHelperDefaults, type ValibotRouteSchemaInput, type ValibotSchemaMiddlewareOptions, ValibotValidationError, type ValibotValidationErrorBody, type ValibotValidationErrorHandler, ValidationError, type ValidationErrorHandler, type ZodHandlerContext, type ZodHandlerParams, type ZodRouteBuilder, type ZodRouteHandler, type ZodRouteHelperDefaults, type ZodRouteSchemaInput, type ZodSchemaMiddlewareOptions, type ZodValidationErrorBody, createValibotRouteBuilder, createZodRouteBuilder, defineValibotMiddleware, defineZodMiddleware, valibotSchemaMiddleware, zodSchemaMiddleware };
@@ -0,0 +1,311 @@
1
+ import { M as isJsonContentType, f as defineMiddleware, t as RequestBodyError } from "./request-Dn0zc-xm.mjs";
2
+ import { a as response, i as isRoutekitResponse, r as isRoutekitBody } from "./core-DbmQauwS.mjs";
3
+ import { i as valibotSchemaMiddleware, n as createValibotRouteBuilder, r as defineValibotMiddleware, t as ValibotValidationError } from "./valibot-Du97X-TS.mjs";
4
+ import { HttpStatus } from "@mpen/http";
5
+ import { z } from "zod";
6
+ //#region src/router/routes/zod/zod.ts
7
+ /**
8
+ * Validation error component identifiers for Zod-backed routes.
9
+ */
10
+ let ValidationError = /* @__PURE__ */ function(ValidationError) {
11
+ ValidationError[ValidationError["REQUEST_BODY"] = 0] = "REQUEST_BODY";
12
+ ValidationError[ValidationError["URL_PATH"] = 1] = "URL_PATH";
13
+ ValidationError[ValidationError["QUERY_PARAMETERS"] = 2] = "QUERY_PARAMETERS";
14
+ return ValidationError;
15
+ }({});
16
+ const validationErrorComponentName = new Map([
17
+ [0, "request_body"],
18
+ [1, "url_path"],
19
+ [2, "query_parameters"]
20
+ ]);
21
+ var ZodResponseValidationError = class extends Error {
22
+ status;
23
+ error;
24
+ constructor(status, error) {
25
+ super(`Response validation failed for status ${status}: ${z.prettifyError(error)}`);
26
+ this.name = "ZodResponseValidationError";
27
+ this.status = status;
28
+ this.error = error;
29
+ }
30
+ };
31
+ function createValidationResponse(component, error) {
32
+ return response({
33
+ component: validationErrorComponentName.get(component) ?? "request_body",
34
+ errorTree: z.treeifyError(error),
35
+ message: z.prettifyError(error)
36
+ }, { status: HttpStatus.BAD_REQUEST });
37
+ }
38
+ function normalizeResponseValidationMode(option) {
39
+ if (option === true) return "strict";
40
+ return option;
41
+ }
42
+ function readQueryParams(searchParams) {
43
+ const query = {};
44
+ for (const [key, value] of searchParams.entries()) {
45
+ const existing = query[key];
46
+ if (existing === void 0) {
47
+ query[key] = value;
48
+ continue;
49
+ }
50
+ if (Array.isArray(existing)) existing.push(value);
51
+ else query[key] = [existing, value];
52
+ }
53
+ return query;
54
+ }
55
+ function zodErrorFromThrowable(error) {
56
+ return new z.ZodError([{
57
+ code: z.ZodIssueCode.custom,
58
+ path: [],
59
+ message: error instanceof Error ? error.message : String(error)
60
+ }]);
61
+ }
62
+ function sanitizeJsonSchema(schema) {
63
+ if (Array.isArray(schema)) return schema.map((entry) => sanitizeJsonSchema(entry));
64
+ if (!schema || typeof schema !== "object") return schema;
65
+ const sanitizedEntries = Object.entries(schema).filter(([key]) => key !== "$schema" && key !== "~standard").map(([key, value]) => [key, sanitizeJsonSchema(value)]);
66
+ return Object.fromEntries(sanitizedEntries);
67
+ }
68
+ function toJsonSchema(schema) {
69
+ return sanitizeJsonSchema(z.toJSONSchema(schema));
70
+ }
71
+ function buildRouteSchema(schema) {
72
+ if (!schema) return void 0;
73
+ const request = schema.request ? {
74
+ ...schema.request.query ? { query: toJsonSchema(schema.request.query) } : {},
75
+ ...schema.request.path ? { path: toJsonSchema(schema.request.path) } : {},
76
+ ...schema.request.body ? { body: toJsonSchema(schema.request.body) } : {}
77
+ } : void 0;
78
+ const responseBody = schema.response?.body ? Object.fromEntries(Object.entries(schema.response.body).map(([status, responseSchema]) => {
79
+ return [status === "default" ? status : Number(status), toJsonSchema(responseSchema)];
80
+ })) : void 0;
81
+ const response = responseBody && Object.keys(responseBody).length > 0 ? { body: responseBody } : void 0;
82
+ if ((!request || Object.keys(request).length === 0) && !response) return;
83
+ return {
84
+ ...request && Object.keys(request).length > 0 ? { request } : {},
85
+ ...response ? { response } : {}
86
+ };
87
+ }
88
+ function buildZodMiddlewareDeclarations(schemas) {
89
+ return Object.fromEntries(Object.entries(schemas).flatMap(([status, schema]) => schema ? [[status, {
90
+ schema: toJsonSchema(schema),
91
+ parse: (value) => schema.parse(value)
92
+ }]] : []));
93
+ }
94
+ function defineZodMiddleware(options) {
95
+ return defineMiddleware({
96
+ responses: buildZodMiddlewareDeclarations(options.responses),
97
+ run: options.run
98
+ });
99
+ }
100
+ function mergeRouteSchema(defaults, schema) {
101
+ const defaultSchema = defaults.schema;
102
+ if (!defaultSchema) return schema;
103
+ if (!schema) return defaultSchema;
104
+ const request = !defaultSchema.request && !schema.request ? void 0 : {
105
+ ...defaultSchema.request,
106
+ ...schema.request
107
+ };
108
+ const defaultBody = defaultSchema.response?.body ?? {};
109
+ const routeBody = schema.response?.body ?? {};
110
+ const responseBody = {};
111
+ const statuses = new Set([...Object.keys(defaultBody), ...Object.keys(routeBody)]);
112
+ for (const status of statuses) {
113
+ const s = status === "default" ? status : Number(status);
114
+ const defaultStatusSchema = defaultBody[s];
115
+ const routeStatusSchema = routeBody[s];
116
+ if (defaultStatusSchema && routeStatusSchema) responseBody[s] = z.union([defaultStatusSchema, routeStatusSchema]);
117
+ else if (defaultStatusSchema) responseBody[s] = defaultStatusSchema;
118
+ else if (routeStatusSchema) responseBody[s] = routeStatusSchema;
119
+ }
120
+ const response = Object.keys(responseBody).length > 0 ? { body: responseBody } : void 0;
121
+ return {
122
+ ...request ? { request } : {},
123
+ ...response ? { response } : {}
124
+ };
125
+ }
126
+ function normalizeMiddlewareInput(middleware) {
127
+ if (!middleware) return [];
128
+ if (Array.isArray(middleware)) return middleware.filter(Boolean);
129
+ return [middleware];
130
+ }
131
+ function mergeMiddleware(defaultMiddleware, routeMiddleware) {
132
+ const list = [...normalizeMiddlewareInput(defaultMiddleware), ...normalizeMiddlewareInput(routeMiddleware)];
133
+ return list.length ? list : void 0;
134
+ }
135
+ function mergeZodOptions(defaults, options) {
136
+ const { middleware: defaultMiddleware, ...defaultOptions } = defaults;
137
+ const schema = mergeRouteSchema(defaults, options.schema);
138
+ const middleware = mergeMiddleware(defaultMiddleware, options.middleware);
139
+ return {
140
+ ...defaultOptions,
141
+ ...options,
142
+ ...schema === void 0 ? {} : { schema },
143
+ ...middleware === void 0 ? {} : { middleware }
144
+ };
145
+ }
146
+ function hasRoutePath(options) {
147
+ return options.path !== void 0;
148
+ }
149
+ function isSkippableResponseValidationValue(value) {
150
+ return value instanceof ReadableStream || value instanceof Uint8Array || typeof Buffer !== "undefined" && value instanceof Buffer || !!value && typeof value === "object" && Symbol.asyncIterator in value;
151
+ }
152
+ function jsonValuesEqual(left, right) {
153
+ if (Object.is(left, right)) return true;
154
+ if (typeof left !== typeof right) return false;
155
+ if (!left || !right || typeof left !== "object") return false;
156
+ if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => jsonValuesEqual(value, right[index]));
157
+ const leftEntries = Object.entries(left);
158
+ const rightRecord = right;
159
+ const rightKeys = new Set(Object.keys(rightRecord));
160
+ return leftEntries.length === rightKeys.size && leftEntries.every(([key, value]) => rightKeys.has(key) && jsonValuesEqual(value, rightRecord[key]));
161
+ }
162
+ function getResponseSchemaForStatus(schema, status) {
163
+ return schema?.response?.body?.[status] ?? schema?.response?.body?.default;
164
+ }
165
+ async function readResponseBodyForValidation(response) {
166
+ if (!response.body) return void 0;
167
+ const contentType = response.headers.get("content-type") ?? "";
168
+ const clone = response.clone();
169
+ if (isJsonContentType(contentType)) return {
170
+ value: await clone.json(),
171
+ writableJson: true
172
+ };
173
+ return {
174
+ value: await clone.text(),
175
+ writableJson: false
176
+ };
177
+ }
178
+ function responseWithJsonBody(response, value) {
179
+ const headers = new Headers(response.headers);
180
+ headers.delete("content-length");
181
+ if (!headers.has("content-type")) headers.set("content-type", "application/json");
182
+ return new Response(value === void 0 ? void 0 : JSON.stringify(value), {
183
+ status: response.status,
184
+ statusText: response.statusText,
185
+ headers
186
+ });
187
+ }
188
+ function parseResponseSchema(schema, status, value, mode) {
189
+ const responseSchema = getResponseSchemaForStatus(schema, status);
190
+ if (!responseSchema) return value;
191
+ const result = responseSchema.safeParse(value);
192
+ if (!result.success) throw new ZodResponseValidationError(status, result.error);
193
+ if (mode === "strict" && !jsonValuesEqual(value, result.data)) throw new ZodResponseValidationError(status, new z.ZodError([{
194
+ code: z.ZodIssueCode.custom,
195
+ path: [],
196
+ message: "Response body does not match the parsed schema output."
197
+ }]));
198
+ return mode === "parse" ? result.data : value;
199
+ }
200
+ async function validateHandlerResult(schema, result, mode) {
201
+ if (result instanceof Response) {
202
+ const body = await readResponseBodyForValidation(result);
203
+ if (!body) return result;
204
+ const parsed = parseResponseSchema(schema, result.status, body.value, mode);
205
+ return mode === "parse" && body.writableJson ? responseWithJsonBody(result, parsed) : result;
206
+ }
207
+ if (isRoutekitResponse(result)) {
208
+ const parsed = parseResponseSchema(schema, result.status, result.body, mode);
209
+ return mode === "parse" ? response(parsed, {
210
+ status: result.status,
211
+ headers: result.headers
212
+ }) : result;
213
+ }
214
+ if (isRoutekitBody(result)) {
215
+ const parsed = parseResponseSchema(schema, HttpStatus.OK, result.value, mode);
216
+ return mode === "parse" ? parsed : result;
217
+ }
218
+ if (isSkippableResponseValidationValue(result)) return result;
219
+ return parseResponseSchema(schema, HttpStatus.OK, result, mode);
220
+ }
221
+ const defaultValidationErrorSchema = z.object({
222
+ component: z.enum([
223
+ "request_body",
224
+ "url_path",
225
+ "query_parameters"
226
+ ]),
227
+ errorTree: z.unknown(),
228
+ message: z.string()
229
+ });
230
+ /**
231
+ * Create Zod middleware that parses request inputs and validates downstream responses.
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * const parseUserId = zodSchemaMiddleware({
236
+ * schema: { request: { path: z.object({ id: z.string() }) } },
237
+ * })
238
+ * ```
239
+ *
240
+ * @param options - Request, response, and validation-error schema behavior.
241
+ * @returns Declared middleware exposing parsed request values to downstream handlers.
242
+ * @typeParam Schema - Zod request and downstream response schema declaration.
243
+ * @typeParam Ctx - Context required before this middleware executes.
244
+ */
245
+ function zodSchemaMiddleware(options) {
246
+ const validateResponse = normalizeResponseValidationMode(options.validateResponse) ?? "parse";
247
+ const parsesRequest = options.schema?.request !== void 0;
248
+ const declarations = buildZodMiddlewareDeclarations(options.validationResponses ?? (parsesRequest ? { [HttpStatus.BAD_REQUEST]: defaultValidationErrorSchema } : {}));
249
+ const onRequestValidationError = options.onRequestValidationError ?? createValidationResponse;
250
+ return defineMiddleware({
251
+ schema: buildRouteSchema(options.schema),
252
+ responses: declarations,
253
+ async run(ctx, { next, forward, respond }) {
254
+ const bodySchema = options.schema?.request?.body;
255
+ const pathSchema = options.schema?.request?.path;
256
+ const querySchema = options.schema?.request?.query;
257
+ const queryParams = readQueryParams(ctx.url.searchParams);
258
+ const handlerContext = ctx;
259
+ const params = {
260
+ path: ctx.path,
261
+ query: void 0,
262
+ body: void 0
263
+ };
264
+ handlerContext.params = params;
265
+ if (querySchema) {
266
+ const parsed = querySchema.safeParse(queryParams);
267
+ if (!parsed.success) return respond(onRequestValidationError(2, parsed.error));
268
+ params.query = parsed.data;
269
+ }
270
+ if (pathSchema) {
271
+ const parsed = pathSchema.safeParse(ctx.path);
272
+ if (!parsed.success) return respond(onRequestValidationError(1, parsed.error));
273
+ params.path = parsed.data;
274
+ }
275
+ if (bodySchema) {
276
+ let rawBody;
277
+ try {
278
+ rawBody = await ctx.request.body.parse();
279
+ } catch (err) {
280
+ if (err instanceof RequestBodyError) throw err;
281
+ return respond(onRequestValidationError(0, zodErrorFromThrowable(err)));
282
+ }
283
+ const parsed = bodySchema.safeParse(rawBody);
284
+ if (!parsed.success) return respond(onRequestValidationError(0, parsed.error));
285
+ params.body = parsed.data;
286
+ }
287
+ const result = await next();
288
+ return forward(validateResponse === false ? result : await validateHandlerResult(options.schema, result, validateResponse));
289
+ }
290
+ });
291
+ }
292
+ function createZodRouteBuilder(defaults = {}) {
293
+ return ((options) => {
294
+ const { schema, handler, onRequestValidationError, validateResponse, validationResponses, middleware, ...routeOptions } = mergeZodOptions(defaults, options);
295
+ const routeMiddleware = mergeMiddleware(middleware, zodSchemaMiddleware({
296
+ ...schema ? { schema } : {},
297
+ ...onRequestValidationError ? { onRequestValidationError } : {},
298
+ ...validateResponse === void 0 ? {} : { validateResponse },
299
+ ...validationResponses === void 0 ? {} : { validationResponses }
300
+ }));
301
+ const built = {
302
+ ...routeOptions,
303
+ handler,
304
+ middleware: routeMiddleware
305
+ };
306
+ if (hasRoutePath(built)) return built;
307
+ return built;
308
+ });
309
+ }
310
+ //#endregion
311
+ export { ValibotValidationError, ValidationError, createValibotRouteBuilder, createZodRouteBuilder, defineValibotMiddleware, defineZodMiddleware, valibotSchemaMiddleware, zodSchemaMiddleware };
@@ -0,0 +1,59 @@
1
+ import { a as response } from "./core-DbmQauwS.mjs";
2
+ import { HttpStatus } from "@mpen/http";
3
+ //#region src/router/response/formats/status/responses.ts
4
+ /**
5
+ * Create a `200 OK` logical response.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * return ok({payload: 'ready'})
10
+ * ```
11
+ *
12
+ * @param responseBody - Logical response body.
13
+ * @param init - Response headers.
14
+ * @returns Routekit logical response.
15
+ */
16
+ function ok(responseBody, init = {}) {
17
+ return response(responseBody, {
18
+ ...init,
19
+ status: HttpStatus.OK
20
+ });
21
+ }
22
+ /**
23
+ * Create a `400 Bad Request` logical response.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * return badRequest({message: 'Invalid request'})
28
+ * ```
29
+ *
30
+ * @param responseBody - Logical response body.
31
+ * @param init - Response headers.
32
+ * @returns Routekit logical response.
33
+ */
34
+ function badRequest(responseBody, init = {}) {
35
+ return response(responseBody, {
36
+ ...init,
37
+ status: HttpStatus.BAD_REQUEST
38
+ });
39
+ }
40
+ /**
41
+ * Create a `422 Unprocessable Content` logical response.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * return unprocessableContent({message: 'Email is already taken'})
46
+ * ```
47
+ *
48
+ * @param responseBody - Logical response body.
49
+ * @param init - Response headers.
50
+ * @returns Routekit logical response.
51
+ */
52
+ function unprocessableContent(responseBody, init = {}) {
53
+ return response(responseBody, {
54
+ ...init,
55
+ status: HttpStatus.UNPROCESSABLE_ENTITY
56
+ });
57
+ }
58
+ //#endregion
59
+ export { ok as n, unprocessableContent as r, badRequest as t };