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';

Here, we use jpeg instead of jpg because the comparison is made with the Media Type, which is the extension's complete name. Due to this, the short form would not work.

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

Import it while adding * as.

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