nestjs-form-data
nestjs-form-data copied to clipboard
In version 1.8.3 mimetype is undefined
I'm trying to upload a video using such a structure
export class VideoUploadData {
@IsFile()
@MaxFileSize(10 * 1024 * 1204)
@ApiProperty()
file: MemoryStoredFile;
@ApiProperty()
fieldName: string;
}
In version 1.7.1
file.mimetype contained a mime type of video, But in version 1.8.3 it is undefined. I see busBoyMimeType property but it is protected
In version 1.8.3, the mime-type logic was changed, but new getters were added to support older versions. Please post a log of the uploaded file from your dto, and make sure you use the class-transformer in your module
Check StoredFile source for details
Now I have issue with validating mimetypes for svg. This is upload data
@IsFile()
@MaxFileSize(5 * 1024 * 1024)
@HasMimeType(['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml'])
@ApiProperty()
file: MemoryStoredFile;
@ApiProperty()
blockConfigId?: string;
@ApiProperty()
blockName?: string;
@ApiProperty()
fieldName: string;
@ApiProperty()
subdir?: string;
}```
Controller
@ApiTags('Files') @Post('sites/:siteId/uploadImage') @FormDataRequest() async uploadImage( @Param('siteId') siteId: string, @Body() imageData: ImageUploadData, @CurrentUser() user: User, ): Promise<ImageConfigData> {
And I got folowing error when I upload svg file
```[
ValidationError {
target: ImageUploadData {
fieldName: 'items.1.image',
blockConfigId: '623ad511a119d8e1e26b5419',
blockName: 'Banner on Home Page',
file: [MemoryStoredFile]
},
value: MemoryStoredFile {
originalName: 'logoQwHvA.svg',
encoding: '7bit',
busBoyMimeType: 'image/svg+xml',
buffer: <Buffer 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 20 73 74 61 6e 64 61 6c 6f 6e 65 3d 22 6e ... 11515 more bytes>,
size: 11565,
fileType: [Object]
},
property: 'file',
children: [],
constraints: {
HasMimeType: 'File must be of one of the types image/jpeg, image/png, image/webp, image/svg+xml'
}
}
]```
When I upload jpg or png file everything is ok
Issue is in file-type dependency. It is not reliable source of mime type. It replaces correct with possible but wrong.
Also On the latest nest.js it seems that all geberated properties are omited then I use decorator Body(). So I have no mimeType property at all
@salos1982 Hi! file-type library which is used to determine mime-type is not suitable for text-based file formats, as it requires parsing the file.
From the file-type readme:
This package is for detecting binary-based file formats, not text-based formats like .txt, .csv, .svg, etc.
You can use @HasExtension to check by file extension or write your own validator, e.g. based on https://www.npmjs.com/package/is-svg.
I had the same issue and debugged my code. It turned out that my DTO was not an instance of the DTO class. Instead, it was a plain JS object. That's the reason the getters of the StoredFile class were missing because getters get not serialized.
To solve my issue, I had to transform the payload objects:
@UsePipes(new ValidationPipe({ transform: true }))
Now my DTOs are class instances and the StoredFile is also an instance with all the getters available.