@sdk-it/hono 0.15.0 → 0.17.0

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.
package/README.md CHANGED
@@ -21,11 +21,16 @@ The validator middleware offers type-safe request validation using [Zod](https:/
21
21
  > [!IMPORTANT]
22
22
  > For openapi generation to work correctly, you must use the `validate` middleware for each route.
23
23
 
24
+ **Basic Usage:**
25
+
24
26
  ```typescript
27
+ import { z } from 'zod';
28
+
25
29
  import { validate } from '@sdk-it/hono/runtime';
26
30
 
27
31
  app.post(
28
32
  '/books',
33
+ // No content type specified - validation runs regardless of content type
29
34
  validate((payload) => ({
30
35
  // Query parameter validation
31
36
  page: {
@@ -80,6 +85,106 @@ app.post(
80
85
  );
81
86
  ```
82
87
 
88
+ **Enforcing Content Type:**
89
+
90
+ The `validate` function can optionally enforce a specific content type before validation.
91
+
92
+ ```typescript
93
+ import { z } from 'zod';
94
+
95
+ import { validate } from '@sdk-it/hono/runtime';
96
+
97
+ // Specifying content type enforcement
98
+ app.post(
99
+ '/users',
100
+ validate('application/json', (payload) => ({
101
+ // <-- Enforces 'application/json'
102
+ name: {
103
+ select: payload.body.name,
104
+ against: z.string(),
105
+ },
106
+ })),
107
+ (c) => {
108
+ // Handle request with guaranteed JSON content
109
+ const { name } = c.var.input;
110
+ return c.json({ success: true });
111
+ },
112
+ );
113
+ ```
114
+
115
+ **Handling File Uploads (`multipart/form-data`):**
116
+
117
+ Use `z.instanceof(File)` to validate file uploads when enforcing `multipart/form-data`.
118
+
119
+ ```typescript
120
+ import { z } from 'zod';
121
+
122
+ import { validate } from '@sdk-it/hono/runtime';
123
+
124
+ // import { writeFile } from 'node:fs/promises'; // Example for saving file
125
+
126
+ /**
127
+ * @openapi uploadProfilePicture
128
+ * @tags users
129
+ */
130
+ app.post(
131
+ '/users/:userId/avatar',
132
+ validate('multipart/form-data', (payload) => ({
133
+ userId: {
134
+ select: payload.params.userId,
135
+ against: z.string().uuid(),
136
+ },
137
+ // File validation
138
+ avatar: {
139
+ select: payload.body.avatar, // 'avatar' is the field name in the form data
140
+ against: z.instanceof(File), // <-- Validate that 'avatar' is a File object
141
+ },
142
+ // Other form fields can also be validated
143
+ caption: {
144
+ select: payload.body.caption,
145
+ against: z.string().optional(), // Example: optional caption field
146
+ },
147
+ })),
148
+ async (c) => {
149
+ const { userId, avatar, caption } = c.var.input;
150
+
151
+ // Example: Process the uploaded file
152
+ // const fileBuffer = Buffer.from(await avatar.arrayBuffer());
153
+ // await writeFile(`./uploads/${userId}_${avatar.name}`, fileBuffer);
154
+
155
+ console.log(
156
+ `Received avatar for user ${userId}: ${avatar.name}, size: ${avatar.size}`,
157
+ );
158
+ if (caption) {
159
+ console.log(`Caption: ${caption}`);
160
+ }
161
+ return c.json({
162
+ message: `Avatar for user ${userId} uploaded successfully.`,
163
+ });
164
+ },
165
+ );
166
+ ```
167
+
168
+ ### Content Type Consumption
169
+
170
+ If you only need to enforce a content type without performing validation, use the `consume` middleware:
171
+
172
+ ```typescript
173
+ import { consume } from '@sdk-it/hono/runtime';
174
+
175
+ app.post(
176
+ '/upload',
177
+ consume('multipart/form-data'), // <-- Enforces 'multipart/form-data'
178
+ async (c) => {
179
+ // Process raw multipart form data from the request body
180
+ const body = await c.req.parseBody();
181
+ const file = body['file']; // Access file data
182
+ // ... process file ...
183
+ return c.json({ success: true });
184
+ },
185
+ );
186
+ ```
187
+
83
188
  ### Response Helper
84
189
 
85
190
  The output function provides a clean API for sending HTTP responses with proper status codes and content types.
@@ -122,7 +227,7 @@ Consider the following example:
122
227
  - Create hono routes with the `@openapi` tag and validate middleware.
123
228
 
124
229
  ```typescript
125
- import z from 'zod';
230
+ import { z } from 'zod';
126
231
 
127
232
  import { validate } from '@sdk-it/hono/runtime';
128
233
 
@@ -141,7 +246,8 @@ app.get(
141
246
  },
142
247
  })),
143
248
  async (c) => {
144
- const books = [{ name: 'OpenAPI' }];
249
+ const { author } = c.var.input; // <-- Access validated input
250
+ const books = [{ name: `Books by ${author}` }];
145
251
  return c.json(books);
146
252
  },
147
253
  );
@@ -80,18 +80,29 @@ function createOutput(contextFn) {
80
80
  var output = createOutput(() => getContext());
81
81
 
82
82
  // packages/hono/src/lib/runtime/validator.ts
83
+ import { parse as parseContentType } from "fast-content-type-parse";
83
84
  import { createMiddleware } from "hono/factory";
84
85
  import { HTTPException } from "hono/http-exception";
85
86
  import z from "zod";
86
- var validate = (selector) => {
87
+ function validate(expectedContentTypeOrSelector, selector) {
88
+ const expectedContentType = typeof expectedContentTypeOrSelector === "string" ? expectedContentTypeOrSelector : void 0;
89
+ const _selector = typeof expectedContentTypeOrSelector === "function" ? expectedContentTypeOrSelector : selector;
90
+ if (!_selector) {
91
+ throw new Error("Selector function is required");
92
+ }
87
93
  return createMiddleware(async (c, next) => {
88
- const contentType = c.req.header("content-type") ?? "";
94
+ const ct = c.req.header("content-type");
95
+ if (expectedContentType) {
96
+ verifyContentType(ct, expectedContentType);
97
+ }
98
+ const contentType = ct ? parseContentType(ct) : null;
89
99
  let body = null;
90
- switch (contentType) {
100
+ switch (contentType?.type) {
91
101
  case "application/json":
92
102
  body = await c.req.json();
93
103
  break;
94
104
  case "application/x-www-form-urlencoded":
105
+ case "multipart/form-data":
95
106
  body = await c.req.parseBody();
96
107
  break;
97
108
  default:
@@ -106,7 +117,7 @@ var validate = (selector) => {
106
117
  Object.entries(c.req.header()).map(([k, v]) => [k, v ?? ""])
107
118
  )
108
119
  };
109
- const config = selector(payload);
120
+ const config = _selector(payload);
110
121
  const schema = z.object(
111
122
  Object.entries(config).reduce(
112
123
  (acc, [key, value]) => {
@@ -127,7 +138,7 @@ var validate = (selector) => {
127
138
  c.set("input", parsed);
128
139
  await next();
129
140
  });
130
- };
141
+ }
131
142
  function parse(schema, input) {
132
143
  const result = schema.safeParse(input);
133
144
  if (!result.success) {
@@ -151,25 +162,38 @@ function parse(schema, input) {
151
162
  var openapi = validate;
152
163
  var consume = (contentType) => {
153
164
  return createMiddleware(async (context, next) => {
154
- const clientContentType = context.req.header("Content-Type");
155
- if (clientContentType !== contentType) {
156
- throw new HTTPException(415, {
157
- message: "Unsupported Media Type",
158
- cause: {
159
- code: "api/unsupported-media-type",
160
- detail: `Expected content type: ${contentType}, but got: ${clientContentType}`
161
- }
162
- });
163
- }
165
+ verifyContentType(context.req.header("content-type"), contentType);
164
166
  await next();
165
167
  });
166
168
  };
169
+ function verifyContentType(actual, expected) {
170
+ if (!actual) {
171
+ throw new HTTPException(415, {
172
+ message: "Unsupported Media Type",
173
+ cause: {
174
+ code: "api/unsupported-media-type",
175
+ details: "Missing content type header"
176
+ }
177
+ });
178
+ }
179
+ const { type: incomingContentType } = parseContentType(actual);
180
+ if (incomingContentType !== expected) {
181
+ throw new HTTPException(415, {
182
+ message: "Unsupported Media Type",
183
+ cause: {
184
+ code: "api/unsupported-media-type",
185
+ details: `Expected content type: ${expected}, but got: ${incomingContentType}`
186
+ }
187
+ });
188
+ }
189
+ }
167
190
  export {
168
191
  consume,
169
192
  createOutput,
170
193
  openapi,
171
194
  output,
172
195
  parse,
173
- validate
196
+ validate,
197
+ verifyContentType
174
198
  };
175
199
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/runtime/output.ts", "../../../src/lib/runtime/validator.ts"],
4
- "sourcesContent": ["import type { Context } from 'hono';\nimport { getContext } from 'hono/context-storage';\nimport type {\n ContentfulStatusCode,\n RedirectStatusCode,\n} from 'hono/utils/http-status';\n\ntype Data = any;\nfunction send(\n context: Context,\n value: Data | undefined | null,\n status: ContentfulStatusCode,\n headers?: Readonly<Record<string, string>>,\n) {\n if (value === undefined || value === null) {\n return context.body(null, status, headers);\n }\n const responseHeaders = { ...headers };\n responseHeaders['Content-Type'] ??= 'application/json';\n if (responseHeaders['Content-Type'].includes('application/json')) {\n return context.body(JSON.stringify(value), status, responseHeaders);\n }\n return context.body(value, status, responseHeaders);\n}\n\nexport function createOutput(contextFn: () => Context) {\n return {\n nocontent() {\n const context = contextFn();\n return context.body(null, 204, {});\n },\n ok(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 200, headers);\n },\n created(\n valueOrUri: string | Data,\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n if (typeof valueOrUri === 'string') {\n // If no content is provided, we send null\n return send(contextFn(), value, 201, {\n Location: valueOrUri,\n ...(headers || {}),\n });\n } else {\n // valueOrUri is the data\n return send(contextFn(), valueOrUri, 201, headers);\n }\n },\n redirect(uri: string | URL, statusCode?: unknown) {\n const context = contextFn();\n return context.redirect(\n uri.toString(),\n (statusCode as RedirectStatusCode) ?? undefined,\n );\n },\n attachment(buffer: Buffer, filename: string, mimeType: string) {\n const context = contextFn();\n // https://github.com/honojs/hono/issues/3720\n return context.body(buffer as never, 200, {\n 'Content-Type': mimeType,\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\n 'Content-Length': buffer.length.toString(),\n });\n },\n badRequest(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 400, headers);\n },\n unauthorized(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 401, headers);\n },\n forbidden(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 403, headers);\n },\n notFound(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 404, headers);\n },\n notImplemented(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 501, headers);\n },\n accepted(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 202, headers);\n },\n conflict(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 409, headers);\n },\n unprocessableEntity(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 422, headers);\n },\n internalServerError(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 500, headers);\n },\n serviceUnavailable(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 503, headers);\n },\n };\n}\n\nexport const output = createOutput(() => getContext());\n", "/* eslint-disable no-unused-private-class-members */\nimport type { MiddlewareHandler, ValidationTargets } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { HTTPException } from 'hono/http-exception';\nimport z from 'zod';\n\ntype ValidatorConfig = Record<\n string,\n { select: unknown; against: z.ZodTypeAny }\n>;\n\ntype ExtractInput<T extends ValidatorConfig> = {\n [K in keyof T]: z.infer<T[K]['against']>;\n};\n\ntype HasUndefined<T> = undefined extends T ? true : false;\n\ntype InferTarget<\n T extends ValidatorConfig,\n S,\n Target extends keyof ValidationTargets,\n> = {\n [K in keyof T as T[K]['select'] extends S ? K : never]: HasUndefined<\n z.infer<T[K]['against']>\n > extends true\n ? z.infer<T[K]['against']> | undefined\n : z.infer<T[K]['against']> extends ValidationTargets[Target]\n ? z.infer<T[K]['against']>\n : z.infer<T[K]['against']>;\n};\n\ntype InferIn<T extends ValidatorConfig> = (keyof InferTarget<\n T,\n QuerySelect | QueriesSelect,\n 'query'\n> extends never\n ? never\n : { query: InferTarget<T, QuerySelect | QueriesSelect, 'query'> }) &\n (keyof InferTarget<T, BodySelect, 'json'> extends never\n ? never\n : { json: InferTarget<T, BodySelect, 'json'> }) &\n (keyof InferTarget<T, ParamsSelect, 'param'> extends never\n ? never\n : { param: InferTarget<T, ParamsSelect, 'param'> }) &\n (keyof InferTarget<T, HeadersSelect, 'header'> extends never\n ? never\n : { header: InferTarget<T, HeadersSelect, 'header'> }) &\n (keyof InferTarget<T, CookieSelect, 'cookie'> extends never\n ? never\n : { form: InferTarget<T, CookieSelect, 'cookie'> });\n\n// Marker classes\nclass BodySelect {\n #private = 0;\n}\nclass QuerySelect {\n #private = 0;\n}\nclass QueriesSelect {\n #private = 0;\n}\nclass ParamsSelect {\n #private = 0;\n}\nclass HeadersSelect {\n #private = 0;\n}\nclass CookieSelect {\n #private = 0;\n}\n\nexport const validate = <T extends ValidatorConfig>(\n selector: (payload: {\n body: Record<string, BodySelect>;\n query: Record<string, QuerySelect>;\n queries: Record<string, QueriesSelect>;\n params: Record<string, ParamsSelect>;\n headers: Record<string, HeadersSelect>;\n }) => T,\n): MiddlewareHandler<\n {\n Variables: {\n input: ExtractInput<T>;\n };\n },\n string,\n { in: InferIn<T> }\n> => {\n return createMiddleware<{\n Variables: {\n input: ExtractInput<T>;\n };\n }>(async (c, next) => {\n const contentType = c.req.header('content-type') ?? '';\n let body: unknown = null;\n\n switch (contentType) {\n case 'application/json':\n body = await c.req.json();\n break;\n case 'application/x-www-form-urlencoded':\n body = await c.req.parseBody();\n break;\n default:\n body = {};\n }\n\n const payload = {\n body,\n query: c.req.query(),\n queries: c.req.queries(),\n params: c.req.param(),\n headers: Object.fromEntries(\n Object.entries(c.req.header()).map(([k, v]) => [k, v ?? '']),\n ),\n };\n\n const config = selector(payload as never);\n const schema = z.object(\n Object.entries(config).reduce(\n (acc, [key, value]) => {\n acc[key] = value.against;\n return acc;\n },\n {} as Record<string, z.ZodTypeAny>,\n ),\n );\n\n const input = Object.entries(config).reduce(\n (acc, [key, value]) => {\n acc[key] = value.select;\n return acc;\n },\n {} as Record<string, unknown>,\n );\n\n const parsed = parse(schema, input);\n c.set('input', parsed as ExtractInput<T>);\n await next();\n });\n};\n\nexport function parse<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n input: unknown,\n) {\n const result = schema.safeParse(input);\n if (!result.success) {\n const error = new HTTPException(400, {\n message: 'Validation failed',\n cause: {\n code: 'api/validation-failed',\n detail: 'The input data is invalid',\n errors: result.error.flatten((issue) => ({\n message: issue.message,\n code: issue.code,\n fatel: issue.fatal,\n path: issue.path.join('.'),\n })).fieldErrors,\n },\n });\n throw error;\n }\n return result.data;\n}\n\nexport const openapi = validate;\n\nexport const consume = (\n contentType: 'application/json' | 'application/x-www-form-urlencoded',\n) => {\n return createMiddleware(async (context, next) => {\n const clientContentType = context.req.header('Content-Type');\n if (clientContentType !== contentType) {\n throw new HTTPException(415, {\n message: 'Unsupported Media Type',\n cause: {\n code: 'api/unsupported-media-type',\n detail: `Expected content type: ${contentType}, but got: ${clientContentType}`,\n },\n });\n }\n await next();\n });\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Context } from 'hono';\nimport { getContext } from 'hono/context-storage';\nimport type {\n ContentfulStatusCode,\n RedirectStatusCode,\n} from 'hono/utils/http-status';\n\ntype Data = any;\nfunction send(\n context: Context,\n value: Data | undefined | null,\n status: ContentfulStatusCode,\n headers?: Readonly<Record<string, string>>,\n) {\n if (value === undefined || value === null) {\n return context.body(null, status, headers);\n }\n const responseHeaders = { ...headers };\n responseHeaders['Content-Type'] ??= 'application/json';\n if (responseHeaders['Content-Type'].includes('application/json')) {\n return context.body(JSON.stringify(value), status, responseHeaders);\n }\n return context.body(value, status, responseHeaders);\n}\n\nexport function createOutput(contextFn: () => Context) {\n return {\n nocontent() {\n const context = contextFn();\n return context.body(null, 204, {});\n },\n ok(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 200, headers);\n },\n created(\n valueOrUri: string | Data,\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n if (typeof valueOrUri === 'string') {\n // If no content is provided, we send null\n return send(contextFn(), value, 201, {\n Location: valueOrUri,\n ...(headers || {}),\n });\n } else {\n // valueOrUri is the data\n return send(contextFn(), valueOrUri, 201, headers);\n }\n },\n redirect(uri: string | URL, statusCode?: unknown) {\n const context = contextFn();\n return context.redirect(\n uri.toString(),\n (statusCode as RedirectStatusCode) ?? undefined,\n );\n },\n attachment(buffer: Buffer, filename: string, mimeType: string) {\n const context = contextFn();\n // https://github.com/honojs/hono/issues/3720\n return context.body(buffer as never, 200, {\n 'Content-Type': mimeType,\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\n 'Content-Length': buffer.length.toString(),\n });\n },\n badRequest(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 400, headers);\n },\n unauthorized(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 401, headers);\n },\n forbidden(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 403, headers);\n },\n notFound(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 404, headers);\n },\n notImplemented(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 501, headers);\n },\n accepted(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 202, headers);\n },\n conflict(value: Data | undefined | null, headers?: Record<string, string>) {\n return send(contextFn(), value, 409, headers);\n },\n unprocessableEntity(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 422, headers);\n },\n internalServerError(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 500, headers);\n },\n serviceUnavailable(\n value: Data | undefined | null,\n headers?: Record<string, string>,\n ) {\n return send(contextFn(), value, 503, headers);\n },\n };\n}\n\nexport const output = createOutput(() => getContext());\n", "import { parse as parseContentType } from 'fast-content-type-parse';\nimport type { MiddlewareHandler, ValidationTargets } from 'hono';\nimport { createMiddleware } from 'hono/factory';\nimport { HTTPException } from 'hono/http-exception';\nimport z from 'zod';\n\ntype ContentType =\n | 'application/json'\n | 'application/x-www-form-urlencoded'\n | 'multipart/form-data'\n | 'text/plain';\n\ntype ValidatorConfig = Record<\n string,\n { select: unknown; against: z.ZodTypeAny }\n>;\n\ntype ExtractInput<T extends ValidatorConfig> = {\n [K in keyof T]: z.infer<T[K]['against']>;\n};\n\ntype HasUndefined<T> = undefined extends T ? true : false;\n\ntype InferTarget<\n T extends ValidatorConfig,\n S,\n Target extends keyof ValidationTargets,\n> = {\n [K in keyof T as T[K]['select'] extends S ? K : never]: HasUndefined<\n z.infer<T[K]['against']>\n > extends true\n ? z.infer<T[K]['against']> | undefined\n : z.infer<T[K]['against']> extends ValidationTargets[Target]\n ? z.infer<T[K]['against']>\n : z.infer<T[K]['against']>;\n};\n\ntype InferIn<T extends ValidatorConfig> = (keyof InferTarget<\n T,\n QuerySelect | QueriesSelect,\n 'query'\n> extends never\n ? never\n : { query: InferTarget<T, QuerySelect | QueriesSelect, 'query'> }) &\n (keyof InferTarget<T, BodySelect, 'json'> extends never\n ? never\n : { json: InferTarget<T, BodySelect, 'json'> }) &\n (keyof InferTarget<T, ParamsSelect, 'param'> extends never\n ? never\n : { param: InferTarget<T, ParamsSelect, 'param'> }) &\n (keyof InferTarget<T, HeadersSelect, 'header'> extends never\n ? never\n : { header: InferTarget<T, HeadersSelect, 'header'> }) &\n (keyof InferTarget<T, CookieSelect, 'cookie'> extends never\n ? never\n : { cookie: InferTarget<T, CookieSelect, 'cookie'> });\n\n// Marker classes\nclass BodySelect {\n #private = 0;\n}\nclass QuerySelect {\n #private = 0;\n}\nclass QueriesSelect {\n #private = 0;\n}\nclass ParamsSelect {\n #private = 0;\n}\nclass HeadersSelect {\n #private = 0;\n}\nclass CookieSelect {\n #private = 0;\n}\n\ntype SelectorFn<T> = (payload: {\n body: Record<string, BodySelect>;\n query: Record<string, QuerySelect>;\n queries: Record<string, QueriesSelect>;\n params: Record<string, ParamsSelect>;\n headers: Record<string, HeadersSelect>;\n}) => T;\ntype ValidateMiddleware<T extends ValidatorConfig> = MiddlewareHandler<\n {\n Variables: {\n input: ExtractInput<T>;\n };\n },\n string,\n { in: InferIn<T> }\n>;\n\nexport function validate<T extends ValidatorConfig>(\n selector: SelectorFn<T>,\n): ValidateMiddleware<T>;\nexport function validate<T extends ValidatorConfig>(\n expectedContentTypeOrSelector: ContentType,\n selector: SelectorFn<T>,\n): ValidateMiddleware<T>;\nexport function validate<T extends ValidatorConfig>(\n expectedContentTypeOrSelector: ContentType | SelectorFn<T>,\n selector?: SelectorFn<T>,\n): ValidateMiddleware<T> {\n const expectedContentType =\n typeof expectedContentTypeOrSelector === 'string'\n ? expectedContentTypeOrSelector\n : undefined;\n const _selector =\n typeof expectedContentTypeOrSelector === 'function'\n ? expectedContentTypeOrSelector\n : selector;\n if (!_selector) {\n throw new Error('Selector function is required');\n }\n\n return createMiddleware(async (c, next) => {\n const ct = c.req.header('content-type');\n if (expectedContentType) {\n verifyContentType(ct, expectedContentType);\n }\n\n const contentType = ct ? parseContentType(ct) : null;\n let body: unknown = null;\n\n switch (contentType?.type) {\n case 'application/json':\n body = await c.req.json();\n break;\n case 'application/x-www-form-urlencoded':\n case 'multipart/form-data':\n body = await c.req.parseBody();\n break;\n default:\n body = {};\n }\n\n const payload = {\n body,\n query: c.req.query(),\n queries: c.req.queries(),\n params: c.req.param(),\n headers: Object.fromEntries(\n Object.entries(c.req.header()).map(([k, v]) => [k, v ?? '']),\n ),\n };\n\n const config = _selector(payload as never);\n const schema = z.object(\n Object.entries(config).reduce(\n (acc, [key, value]) => {\n acc[key] = value.against;\n return acc;\n },\n {} as Record<string, z.ZodTypeAny>,\n ),\n );\n\n const input = Object.entries(config).reduce(\n (acc, [key, value]) => {\n acc[key] = value.select;\n return acc;\n },\n {} as Record<string, unknown>,\n );\n\n const parsed = parse(schema, input);\n c.set('input', parsed as ExtractInput<T>);\n await next();\n });\n}\n\nexport function parse<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n input: unknown,\n) {\n const result = schema.safeParse(input);\n if (!result.success) {\n const error = new HTTPException(400, {\n message: 'Validation failed',\n cause: {\n code: 'api/validation-failed',\n detail: 'The input data is invalid',\n errors: result.error.flatten((issue) => ({\n message: issue.message,\n code: issue.code,\n fatel: issue.fatal,\n path: issue.path.join('.'),\n })).fieldErrors,\n },\n });\n throw error;\n }\n return result.data;\n}\n\nexport const openapi = validate;\n\nexport const consume = (contentType: ContentType) => {\n return createMiddleware(async (context, next) => {\n verifyContentType(context.req.header('content-type'), contentType);\n await next();\n });\n};\n\nexport function verifyContentType(\n actual: string | undefined,\n expected: ContentType,\n): asserts actual is ContentType {\n if (!actual) {\n throw new HTTPException(415, {\n message: 'Unsupported Media Type',\n cause: {\n code: 'api/unsupported-media-type',\n details: 'Missing content type header',\n },\n });\n }\n const { type: incomingContentType } = parseContentType(actual);\n if (incomingContentType !== expected) {\n throw new HTTPException(415, {\n message: 'Unsupported Media Type',\n cause: {\n code: 'api/unsupported-media-type',\n details: `Expected content type: ${expected}, but got: ${incomingContentType}`,\n },\n });\n }\n}\n"],
5
+ "mappings": ";AACA,SAAS,kBAAkB;AAO3B,SAAS,KACP,SACA,OACA,QACA,SACA;AACA,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO,QAAQ,KAAK,MAAM,QAAQ,OAAO;AAAA,EAC3C;AACA,QAAM,kBAAkB,EAAE,GAAG,QAAQ;AACrC,kBAAgB,cAAc,MAAM;AACpC,MAAI,gBAAgB,cAAc,EAAE,SAAS,kBAAkB,GAAG;AAChE,WAAO,QAAQ,KAAK,KAAK,UAAU,KAAK,GAAG,QAAQ,eAAe;AAAA,EACpE;AACA,SAAO,QAAQ,KAAK,OAAO,QAAQ,eAAe;AACpD;AAEO,SAAS,aAAa,WAA0B;AACrD,SAAO;AAAA,IACL,YAAY;AACV,YAAM,UAAU,UAAU;AAC1B,aAAO,QAAQ,KAAK,MAAM,KAAK,CAAC,CAAC;AAAA,IACnC;AAAA,IACA,GAAG,OAAgC,SAAkC;AACnE,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,QACE,YACA,OACA,SACA;AACA,UAAI,OAAO,eAAe,UAAU;AAElC,eAAO,KAAK,UAAU,GAAG,OAAO,KAAK;AAAA,UACnC,UAAU;AAAA,UACV,GAAI,WAAW,CAAC;AAAA,QAClB,CAAC;AAAA,MACH,OAAO;AAEL,eAAO,KAAK,UAAU,GAAG,YAAY,KAAK,OAAO;AAAA,MACnD;AAAA,IACF;AAAA,IACA,SAAS,KAAmB,YAAsB;AAChD,YAAM,UAAU,UAAU;AAC1B,aAAO,QAAQ;AAAA,QACb,IAAI,SAAS;AAAA,QACZ,cAAqC;AAAA,MACxC;AAAA,IACF;AAAA,IACA,WAAW,QAAgB,UAAkB,UAAkB;AAC7D,YAAM,UAAU,UAAU;AAE1B,aAAO,QAAQ,KAAK,QAAiB,KAAK;AAAA,QACxC,gBAAgB;AAAA,QAChB,uBAAuB,yBAAyB,QAAQ;AAAA,QACxD,kBAAkB,OAAO,OAAO,SAAS;AAAA,MAC3C,CAAC;AAAA,IACH;AAAA,IACA,WACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,aACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,UACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,SAAS,OAAgC,SAAkC;AACzE,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,eACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,SAAS,OAAgC,SAAkC;AACzE,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,SAAS,OAAgC,SAAkC;AACzE,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,oBACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,oBACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,IACA,mBACE,OACA,SACA;AACA,aAAO,KAAK,UAAU,GAAG,OAAO,KAAK,OAAO;AAAA,IAC9C;AAAA,EACF;AACF;AAEO,IAAM,SAAS,aAAa,MAAM,WAAW,CAAC;;;ACxHrD,SAAS,SAAS,wBAAwB;AAE1C,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAC9B,OAAO,OAAO;AAiGP,SAAS,SACd,+BACA,UACuB;AACvB,QAAM,sBACJ,OAAO,kCAAkC,WACrC,gCACA;AACN,QAAM,YACJ,OAAO,kCAAkC,aACrC,gCACA;AACN,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAEA,SAAO,iBAAiB,OAAO,GAAG,SAAS;AACzC,UAAM,KAAK,EAAE,IAAI,OAAO,cAAc;AACtC,QAAI,qBAAqB;AACvB,wBAAkB,IAAI,mBAAmB;AAAA,IAC3C;AAEA,UAAM,cAAc,KAAK,iBAAiB,EAAE,IAAI;AAChD,QAAI,OAAgB;AAEpB,YAAQ,aAAa,MAAM;AAAA,MACzB,KAAK;AACH,eAAO,MAAM,EAAE,IAAI,KAAK;AACxB;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,eAAO,MAAM,EAAE,IAAI,UAAU;AAC7B;AAAA,MACF;AACE,eAAO,CAAC;AAAA,IACZ;AAEA,UAAM,UAAU;AAAA,MACd;AAAA,MACA,OAAO,EAAE,IAAI,MAAM;AAAA,MACnB,SAAS,EAAE,IAAI,QAAQ;AAAA,MACvB,QAAQ,EAAE,IAAI,MAAM;AAAA,MACpB,SAAS,OAAO;AAAA,QACd,OAAO,QAAQ,EAAE,IAAI,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,SAAS,UAAU,OAAgB;AACzC,UAAM,SAAS,EAAE;AAAA,MACf,OAAO,QAAQ,MAAM,EAAE;AAAA,QACrB,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACrB,cAAI,GAAG,IAAI,MAAM;AACjB,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO,QAAQ,MAAM,EAAE;AAAA,MACnC,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM;AACrB,YAAI,GAAG,IAAI,MAAM;AACjB,eAAO;AAAA,MACT;AAAA,MACA,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,MAAM,QAAQ,KAAK;AAClC,MAAE,IAAI,SAAS,MAAyB;AACxC,UAAM,KAAK;AAAA,EACb,CAAC;AACH;AAEO,SAAS,MACd,QACA,OACA;AACA,QAAM,SAAS,OAAO,UAAU,KAAK;AACrC,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,QAAQ,IAAI,cAAc,KAAK;AAAA,MACnC,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ,OAAO,MAAM,QAAQ,CAAC,WAAW;AAAA,UACvC,SAAS,MAAM;AAAA,UACf,MAAM,MAAM;AAAA,UACZ,OAAO,MAAM;AAAA,UACb,MAAM,MAAM,KAAK,KAAK,GAAG;AAAA,QAC3B,EAAE,EAAE;AAAA,MACN;AAAA,IACF,CAAC;AACD,UAAM;AAAA,EACR;AACA,SAAO,OAAO;AAChB;AAEO,IAAM,UAAU;AAEhB,IAAM,UAAU,CAAC,gBAA6B;AACnD,SAAO,iBAAiB,OAAO,SAAS,SAAS;AAC/C,sBAAkB,QAAQ,IAAI,OAAO,cAAc,GAAG,WAAW;AACjE,UAAM,KAAK;AAAA,EACb,CAAC;AACH;AAEO,SAAS,kBACd,QACA,UAC+B;AAC/B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,cAAc,KAAK;AAAA,MAC3B,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,EAAE,MAAM,oBAAoB,IAAI,iBAAiB,MAAM;AAC7D,MAAI,wBAAwB,UAAU;AACpC,UAAM,IAAI,cAAc,KAAK;AAAA,MAC3B,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,0BAA0B,QAAQ,cAAc,mBAAmB;AAAA,MAC9E;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import type { MiddlewareHandler, ValidationTargets } from 'hono';
2
2
  import z from 'zod';
3
+ type ContentType = 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain';
3
4
  type ValidatorConfig = Record<string, {
4
5
  select: unknown;
5
6
  against: z.ZodTypeAny;
@@ -20,7 +21,7 @@ type InferIn<T extends ValidatorConfig> = (keyof InferTarget<T, QuerySelect | Qu
20
21
  }) & (keyof InferTarget<T, HeadersSelect, 'header'> extends never ? never : {
21
22
  header: InferTarget<T, HeadersSelect, 'header'>;
22
23
  }) & (keyof InferTarget<T, CookieSelect, 'cookie'> extends never ? never : {
23
- form: InferTarget<T, CookieSelect, 'cookie'>;
24
+ cookie: InferTarget<T, CookieSelect, 'cookie'>;
24
25
  });
25
26
  declare class BodySelect {
26
27
  #private;
@@ -40,33 +41,25 @@ declare class HeadersSelect {
40
41
  declare class CookieSelect {
41
42
  #private;
42
43
  }
43
- export declare const validate: <T extends ValidatorConfig>(selector: (payload: {
44
+ type SelectorFn<T> = (payload: {
44
45
  body: Record<string, BodySelect>;
45
46
  query: Record<string, QuerySelect>;
46
47
  queries: Record<string, QueriesSelect>;
47
48
  params: Record<string, ParamsSelect>;
48
49
  headers: Record<string, HeadersSelect>;
49
- }) => T) => MiddlewareHandler<{
50
+ }) => T;
51
+ type ValidateMiddleware<T extends ValidatorConfig> = MiddlewareHandler<{
50
52
  Variables: {
51
53
  input: ExtractInput<T>;
52
54
  };
53
55
  }, string, {
54
56
  in: InferIn<T>;
55
57
  }>;
58
+ export declare function validate<T extends ValidatorConfig>(selector: SelectorFn<T>): ValidateMiddleware<T>;
59
+ export declare function validate<T extends ValidatorConfig>(expectedContentTypeOrSelector: ContentType, selector: SelectorFn<T>): ValidateMiddleware<T>;
56
60
  export declare function parse<T extends z.ZodRawShape>(schema: z.ZodObject<T>, input: unknown): z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any>[k]; } : never;
57
- export declare const openapi: <T extends ValidatorConfig>(selector: (payload: {
58
- body: Record<string, BodySelect>;
59
- query: Record<string, QuerySelect>;
60
- queries: Record<string, QueriesSelect>;
61
- params: Record<string, ParamsSelect>;
62
- headers: Record<string, HeadersSelect>;
63
- }) => T) => MiddlewareHandler<{
64
- Variables: {
65
- input: ExtractInput<T>;
66
- };
67
- }, string, {
68
- in: InferIn<T>;
69
- }>;
70
- export declare const consume: (contentType: "application/json" | "application/x-www-form-urlencoded") => MiddlewareHandler<any, string, {}>;
61
+ export declare const openapi: typeof validate;
62
+ export declare const consume: (contentType: ContentType) => MiddlewareHandler<any, string, {}>;
63
+ export declare function verifyContentType(actual: string | undefined, expected: ContentType): asserts actual is ContentType;
71
64
  export {};
72
65
  //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/lib/runtime/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAGjE,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,KAAK,WAAW,GACZ,kBAAkB,GAClB,mCAAmC,GACnC,qBAAqB,GACrB,YAAY,CAAC;AAEjB,KAAK,eAAe,GAAG,MAAM,CAC3B,MAAM,EACN;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAA;CAAE,CAC3C,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,SAAS,eAAe,IAAI;KAC5C,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CACzC,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAE1D,KAAK,WAAW,CACd,CAAC,SAAS,eAAe,EACzB,CAAC,EACD,MAAM,SAAS,MAAM,iBAAiB,IACpC;KACD,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,YAAY,CAClE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CACzB,SAAS,IAAI,GACV,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,GACpC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,iBAAiB,CAAC,MAAM,CAAC,GACxD,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GACxB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;CAC/B,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,SAAS,eAAe,IAAI,CAAC,MAAM,WAAW,CAC1D,CAAC,EACD,WAAW,GAAG,aAAa,EAC3B,OAAO,CACR,SAAS,KAAK,GACX,KAAK,GACL;IAAE,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,aAAa,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAClE,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,KAAK,GACnD,KAAK,GACL;IAAE,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,GACjD,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,KAAK,GACtD,KAAK,GACL;IAAE,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GACrD,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,SAAS,KAAK,GACxD,KAAK,GACL;IAAE,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAA;CAAE,CAAC,GACxD,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,SAAS,KAAK,GACvD,KAAK,GACL;IAAE,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAA;CAAE,CAAC,CAAC;AAG1D,cAAM,UAAU;;CAEf;AACD,cAAM,WAAW;;CAEhB;AACD,cAAM,aAAa;;CAElB;AACD,cAAM,YAAY;;CAEjB;AACD,cAAM,aAAa;;CAElB;AACD,cAAM,YAAY;;CAEjB;AAED,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACxC,KAAK,CAAC,CAAC;AACR,KAAK,kBAAkB,CAAC,CAAC,SAAS,eAAe,IAAI,iBAAiB,CACpE;IACE,SAAS,EAAE;QACT,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;KACxB,CAAC;CACH,EACD,MAAM,EACN;IAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,CACnB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,CAAC,SAAS,eAAe,EAChD,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACzB,wBAAgB,QAAQ,CAAC,CAAC,SAAS,eAAe,EAChD,6BAA6B,EAAE,WAAW,EAC1C,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAyEzB,wBAAgB,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAC3C,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,KAAK,EAAE,OAAO,qLAoBf;AAED,eAAO,MAAM,OAAO,iBAAW,CAAC;AAEhC,eAAO,MAAM,OAAO,GAAI,aAAa,WAAW,uCAK/C,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,IAAI,WAAW,CAoB/B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/hono",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -26,10 +26,13 @@
26
26
  "!**/*.tsbuildinfo"
27
27
  ],
28
28
  "dependencies": {
29
- "@sdk-it/core": "0.15.0",
29
+ "@sdk-it/core": "0.17.0",
30
30
  "hono": "^4.7.4",
31
- "typescript": "^5.7.2",
32
- "zod": "^3.24.2"
31
+ "zod": "^3.24.2",
32
+ "fast-content-type-parse": "^3.0.0"
33
+ },
34
+ "peerDependencies": {
35
+ "typescript": "^5.8.3"
33
36
  },
34
37
  "devDependencies": {
35
38
  "@types/debug": "^4.1.12"