Open tsutoringo opened 5 days ago
import { OpenAPIRegistry, OpenApiGeneratorV3, extendZodWithOpenApi } from 'npm:@asteasolutions/zod-to-openapi'; import { z } from 'npm:zod'; extendZodWithOpenApi(z); const registry = new OpenAPIRegistry(); const NewFile = z .object({ description: z.string().openapi({}), file_1: z.custom((target) => target instanceof File).openapi({ type: 'string', format: 'binary' }), file_2: z.instanceof(File).openapi({ type: 'string', format: 'binary' }), }) .openapi('NewFile'); registry.registerPath({ method: 'post', path: '/', request: { body: { content: { "multipart/form-data": { schema: NewFile } } } }, responses: { 200: { description: 'Success.', }, } }); const generator = new OpenApiGeneratorV3(registry.definitions); const docs = generator.generateDocument({ openapi: '3.0.0', info: { version: '1.0.0', title: 'My API', description: 'This is the API', }, servers: [{ url: 'v1' }], }); console.log(JSON.stringify(docs, null, ' '));
result
{ "openapi": "3.0.0", "info": { "version": "1.0.0", "title": "My API", "description": "This is the API" }, "servers": [ { "url": "v1" } ], "components": { "schemas": { "NewFile": { "type": "object", "properties": { "description": { "type": "string" }, "file_1": { "type": "string", "format": "binary" }, "file_2": { "type": "string", "format": "binary" } }, "required": [ // expects `"description", "file_1", "file_2"` "description" ] } }, "parameters": {} }, "paths": { "/": { "post": { "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewFile" } } } }, "responses": { "200": { "description": "Success." } } } } } }
Actually file_1 and file_2 are required, so this code returns an error
const result = NewFile.safeParse({ description: 'description', file_1: new File([], 'file_1'), // file_2: new File([], 'file_2') }); console.log(result); // { success: false, error: ... }
I've looked into it myself, and the cause is probably that zod.custom and zod.instanceof are wrapped in zod.any with ZodEffect, and I think this code is doing something bad. https://github.com/asteasolutions/zod-to-openapi/blob/81f003daa97c3e4baf06adf2e37183e575317c41/src/openapi-generator.ts#L326-L327
zod.custom
zod.instanceof
zod.any
Reproduce code
result
Actually file_1 and file_2 are required, so this code returns an error
I've looked into it myself, and the cause is probably that
zod.custom
andzod.instanceof
are wrapped inzod.any
with ZodEffect, and I think this code is doing something bad. https://github.com/asteasolutions/zod-to-openapi/blob/81f003daa97c3e4baf06adf2e37183e575317c41/src/openapi-generator.ts#L326-L327