I'm developing a NestJS application and using the nestjs-zod library for validation and swagger documentation. However, I'm facing an issue when trying to upload files in a multipart form-data request.
The problem is that zod, which I use for validation, doesn't have a specific File type, and Swagger doesn't recognize it as a file input because it lacks the @ApiProperty({ format: 'binary' }) decoration. I'm looking for a solution to properly document and validate multipart file uploads using zod And in the same time I want to keep up using my Dtos that i am doing
dto.ts
import { createZodDto } from 'nestjs-zod/dto';
import * as z from 'nestjs-zod/z';
export const schema = z.object({
field: z.string().optional(),
requiredFile: z
.string()
.refine((str: any): str is Buffer => Buffer.isBuffer(Buffer.from(str))),
optionalFile: z
.string()
.refine((str: any): str is Buffer => Buffer.isBuffer(Buffer.from(str)))
.optional(),
});
export class Dto extends createZodDto(schema) {}
controller.ts
@Post()
@UseInterceptors(
FileFieldsInterceptor(
[{ name: 'requiredFile' }, { name: 'optionalFile' }],
multerLimits,
),
)
@ApiConsumes('multipart/form-data')
async create(
@Body() dto: CreateStoreDto,
@UploadedFiles()
files,
) {
// Handle the request...
}
I tried also using zod-to-openapi
package but nothing changed!
dto2.ts
import { createZodDto } from 'nestjs-zod/dto';
import { z as z2 } from 'nestjs-zod/z';
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
extendZodWithOpenApi(z2);
export const schema = z2.object({
optionalFile: z2
.custom<Express.Multer.File>()
.openapi({ format: 'binary', type: 'string' }),
requiredFile: z2
.string()
.refine((str: any): str is Buffer => Buffer.isBuffer(Buffer.from(str)))
.openapi({ type: 'string', format: 'binary' }),
});
export class Dto extends createZodDto(schema) {}
I also tried
file3: z2.string().openapi({ type: 'string', format: 'binary' }),
but that didnt work also
Here is the github repo you can fork and try to PR to fix the issue: https://github.com/mohrazzak/nodejs