Factory function for file validators
A more encapsulated way to instantiate file validators.
Let's then continue this structure in src/files. There, first we'll create the file util/file-validation.util, where we'll define a type for the allowed file types.
type FileType = 'png' | 'jpeg' | 'pdf';
Now, let's create a factory function that returns the two validators, so that we don't need to manually instantiate them. The function will have, as parameters, the maxSize
and the fileTypes
, and then returns the two validators. Therefore, this will be its signature:
export const createFileValidators = (
maxSize: number,
...fileTypes: NonEmptyArray<FileType>
): FileValidator[] => {};
Let's then create the fileTypeRegex
from the received fileTypes
.
const fileTypeRegex = new RegExp(fileTypes.join('|'));
Then, return the two validators.
return [
new MaxFileSizeValidator({ maxSize }),
new FileTypeValidator({ fileType: fileTypeRegex }),
];
There is still a problem: the maxSize
in bytes. To fix this, we can use the bytes library, which is already installed. We just need to install its typing.
yarn add -D @types/bytes
What's left to do is to change the type of the maxSize
parameter to string, and then use the bytes library to transform this string to a value in bytes when instantiating the first validator.
new MaxFileSizeValidator({ maxSize: bytes(maxSize) }),
And, a last improvement we could make, is to create the template literal type FileSize
. With it, we can enforce that the maxSize
should be a string containing a number followed by either KB, MB or GB. We can also create a type to represent these magnitudes.
type FileSizeMagnitude = 'KB' | 'MB' | 'GB';
type FileSize = `${number}${FileSizeMagnitude}`;
Back in the route, our validators
can now be created like this:
validators: createFileValidators('2MB', 'png', 'jpeg')
Commit - Using factory function to create file validators
Last updated