express-image-validator
is a TypeScript library for validating received images in Express applications.
Uses req.files
provided by express-fileupload.
$ npm install express-image-validator
When you upload an image, you often have to perform some checks on the files to get the expected result. For example, this includes validating MIME types, sizes, or whether files must be uploaded.
The API provides 3 middleware for image validation. Let's talk about each of them.
isImage
allows you to perform basic verification of an uploaded files:
- Using MIME type verification, reject files that are not images.
- Specify a limit on the number of images.
- Specify that at least one file should be uploaded.
It accepts 2 parameters:
field: string | string[]
– name or array of names of fields for validationoptions?: IsImageOptions
– optional partial ValidationOptions object consisting of:required: boolean
.limit: number
.allowedMimeTypes: ImageMimeTypes
.
Example:
const { Router } = require('express');
const { isImage } = require('express-image-validator');
const router = Router();
const schema = isImage('avatar', {
required: true,
limit: 1,
});
router.post('/upload', schema, (req, res) => {
res.send('Nice picture!');
});
This code snippet validates that the user is sure to upload only one image in the avatar
field.
If you need to check multiple fields at once, just list them in the array:
const schema = isImage(['avatar', 'banner'], {
required: true,
limit: 1,
});
router.post('/upload', schema, (req, res) => {
res.send('Nice pictures!');
});
In this case, the specified validation options will be applied for req.files.avatar
and req.files.banner
.
If you only need to check one field, but you need more options, use validateImageSingle
.
It accepts 2 parameters:
field: string
– name of field for validation.options?: ValidationOptions
– optional ValidationOptions object.
Example:
const { Router } = require('express');
const { validateImageSingle } = require('express-image-validator');
const router = Router();
const schema = validateImageSingle('avatar', {
required: true,
limit: 1,
maxSize: 10,
aspectRatio: 1,
});
router.post('/upload', schema, (req, res) => {
res.send('Nice picture!');
});
This code snippet validates that the user sent a single square image of no more than 10 megabytes in size.
If you need to validate multiple fields with different options using a single middleware, use `validateImage'.
This function accepts a single parameter field: FieldSet
, combining the field
and options
from the previous functions. FieldSet is either a string with a field name or FieldSchema, or an array of strings with a field name or FieldSchemas
.
If the parameter contains a string, it is transformed into an instance of FieldSchema
with the default options object.
Example:
const { Router } = require('express');
const { validateImage } = require('express-image-validator');
const router = Router();
const schema = validateImage([
'avatar',
{
name: 'banner',
options: {
limit: 1,
aspectRatio: 16 / 9,
},
},
]);
router.post('/upload', schema, (req, res) => {
res.send('Nice picture!');
});
This array for the validator will be transformed into something like:
[
{
name: 'avatar',
options: {
limit: null,
minSize: 0,
maxSize: null,
required: false,
aspectRatio: null,
allowedMimeTypes: ['...'],
},
},
{
name: 'banner',
options: {
limit: 1,
minSize: 0,
maxSize: null,
required: true,
aspectRatio: 1.77777777778,
allowedMimeTypes: ['...'],
},
},
];
You can also specify one field for validation, for example:
const schema = validateImage({
name: 'avatar',
options: {
required: true,
limit: 1,
},
});
Validators do not report validation errors to users automatically. Instead, it is suggested to manually handle errors using the imageValidationResult
function.
const { isImage, imageValidationResult } = require('express-image-validator');
router.post('/upload', isImage('avatar', { required: true }), (req, res) => {
const result = imageValidationResult(req);
if (!result.isEmpty()) {
return res.status(200).json({ errors: result.array() });
}
return res.status(400);
});
Now, if the avatar
image is not received on the POST /upload
, we will get:
{
"errors": [
{
"field": "avatar",
"msg": "Missing required field",
"value": true,
"filename": null
}
]
}
imageValidationResult(req: Request): ValidationState
Extracts the validation results from a request, wraps them in a ValidationState object, and returns it.
The result object is a wrapper around the validation state of a request. It provides a couple of methods that you can use to determine if the request is valid or not.
isEmpty(): boolean
Returns whether the request contains validation errors, and therefore whether it's valid or not.
array(options?: { onlyFirstError?: boolean }): ValidationError[]
Returns a list of all errors from all validated fields.
const result = imageValidationResult(req).array();
// => [{ msg: 'Invalid file', field: 'field1' }, { msg: 'Invalid file', field: 'field1' }]
When options.onlyFirstError
is set to true
, then only the first error of each field is returned:
const result = imageValidationResult(req).array({ onlyFirstError: true });
// => [{ msg: 'Invalid file', field: 'field1' }]
mapped(): Record<string, ValidationError>
Returns an object from field path to error. If a field has multiple errors, only the first one is returned.
const result = imageValidationResult(req).mapped();
// => { field1: { msg: 'Invalid value', ... }, field2: { msg: 'Invalid value', ... } }
throw(): void
If the result object has errors, then this method throws an error decorated with the same methods as the ValidationState
type.
This is useful if you wish to forward the errors to the error handler middleware of your Express.js application, for example.
If the result object has no errors, then this method does nothing.
const { isImage, imageValidationResult } = require('express-image-validator');
router.post('/upload', isImage('avatar', { required: true }), (req, res) => {
try {
imageValidationResult(req).throw();
res.send('Nice picture!');
} catch (e) {
res.status(400).send({ errors: e.mapped() });
}
});
The object of the image validation parameters. It can be specified empty in middleware, but it is always filled in with default values or user values as a result of the internal work of validators.
-
limit: number | null
– maximum number of files in one field.null
means that the number of files is unlimited. -
minSize: number
– minimum file size, specified in megabytes (Inside it is translated into bytes). -
maxSize: number | null
– maximum file size, specified in megabytes (Inside it is translated into bytes).null
means that the maximum file size is unlimited. -
required: boolean
– specify that at least one file should be uploaded. -
aspectRatio: number | null
– required aspect ratio of the image with a tolerance of 5%.null
means that the aspect ratio is not important. -
allowedMimeTypes: ImageMimeTypes
– array of allowed MIME image types.null
means that all MIME types are allowed.
By default:
{
limit: null,
minSize: 0,
maxSize: null,
required: false,
aspectRatio: null,
allowedMimeTypes: null,
}
An object of validation options for one specified field. Contains 2 properties:
name: string
– name of field for validation.options: ValidationOptions
– instance of the ValidationOptions object.
A composite type that describes a set of fields and validation parameters for them, allowing the following data types:
Field: string | FieldSchema
– the name of field to validate or the FieldSchema object.Field[]
– an array containing both strings of field names and FieldSchema objects.
Validators receive this value as an array FieldSchema[]
, so you can safely use any of the valid data types in your configuration.
isImage(field: string | string[], options?: { limit?: number | null, required?: boolean, allowedMimeTypes: ImageMimeTypes | null }): RequestHandler
isImage
allows you to perform basic verification of an uploaded files:
- Using MIME type verification, reject files that are not images.
- Specify a limit on the number of images.
- Specify that at least one file should be uploaded.
validateImageSingle(field: string, options?: ValidationOptions): RequestHandler
see Advanced image validation with validateImageSingle
validateImage(field: FieldSet): RequestHandler
see Advanced image validation of multiple image fields with validateImage
Common aspect ratios for images.
const AspectRatios: Record<string, number> = {
LANDSCAPE_16_9: 16 / 9,
LANDSCAPE_16_10: 16 / 10,
LANDSCAPE_4_3: 4 / 3,
LANDSCAPE_3_2: 3 / 2,
LANDSCAPE_5_3: 5 / 3,
PORTRAIT_9_16: 9 / 16,
PORTRAIT_10_16: 10 / 16,
PORTRAIT_2_3: 2 / 3,
PORTRAIT_3_5: 3 / 5,
SQUARE_1_1: 1 / 1,
CINEMA_21_9: 21 / 9,
};
A supported MIME type for image files.
type ImageMimeType =
| 'image/jpeg'
| 'image/png'
| 'image/gif'
| 'image/webp'
| 'image/bmp'
| 'image/tiff'
| 'image/svg+xml'
| 'image/avif';
Non-empty array of supported image MIME types.
type ImageMimeTypes = [ImageMimeType, ...ImageMimeType[]];
This work is licensed under the MIT License (see the LICENSE file).