@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,79 @@
1
+ import { n as RoutekitResponse, r as RoutekitResponseInit } from "../core-CzUCxvGk.mjs";
2
+ import { HttpStatus } from "@mpen/http";
3
+
4
+ //#region src/router/response/formats/content/content.d.ts
5
+ /**
6
+ * Create a represented `text/plain` response.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * return text('pong')
11
+ * ```
12
+ *
13
+ * @param value - Text response body.
14
+ * @param init - Response status and headers.
15
+ * @returns Routekit logical response with `Content-Type` set.
16
+ */
17
+ declare function text(value: string): RoutekitResponse<string, HttpStatus.OK>;
18
+ declare function text(value: string, init: Omit<RoutekitResponseInit, 'status'>): RoutekitResponse<string, HttpStatus.OK>;
19
+ declare function text<const Status extends number>(value: string, init: RoutekitResponseInit<Status> & {
20
+ status: Status;
21
+ }): RoutekitResponse<string, Status>;
22
+ /**
23
+ * Create a represented `text/html` response.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * return html('<h1>Hello</h1>')
28
+ * ```
29
+ *
30
+ * @param value - HTML response body.
31
+ * @param init - Response status and headers.
32
+ * @returns Routekit logical response with `Content-Type` set.
33
+ */
34
+ declare function html(value: string): RoutekitResponse<string, HttpStatus.OK>;
35
+ declare function html(value: string, init: Omit<RoutekitResponseInit, 'status'>): RoutekitResponse<string, HttpStatus.OK>;
36
+ declare function html<const Status extends number>(value: string, init: RoutekitResponseInit<Status> & {
37
+ status: Status;
38
+ }): RoutekitResponse<string, Status>;
39
+ //#endregion
40
+ //#region src/router/response/formats/content/bodyless.d.ts
41
+ /**
42
+ * Create an empty response with the provided status.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * return empty(HttpStatus.ACCEPTED)
47
+ * ```
48
+ *
49
+ * @param statusCode - HTTP status code to use.
50
+ * @param init - Response headers.
51
+ * @returns Routekit logical response with no body.
52
+ */
53
+ declare function empty<const Status extends number = HttpStatus.NO_CONTENT>(statusCode?: Status, init?: Omit<RoutekitResponseInit, 'status'>): RoutekitResponse<undefined, Status>;
54
+ /**
55
+ * Create a `204 No Content` response.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * return noContent()
60
+ * ```
61
+ *
62
+ * @returns Routekit logical response with no body.
63
+ */
64
+ declare function noContent(): RoutekitResponse<undefined, HttpStatus.NO_CONTENT>;
65
+ /**
66
+ * Create a redirect response.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * return redirect('/login')
71
+ * ```
72
+ *
73
+ * @param url - Redirect target URL.
74
+ * @param statusCode - Redirect status code. Defaults to `302`.
75
+ * @returns Routekit logical response with a `Location` header.
76
+ */
77
+ declare function redirect<const Status extends number = HttpStatus.FOUND>(url: string, statusCode?: Status): RoutekitResponse<undefined, Status>;
78
+ //#endregion
79
+ export { empty, html, noContent, redirect, text };
@@ -0,0 +1,2 @@
1
+ import { a as text, i as html, n as noContent, r as redirect, t as empty } from "../content-BuDOmhH_.mjs";
2
+ export { empty, html, noContent, redirect, text };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,230 @@
1
+ import { C as MiddlewareInput, f as ContextFromMiddlewareInput } from "../../router-Cwb7ak0J.mjs";
2
+ import { n as RoutekitResponse } from "../../core-CzUCxvGk.mjs";
3
+ import { d as ProblemResponse, i as ValidationProblemInit, l as ProblemIssue } from "../../responses-B379Ep9Y.mjs";
4
+ import { i as ValibotRouteBuilder, l as ValibotValidationError, o as ValibotRouteHelperDefaults } from "../../valibot-D7liFYyB.mjs";
5
+ import * as v from "valibot";
6
+
7
+ //#region src/router/response/formats/problem/valibot.d.ts
8
+ type AnySchema = v.BaseSchema<any, any, any>;
9
+ type StringSchema = v.BaseSchema<any, string, any>;
10
+ type ProblemSchemaResult<CodeSchema extends StringSchema, Schema extends AnySchema> = v.BaseSchema<v.InferInput<Schema>, ProblemResponse<v.InferOutput<CodeSchema> & string>, v.InferIssue<Schema>>;
11
+ declare function createSuccessSchema<const DataSchema extends AnySchema>(dataSchema: DataSchema): v.ObjectSchema<{
12
+ readonly success: v.LiteralSchema<true, undefined>;
13
+ readonly data: DataSchema;
14
+ }, undefined>;
15
+ declare function createSuccessSchemaWithMeta<const DataSchema extends AnySchema, const MetaSchema extends AnySchema>(dataSchema: DataSchema, metaSchema: MetaSchema): v.ObjectSchema<{
16
+ readonly success: v.LiteralSchema<true, undefined>;
17
+ readonly data: DataSchema;
18
+ readonly meta: v.OptionalSchema<MetaSchema, undefined>;
19
+ }, undefined>;
20
+ type SuccessSchemaResult<DataSchema extends AnySchema, MetaSchema extends AnySchema | undefined> = MetaSchema extends AnySchema ? ReturnType<typeof createSuccessSchemaWithMeta<DataSchema, MetaSchema>> : ReturnType<typeof createSuccessSchema<DataSchema>>;
21
+ /**
22
+ * Create a Valibot schema for standard response issues.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const schema = problemIssueSchema(v.picklist(['required', 'invalid_type']))
27
+ * ```
28
+ *
29
+ * @param codeSchema - Optional issue code schema. Defaults to `v.string()`.
30
+ * @returns Valibot object schema for [`ProblemIssue`]{@link ProblemIssue}.
31
+ * @typeParam CodeSchema - Valibot schema used for issue codes.
32
+ */
33
+ declare function problemIssueSchema<const CodeSchema extends StringSchema = StringSchema>(codeSchema?: CodeSchema): v.ObjectSchema<{
34
+ readonly code: CodeSchema;
35
+ readonly message: v.StringSchema<undefined>;
36
+ readonly path: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>], undefined>, undefined>, v.ReadonlyAction<(string | number)[]>]>, undefined>;
37
+ readonly expected: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
38
+ readonly received: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
39
+ }, undefined>;
40
+ /**
41
+ * Create a Valibot schema for standard primary error metadata.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const schema = problemErrorSchema(v.picklist(['not_found', 'validation_failed']))
46
+ * ```
47
+ *
48
+ * @param codeSchema - Optional primary error code schema. Defaults to `v.string()`.
49
+ * @returns Valibot object schema for problem error metadata.
50
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
51
+ */
52
+ declare function problemErrorSchema<const CodeSchema extends StringSchema = StringSchema>(codeSchema?: CodeSchema): v.ObjectSchema<{
53
+ readonly code: CodeSchema;
54
+ readonly message: v.StringSchema<undefined>;
55
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
56
+ }, undefined>;
57
+ /**
58
+ * Create a Valibot schema for successful standard response envelopes.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const schema = okSchema(v.object({ id: v.string() }))
63
+ * ```
64
+ *
65
+ * @param dataSchema - Valibot schema for the response payload.
66
+ * @param metaSchema - Optional Valibot schema for response metadata.
67
+ * @returns Valibot object schema for a successful standard response.
68
+ * @typeParam DataSchema - Valibot schema used for the response payload.
69
+ * @typeParam MetaSchema - Optional Valibot schema used for response metadata.
70
+ */
71
+ declare function okSchema<const DataSchema extends AnySchema, const MetaSchema extends AnySchema | undefined = undefined>(dataSchema: DataSchema, metaSchema?: MetaSchema): SuccessSchemaResult<DataSchema, MetaSchema>;
72
+ /**
73
+ * Create a Valibot schema for standard problem response envelopes.
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * const schema = problemSchema({
78
+ * code: v.picklist(['not_found', 'validation_failed']),
79
+ * })
80
+ * ```
81
+ *
82
+ * @param options - Optional primary error and issue schemas.
83
+ * @returns Valibot object schema for a standard problem response.
84
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
85
+ * @typeParam IssueSchema - Valibot schema used for response issues.
86
+ */
87
+ declare function problemSchema<const CodeSchema extends StringSchema = StringSchema, const IssueSchema extends AnySchema = ReturnType<typeof problemIssueSchema>>(options?: {
88
+ code?: CodeSchema;
89
+ issue?: IssueSchema;
90
+ }): ProblemSchemaResult<CodeSchema, v.ObjectSchema<{
91
+ readonly success: v.LiteralSchema<false, undefined>;
92
+ readonly error: v.ObjectSchema<{
93
+ readonly code: CodeSchema;
94
+ readonly message: v.StringSchema<undefined>;
95
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
96
+ }, undefined>;
97
+ readonly issues: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<IssueSchema, undefined>, v.ReadonlyAction<v.InferOutput<IssueSchema>[]>]>, undefined>;
98
+ }, undefined>>;
99
+ /**
100
+ * Create a Valibot schema for the full standard response union.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * const schema = standardResponseSchema(v.object({ id: v.string() }), {
105
+ * code: v.picklist(['not_found']),
106
+ * })
107
+ * ```
108
+ *
109
+ * @param dataSchema - Valibot schema for the successful response payload.
110
+ * @param options - Optional metadata, primary error, and issue schemas.
111
+ * @returns Valibot union schema for successful and problem responses.
112
+ * @typeParam DataSchema - Valibot schema used for the response payload.
113
+ * @typeParam MetaSchema - Optional Valibot schema used for response metadata.
114
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
115
+ * @typeParam IssueSchema - Valibot schema used for response issues.
116
+ */
117
+ declare function standardResponseSchema<const DataSchema extends AnySchema, const MetaSchema extends AnySchema | undefined = undefined, const CodeSchema extends StringSchema = StringSchema, const IssueSchema extends AnySchema = ReturnType<typeof problemIssueSchema>>(dataSchema: DataSchema, options?: {
118
+ meta?: MetaSchema;
119
+ code?: CodeSchema;
120
+ issue?: IssueSchema;
121
+ }): v.UnionSchema<[v.ObjectSchema<{
122
+ readonly success: v.LiteralSchema<true, undefined>;
123
+ readonly data: DataSchema;
124
+ }, undefined> | SuccessSchemaResult<DataSchema, MetaSchema & {}>, ProblemSchemaResult<CodeSchema, v.ObjectSchema<{
125
+ readonly success: v.LiteralSchema<false, undefined>;
126
+ readonly error: v.ObjectSchema<{
127
+ readonly code: CodeSchema;
128
+ readonly message: v.StringSchema<undefined>;
129
+ readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
130
+ }, undefined>;
131
+ readonly issues: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<IssueSchema, undefined>, v.ReadonlyAction<v.InferOutput<IssueSchema>[]>]>, undefined>;
132
+ }, undefined>>], undefined>;
133
+ /**
134
+ * Convert a Valibot issue into a standard response issue.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const parsed = v.safeParse(v.object({ id: v.string() }), { id: 123 })
139
+ * if (!parsed.success) {
140
+ * const issue = issueFromValibotIssue(parsed.issues[0])
141
+ * }
142
+ * ```
143
+ *
144
+ * @param issue - Valibot issue to convert.
145
+ * @returns Standard response issue.
146
+ */
147
+ declare function issueFromValibotIssue(issue: v.BaseIssue<unknown>): ProblemIssue;
148
+ /**
149
+ * Convert Valibot issues into standard response issues.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * const parsed = v.safeParse(v.object({ id: v.string() }), { id: 123 })
154
+ * if (!parsed.success) {
155
+ * const issues = issuesFromValibotIssues(parsed.issues)
156
+ * }
157
+ * ```
158
+ *
159
+ * @param issues - Valibot issues to convert.
160
+ * @returns Standard response issues.
161
+ */
162
+ declare function issuesFromValibotIssues(issues: readonly v.BaseIssue<unknown>[]): ProblemIssue[];
163
+ /**
164
+ * Create a validation problem response from Valibot issues.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const route = createValibotRouteBuilder()
169
+ * route({
170
+ * onRequestValidationError: (_component, issues) => validationProblemFromValibotIssues(issues),
171
+ * handler: () => ok({ saved: true }),
172
+ * })
173
+ * ```
174
+ *
175
+ * @param issues - Valibot issues to convert and include in the response.
176
+ * @param init - Optional problem response overrides and headers.
177
+ * @returns Routekit logical response with a validation [`ProblemResponse`]{@link ProblemResponse}.
178
+ * @typeParam Code - Machine-readable primary error code.
179
+ */
180
+ declare function validationProblemFromValibotIssues<const Code extends string = 'validation_failed'>(issues: readonly v.BaseIssue<unknown>[], init?: ValidationProblemInit<Code>): RoutekitResponse<ProblemResponse<Code>>;
181
+ /**
182
+ * A Valibot validation error handler that maps request validation errors to problem-compliant responses.
183
+ *
184
+ * This handler returns `422 Unprocessable Content` with error code `validation_failed:body` for request body
185
+ * validation failures, and `400 Bad Request` with `validation_failed:query` or `validation_failed:path` for
186
+ * query and path parameter validation failures respectively.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * const route = createValibotRouteBuilder({
191
+ * onRequestValidationError: problemValidationErrorHandler,
192
+ * })
193
+ * ```
194
+ *
195
+ * @param component - The request component that failed validation.
196
+ * @param issues - A non-empty tuple of Valibot validation issues.
197
+ * @returns A Routekit handler result containing the formatted problem response.
198
+ */
199
+ declare function problemValidationErrorHandler(component: ValibotValidationError, issues: [v.BaseIssue<unknown>, ...v.BaseIssue<unknown>[]]): RoutekitResponse<ProblemResponse<'validation_failed:body' | 'validation_failed:query' | 'validation_failed:path'>>;
200
+ /**
201
+ * Create a Valibot route builder pre-configured with problem-spec-compliant request validation errors.
202
+ *
203
+ * This route builder automatically configures standard error schemas for `400 Bad Request` and
204
+ * `422 Unprocessable Content` statuses. It also uses [`problemValidationErrorHandler`]{@link problemValidationErrorHandler}
205
+ * as its default validation error handler to output structured JSON responses when validation fails.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * const route = createValibotRouteBuilder()
210
+ *
211
+ * router.post('/todos', route({
212
+ * schema: {
213
+ * request: {
214
+ * body: v.object({ title: v.string() })
215
+ * }
216
+ * },
217
+ * handler: ({ body }) => ok({ title: body.title })
218
+ * }))
219
+ * ```
220
+ *
221
+ * @param defaults - Additional defaults to apply to built routes.
222
+ * @returns A problem-spec-compliant Valibot route builder.
223
+ * @typeParam BuilderCtx - Custom context registered by middlewares (e.g. Services, Auth).
224
+ */
225
+ declare function createValibotRouteBuilder<BuilderMiddleware extends MiddlewareInput<any>, BuilderCtx extends object = ContextFromMiddlewareInput<BuilderMiddleware>>(defaults: ValibotRouteHelperDefaults<BuilderCtx, BuilderMiddleware> & {
226
+ middleware: BuilderMiddleware;
227
+ }): ValibotRouteBuilder<BuilderCtx, BuilderMiddleware>;
228
+ declare function createValibotRouteBuilder<BuilderCtx extends object = object, BuilderMiddleware extends MiddlewareInput<BuilderCtx> = undefined>(defaults?: ValibotRouteHelperDefaults<BuilderCtx, BuilderMiddleware>): ValibotRouteBuilder<BuilderCtx, BuilderMiddleware>;
229
+ //#endregion
230
+ export { createValibotRouteBuilder, issueFromValibotIssue, issuesFromValibotIssues, okSchema, problemErrorSchema, problemIssueSchema, problemSchema, problemValidationErrorHandler, standardResponseSchema, validationProblemFromValibotIssues };
@@ -0,0 +1,258 @@
1
+ import { i as validationProblem } from "../../responses-BpVrgeYi.mjs";
2
+ import { n as createValibotRouteBuilder$1 } from "../../valibot-Du97X-TS.mjs";
3
+ import { HttpStatus } from "@mpen/http";
4
+ import * as v from "valibot";
5
+ //#region src/router/response/formats/problem/valibot.ts
6
+ function pathSegmentFromValibotKey(key) {
7
+ if (typeof key === "string" || typeof key === "number") return key;
8
+ }
9
+ function pathFromValibotIssue(issue) {
10
+ const path = issue.path?.map((item) => pathSegmentFromValibotKey(item.key)).filter((item) => item !== void 0);
11
+ return path?.length ? path : void 0;
12
+ }
13
+ function collectValibotIssues(issue, target) {
14
+ if (issue.issues?.length) {
15
+ for (const child of issue.issues) collectValibotIssues(child, target);
16
+ return target;
17
+ }
18
+ target.push(issueFromValibotIssue(issue));
19
+ return target;
20
+ }
21
+ function createSuccessSchema(dataSchema) {
22
+ return v.object({
23
+ success: v.literal(true),
24
+ data: dataSchema
25
+ });
26
+ }
27
+ function createSuccessSchemaWithMeta(dataSchema, metaSchema) {
28
+ return v.object({
29
+ success: v.literal(true),
30
+ data: dataSchema,
31
+ meta: v.optional(metaSchema)
32
+ });
33
+ }
34
+ /**
35
+ * Create a Valibot schema for standard response issues.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const schema = problemIssueSchema(v.picklist(['required', 'invalid_type']))
40
+ * ```
41
+ *
42
+ * @param codeSchema - Optional issue code schema. Defaults to `v.string()`.
43
+ * @returns Valibot object schema for [`ProblemIssue`]{@link ProblemIssue}.
44
+ * @typeParam CodeSchema - Valibot schema used for issue codes.
45
+ */
46
+ function problemIssueSchema(codeSchema = v.string()) {
47
+ return v.object({
48
+ code: codeSchema,
49
+ message: v.string(),
50
+ path: v.optional(v.pipe(v.array(v.union([v.string(), v.number()])), v.readonly())),
51
+ expected: v.optional(v.string()),
52
+ received: v.optional(v.string())
53
+ });
54
+ }
55
+ /**
56
+ * Create a Valibot schema for standard primary error metadata.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const schema = problemErrorSchema(v.picklist(['not_found', 'validation_failed']))
61
+ * ```
62
+ *
63
+ * @param codeSchema - Optional primary error code schema. Defaults to `v.string()`.
64
+ * @returns Valibot object schema for problem error metadata.
65
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
66
+ */
67
+ function problemErrorSchema(codeSchema = v.string()) {
68
+ return v.object({
69
+ code: codeSchema,
70
+ message: v.string(),
71
+ title: v.optional(v.string())
72
+ });
73
+ }
74
+ /**
75
+ * Create a Valibot schema for successful standard response envelopes.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const schema = okSchema(v.object({ id: v.string() }))
80
+ * ```
81
+ *
82
+ * @param dataSchema - Valibot schema for the response payload.
83
+ * @param metaSchema - Optional Valibot schema for response metadata.
84
+ * @returns Valibot object schema for a successful standard response.
85
+ * @typeParam DataSchema - Valibot schema used for the response payload.
86
+ * @typeParam MetaSchema - Optional Valibot schema used for response metadata.
87
+ */
88
+ function okSchema(dataSchema, metaSchema) {
89
+ if (metaSchema) return createSuccessSchemaWithMeta(dataSchema, metaSchema);
90
+ return createSuccessSchema(dataSchema);
91
+ }
92
+ /**
93
+ * Create a Valibot schema for standard problem response envelopes.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * const schema = problemSchema({
98
+ * code: v.picklist(['not_found', 'validation_failed']),
99
+ * })
100
+ * ```
101
+ *
102
+ * @param options - Optional primary error and issue schemas.
103
+ * @returns Valibot object schema for a standard problem response.
104
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
105
+ * @typeParam IssueSchema - Valibot schema used for response issues.
106
+ */
107
+ function problemSchema(options = {}) {
108
+ const codeSchema = options.code ?? v.string();
109
+ const issueSchema = options.issue ?? problemIssueSchema();
110
+ return v.object({
111
+ success: v.literal(false),
112
+ error: problemErrorSchema(codeSchema),
113
+ issues: v.optional(v.pipe(v.array(issueSchema), v.readonly()))
114
+ });
115
+ }
116
+ /**
117
+ * Create a Valibot schema for the full standard response union.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * const schema = standardResponseSchema(v.object({ id: v.string() }), {
122
+ * code: v.picklist(['not_found']),
123
+ * })
124
+ * ```
125
+ *
126
+ * @param dataSchema - Valibot schema for the successful response payload.
127
+ * @param options - Optional metadata, primary error, and issue schemas.
128
+ * @returns Valibot union schema for successful and problem responses.
129
+ * @typeParam DataSchema - Valibot schema used for the response payload.
130
+ * @typeParam MetaSchema - Optional Valibot schema used for response metadata.
131
+ * @typeParam CodeSchema - Valibot schema used for primary error codes.
132
+ * @typeParam IssueSchema - Valibot schema used for response issues.
133
+ */
134
+ function standardResponseSchema(dataSchema, options = {}) {
135
+ const successEnvelopeSchema = options.meta === void 0 ? okSchema(dataSchema) : okSchema(dataSchema, options.meta);
136
+ return v.union([successEnvelopeSchema, problemSchema({
137
+ code: options.code,
138
+ issue: options.issue
139
+ })]);
140
+ }
141
+ /**
142
+ * Convert a Valibot issue into a standard response issue.
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * const parsed = v.safeParse(v.object({ id: v.string() }), { id: 123 })
147
+ * if (!parsed.success) {
148
+ * const issue = issueFromValibotIssue(parsed.issues[0])
149
+ * }
150
+ * ```
151
+ *
152
+ * @param issue - Valibot issue to convert.
153
+ * @returns Standard response issue.
154
+ */
155
+ function issueFromValibotIssue(issue) {
156
+ const path = pathFromValibotIssue(issue);
157
+ return {
158
+ code: issue.type,
159
+ message: issue.message,
160
+ ...path ? { path } : {},
161
+ ...issue.expected == null ? {} : { expected: issue.expected },
162
+ received: issue.received
163
+ };
164
+ }
165
+ /**
166
+ * Convert Valibot issues into standard response issues.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * const parsed = v.safeParse(v.object({ id: v.string() }), { id: 123 })
171
+ * if (!parsed.success) {
172
+ * const issues = issuesFromValibotIssues(parsed.issues)
173
+ * }
174
+ * ```
175
+ *
176
+ * @param issues - Valibot issues to convert.
177
+ * @returns Standard response issues.
178
+ */
179
+ function issuesFromValibotIssues(issues) {
180
+ return issues.flatMap((issue) => collectValibotIssues(issue, []));
181
+ }
182
+ /**
183
+ * Create a validation problem response from Valibot issues.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * const route = createValibotRouteBuilder()
188
+ * route({
189
+ * onRequestValidationError: (_component, issues) => validationProblemFromValibotIssues(issues),
190
+ * handler: () => ok({ saved: true }),
191
+ * })
192
+ * ```
193
+ *
194
+ * @param issues - Valibot issues to convert and include in the response.
195
+ * @param init - Optional problem response overrides and headers.
196
+ * @returns Routekit logical response with a validation [`ProblemResponse`]{@link ProblemResponse}.
197
+ * @typeParam Code - Machine-readable primary error code.
198
+ */
199
+ function validationProblemFromValibotIssues(issues, init = {}) {
200
+ return validationProblem(issuesFromValibotIssues(issues), init);
201
+ }
202
+ /**
203
+ * A Valibot validation error handler that maps request validation errors to problem-compliant responses.
204
+ *
205
+ * This handler returns `422 Unprocessable Content` with error code `validation_failed:body` for request body
206
+ * validation failures, and `400 Bad Request` with `validation_failed:query` or `validation_failed:path` for
207
+ * query and path parameter validation failures respectively.
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * const route = createValibotRouteBuilder({
212
+ * onRequestValidationError: problemValidationErrorHandler,
213
+ * })
214
+ * ```
215
+ *
216
+ * @param component - The request component that failed validation.
217
+ * @param issues - A non-empty tuple of Valibot validation issues.
218
+ * @returns A Routekit handler result containing the formatted problem response.
219
+ */
220
+ function problemValidationErrorHandler(component, issues) {
221
+ let code;
222
+ let status;
223
+ switch (component) {
224
+ case 0:
225
+ code = "validation_failed:body";
226
+ status = HttpStatus.UNPROCESSABLE_ENTITY;
227
+ break;
228
+ case 2:
229
+ code = "validation_failed:query";
230
+ status = HttpStatus.BAD_REQUEST;
231
+ break;
232
+ case 1:
233
+ code = "validation_failed:path";
234
+ status = HttpStatus.BAD_REQUEST;
235
+ break;
236
+ default:
237
+ code = "validation_failed:body";
238
+ status = HttpStatus.UNPROCESSABLE_ENTITY;
239
+ break;
240
+ }
241
+ return validationProblemFromValibotIssues(issues, {
242
+ code,
243
+ status,
244
+ message: `Validation failed: ${component === 0 ? "body" : component === 2 ? "query" : "path"}`
245
+ });
246
+ }
247
+ function createValibotRouteBuilder(defaults = {}) {
248
+ return createValibotRouteBuilder$1({
249
+ onRequestValidationError: problemValidationErrorHandler,
250
+ validationResponses: { response: { body: {
251
+ 400: v.union([problemSchema({ code: v.literal("validation_failed:query") }), problemSchema({ code: v.literal("validation_failed:path") })]),
252
+ 422: problemSchema({ code: v.literal("validation_failed:body") })
253
+ } } }.response.body,
254
+ ...defaults
255
+ });
256
+ }
257
+ //#endregion
258
+ export { createValibotRouteBuilder, issueFromValibotIssue, issuesFromValibotIssues, okSchema, problemErrorSchema, problemIssueSchema, problemSchema, problemValidationErrorHandler, standardResponseSchema, validationProblemFromValibotIssues };