I'm using NestJS 10. I want to create a file upload endpoint that only accepts image file uploads. I created
@Post()
@UseInterceptors(
FileFieldsInterceptor([
{ name: 'frontImg', maxCount: 1 },
{ name: 'backImg', maxCount: 1 },
]),
)
async create(
@Req() req: Request,
@Body('title') title: string,
@Body('frontImgAltText') frontImgAltText: string,
@Body('category') category: Occasion,
@UploadedFiles(
new ParseFilePipe({
validators: [
new FileTypeValidator({ fileType: /(jpg|jpeg|png|webp)$/ }),
],
}),
)
files: { frontImg: Express.Multer.File[]; backImg?: Express.Multer.File[] },
) { ... }
but when I execute a request against the endpoint, it consistently fails with the error
{
"message": "Validation failed (expected type is /(jpg|jpeg|png|webp)$/)",
"error": "Bad Request",
"statusCode": 400
}
What's the proper way to create a validator that only accepts certain image file types?
The issue here is that when isValid
method from the built-in FileTypeValidator
is called it gets an object with the two fields frontImg
and backImg
: and it makes sense since
files
is defined like that here:
files: { frontImg: Express.Multer.File[]; backImg?: Express.Multer.File[] }
and it doesn't have any mimetype whatsoever.
I think one way to work around this can be to create a small pipe that forwards every file to FileTypeValidator
like this:
@UseInterceptors(
FileFieldsInterceptor([
{ name: 'frontImg', maxCount: 1 },
{ name: 'backImg', maxCount: 1 },
]),
)
async uploadTest(
@UploadedFiles({
transform: (fileRequest: {
frontImg: Express.Multer.File[];
backImg?: Express.Multer.File[];
}) => {
const validator = new FileTypeValidator({
fileType: /(jpg|jpeg|png|webp)$/,
});
if (
validator.isValid(fileRequest.frontImg[0]) &&
validator.isValid(fileRequest.backImg[0])
) {
return fileRequest;
}
throw new HttpException(validator.buildErrorMessage(), 400);
},
})
files: {
frontImg: Express.Multer.File[];
backImg?: Express.Multer.File[];
},
) {
console.log(files);
}