Socket
Socket
Sign inDemoInstall

express-json-validator-middleware

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-json-validator-middleware - npm Package Compare versions

Comparing version 2.1.1 to 2.2.0

.editorconfig

0

.prettierrc.json

@@ -0,0 +0,0 @@ {

25

package.json
{
"name": "express-json-validator-middleware",
"version": "2.1.1",
"version": "2.2.0",
"description": "An Express middleware to validate requests against JSON Schemas",
"main": "src/index.js",
"author": "Josef Vacek",
"author": "Simon Plenderleith",
"license": "MIT",

@@ -17,10 +17,10 @@ "keywords": [

"type": "git",
"url": "git+https://github.com/JouzaLoL/express-json-validator-middleware.git"
"url": "git+https://github.com/simonplend/express-json-validator-middleware.git"
},
"bugs": {
"url": "https://github.com/JouzaLoL/express-json-validator-middleware/issues"
"url": "https://github.com/simonplend/express-json-validator-middleware/issues"
},
"homepage": "https://github.com/JouzaLoL/express-json-validator-middleware#readme",
"homepage": "https://github.com/simonplend/express-json-validator-middleware#readme",
"scripts": {
"test": "mocha",
"test": "tap",
"lint": "eslint \"src/*.js\" --fix",

@@ -35,5 +35,3 @@ "prepush": "npm run lint && npm run test",

"devDependencies": {
"body-parser": "^1.18.3",
"chai": "^3.5.0",
"chai-http": "^4.2.1",
"codecov": "^3.8.1",
"eslint": "^6.8.0",

@@ -45,10 +43,11 @@ "eslint-config-google": "^0.9.1",

"mocha": "^7.1.1",
"nyc": "^15.0.0",
"prettier": "^1.19.1"
"prettier": "^1.19.1",
"simple-get": "^4.0.0",
"tap": "^15.0.1"
},
"dependencies": {
"ajv": "^6.6.2",
"@types/express": "^4.17.3",
"@types/express-serve-static-core": "^4.17.2",
"@types/json-schema": "^7.0.4",
"@types/express-serve-static-core": "^4.17.2"
"ajv": "^6.6.2"
},

@@ -55,0 +54,0 @@ "husky": {

@@ -1,30 +0,16 @@

# express-json-validator-middleware
[express.js](https://github.com/visionmedia/express) middleware for validating requests against JSON Schema
# Express JSON Validator Middleware
<a href="https://www.patreon.com/bePatron?u=19773095" data-patreon-widget-type="become-patron-button"><img src="patreon.png"></img></a>
[![Build Status](https://travis-ci.org/JouzaLoL/express-json-validator-middleware.svg?branch=master)](https://travis-ci.org/JouzaLoL/express-json-validator-middleware)
[![codecov](https://codecov.io/gh/JouzaLoL/express-json-validator-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/JouzaLoL/express-json-validator-middleware)
[![npm](https://img.shields.io/npm/dm/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
[![npm](https://img.shields.io/npm/v/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
[![npm](https://img.shields.io/npm/l/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
> [Express](https://github.com/expressjs/express/) middleware for validating
requests against JSON schemas.
<hr>
[![npm version](https://img.shields.io/npm/v/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
[![npm monthly downloads](https://img.shields.io/npm/dm/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
[![npm license](https://img.shields.io/npm/l/express-json-validator-middleware.svg)](https://www.npmjs.com/package/express-json-validator-middleware)
[![Build status](https://github.com/vacekj/express-json-validator-middleware/workflows/Node.js%20CI/badge.svg)](https://github.com/vacekj/express-json-validator-middleware/actions?query=workflow%3A%22Node.js+CI%22)
[![codecov](https://codecov.io/gh/vacekj/express-json-validator-middleware/branch/master/graph/badge.svg)](https://codecov.io/gh/vacekj/express-json-validator-middleware)
Coming from `express-jsonschema`? Read our [migration notes](#migrating)
Major version `1.x` of this module uses `ajv@5`, read their changelog and migration guide [here](https://github.com/epoberezkin/ajv/releases/tag/5.0.0).
Major version `2.x` uses `ajv@6` in order to support draft-07 of JSON Schema.
Please keep in mind that you have to manually configure ajv to support **draft-06** schema files from now on (see https://github.com/epoberezkin/ajv#using-version-6).
## Why use this library over [express-jsonschema](https://github.com/trainiac/express-jsonschema) ?
- **Performance** - [ajv](https://github.com/epoberezkin/ajv) offers a [significant performance boost over](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance) JSONSchema.
- **Latest JSON Schema Standard** - [ajv](https://github.com/epoberezkin/ajv) supports JSON Schema v7 proposal.
- **Active Maintenance** - `express-json-validator-middleware` is being actively maintained.
## Why validate with JSON schemas?
- **Simple** - JSON schemas are a simple and expressive way to describe a data structure.
- **Standard** - JSON schemas are not specific to Javascript. In fact, they are used just about everywhere.
- **Standard** - JSON schemas are not specific to JavaScript. In fact, they are used just about everywhere.
- **Fail-Fast** - Catch errors early in your logic, evading confusing errors later.

@@ -35,53 +21,87 @@ - **Separate Validation** - Keep your routes clean. Validation logic doesn't need to be defined in your route handlers.

## Installation
## Install
```sh
$ npm install express-json-validator-middleware
npm install express-json-validator-middleware
```
`--save` is no longer necessary as of `npm@5`
## Getting started
1. Require the module
```js
var { Validator, ValidationError } = require('express-json-validator-middleware');
```
```javascript
import { Validator } from "express-json-validator-middleware";
2. Initialize a Validator instance, optionally passing in an [ajv#options](https://github.com/epoberezkin/ajv#options) object
/**
* Define a JSON schema.
*/
const addressSchema = {
type: "object",
required: ["street"],
properties: {
street: {
type: "string",
}
},
};
```js
var validator = new Validator({allErrors: true});
```
/**
* Initialize a `Validator` instance, optionally passing in
* an Ajv options object.
*
* @see https://github.com/ajv-validator/ajv/tree/v6#options
*/
const { validate } = new Validator();
3. *Optional* - Define a bound shortcut function that can be used instead of Validator.validate
```js
var validate = validator.validate;
/**
* The `validate` method accepts an object which maps request
* properties to the JSON schema you want them to be validated
* against e.g.
*
* { requestPropertyToValidate: jsonSchemaObject }
*
* Validate `request.body` against `addressSchema`.
*/
app.post("/address", validate({ body: addressSchema }), (request, response) => {
/**
* Route handler logic to run when `request.body` has been validated.
*/
response.send({});
});
```
4. Use the Validator.validate method as an Express middleware, passing in an options object of the following format:
```js
Validator.validate({
requestProperty: schemaToUse
})
```
Coming from `express-jsonschema`? Read the [migration notes](docs/migrating-from-express-jsonschema.md).
Example: Validate `req.body` against `bodySchema`
### Schemas in TypeScript
```js
app.post('/street/', validate({body: bodySchema}), function(req, res) {
// route code
});
If you are writing JSON schemas in TypeScript, you will need to cast your schema
to the `const` type e.g.
```typescript
const addressSchema = {
type: "object",
required: ["street"],
properties: {
street: {
type: "string",
}
},
} as const;
```
This is required so that TypeScript doesn't attempt to widen the types of values
in the schema object. If you omit the `as const` statement TypeScript will raise
a compilation error. The discussion in
[this issue](https://github.com/simonplend/express-json-validator-middleware/issues/39)
provides further background.
## Error handling
On encountering erroneous data, the validator will call next() with a ValidationError object.
It is recommended to setup a general error handler for your app where you will catch ValidationError errors
On encountering invalid data, the validator will call `next()` with a
`ValidationError` object. It is recommended to setup a general error handler
for your app where you handle `ValidationError` errors.
Example - error thrown for the `body` request property
Example - error thrown for the `body` request property:
```js
```javascript
ValidationError {
name: 'JsonSchemaValidationError',
name: "JsonSchemaValidationError",
validationErrors: {

@@ -93,58 +113,60 @@ body: [AjvError]

More information on [ajv#errors](https://github.com/epoberezkin/ajv#validation-errors)
More information on [Ajv errors](https://github.com/ajv-validator/ajv/tree/v6#validation-errors).
## Example Express app
## Example Express application
```js
var express = require('express');
var bodyParser = require('body-parser');
```javascript
import express from "express";
var { Validator, ValidationError } = require('express-json-validator-middleware');
import { Validator, ValidationError } from "express-json-validator-middleware";
const app = express();
// Initialize a Validator instance first
var validator = new Validator({allErrors: true}); // pass in options to the Ajv instance
app.use(express.json());
// Define a shortcut function
var validate = validator.validate;
const addressSchema = {
type: "object",
required: ["number", "street", "type"],
properties: {
number: {
type: "number",
},
street: {
type: "string",
},
type: {
type: "string",
enum: ["Street", "Avenue", "Boulevard"],
},
},
};
// Define a JSON Schema
var StreetSchema = {
type: 'object',
required: ['number', 'name', 'type'],
properties: {
number: {
type: 'number'
},
name: {
type: 'string'
},
type: {
type: 'string',
enum: ['Street', 'Avenue', 'Boulevard']
}
}
}
const { validate } = new Validator();
/**
* Validate `request.body` against `addressSchema`.
*/
app.post("/address", validate({ body: addressSchema }), (request, response) => {
/**
* Route handler logic to run when `request.body` has been validated.
*/
response.send({});
});
var app = express();
app.use(bodyParser.json());
// This route validates req.body against the StreetSchema
app.post('/street/', validate({body: StreetSchema}), function(req, res) {
// At this point req.body has been validated and you can
// begin to execute your application code
res.send('valid');
/**
* Error handler middleware for validation errors.
*/
app.use((error, request, response, next) => {
// Check the error is a validation error
if (error instanceof ValidationError) {
// Handle the error
response.status(400).send(error.validationErrors);
next();
} else {
// Pass error on if not a validation error
next(error);
}
});
// Error handler for valication errors
app.use(function(err, req, res, next) {
if (err instanceof ValidationError) {
// At this point you can execute your error handling code
res.status(400).send('invalid');
next();
}
else next(err); // pass error on if not a validation error
});
app.listen(3000);
```

@@ -154,89 +176,114 @@

Sometimes your route may depend on the `body` and `query` both having a specific format. In this example we use `body` and `query` but you can choose to validate any `request` properties you like.
Sometimes your route may depend on the `body` and `query` both having a specific
format. In this example we use `body` and `query` but you can choose to validate
any `request` properties you like. This example builds on the
[Example Express application](#example-express-application).
```js
var TokenSchema = {
type: 'object', // req.query is of type object
required: ['token'], // req.query.token is required
properties: {
uuid: { // validate token
type: 'string',
format: 'uuid',
minLength: 36,
maxLength: 36
}
}
}
```javascript
const tokenSchema = {
type: "object",
required: ["token"],
properties: {
token: {
type: "string",
minLength: 36,
maxLength: 36
},
},
};
app.post('/street/', Validator.validate({body: StreetSchema, query: TokenSchema}), function(req, res) {
// application code
});
app.post(
"/address",
validate({ body: addressSchema, query: tokenSchema }),
(request, response) => {
/**
* Route handler logic to run when `request.body` and
* `request.query` have both been validated.
*/
response.send({});
}
);
```
A valid request must now include a token URL query. Example valid URL: `/street/?uuid=af3996d0-0e8b-4165-ae97-fdc0823be417`
A valid request must now include a token URL query. Example valid URL:
`/street/?uuid=af3996d0-0e8b-4165-ae97-fdc0823be417`
## Using dynamic schema
Instead of passing in a schema object you can also pass in a function that will return a schema. It is
useful if you need to generate or alter the schema based on the request object.
Instead of passing in a schema object you can also pass in a function that will
return a schema. It is useful if you need to generate or alter the schema based
on the request object.
Example: loading schema from the database
Example: Loading schema from a database (this example builds on the
[Example Express application](#example-express-application)):
// Middleware executed before validate function
```js
function loadSchema(req, res, next) {
getSchemaFromDB()
.then((schema) => {
req.schema = schema;
next();
})
.catch(next);
```javascript
function getSchemaFromDb() {
/**
* In a real application this would be making a database query.
*/
return Promise.resolve(addressSchema);
}
// function that returns a schema object
function getSchema(req) {
// return the schema from the previous middleware or the default schema
return req.schema || DefaultSchema;
/**
* Middleware to set schema on the `request` object.
*/
async function loadSchema(request, response, next) {
try {
request.schema = await getSchemaFromDb();
next();
} catch (error) {
next(error);
}
}
app.post('/street/', loadSchema, Validator.validate({body: getSchema}), function(req, res) {
// route code
});
/**
* Get schema set by the `loadSchema` middleware.
*/
function getSchema(request) {
return request.schema;
}
app.post(
"/address",
loadSchema,
validate({ body: getSchema }),
(request, response) => {
/**
* Route handler logic to run when `request.body` has been validated.
*/
response.send({});
}
);
```
## Custom keywords
## Ajv instance
Ajv custom keywords must be defined *before* any validate() middleware
The Ajv instance can be accessed via `validator.ajv`.
Example:
```javascript
import { Validator, ValidationError } from "express-json-validator-middleware";
```js
var { Validator, ValidationError } = require('express-json-validator-middleware');
var validator = new Validator({allErrors: true});
const validator = new Validator();
validator.ajv.addKeyword('constant', { validate: function (schema, data) {
return typeof schema == 'object' && schema !== null
? deepEqual(schema, data)
: schema === data;
}, errors: false });
// route handlers with validate()
// Ajv instance
validator.ajv;
```
More info on custom keywords: [ajv#customs-keywords](https://github.com/epoberezkin/ajv/blob/master/CUSTOM.md#defining-custom-keywords)
Ajv must be configured *before* you call `Validator.validate()` to add middleware
(e.g. if you need to define [custom keywords](https://ajv.js.org/custom.html).
## Ajv instance
The Ajv instance can be accessed via validator.ajv.
## Ajv versions
```js
var { Validator, ValidationError } = require('express-json-validator-middleware');
var validator = new Validator({allErrors: true});
The major version `1.x` of this module uses `ajv@5`, read their changelog and
migration guide [here](https://github.com/ajv-validator/ajv/releases/tag/5.0.0).
validator.ajv // ajv instance
```
Major version `2.x` uses `ajv@6` in order to support draft-07 of JSON Schema.
You have to manually configure Ajv to support **draft-06** schemas
(see https://github.com/ajv-validator/ajv/tree/v6#using-version-6).
## Tests
Tests are written using Mocha & Chai
Tests are written using Mocha & Chai.
```

@@ -247,39 +294,11 @@ npm install

## More documentation on JSON Schema
## More documentation on JSON schemas
- [Understanding JSON Schema](https://json-schema.org/understanding-json-schema/index.html)
- [spacetelescope's understanding json schema](http://spacetelescope.github.io/understanding-json-schema/)
## <a name="migrating"></a> Migrating from `express-jsonschema`
In `express-jsonschema`, you could define a required property in two ways. Ajv only supports one way of doing this.
```js
// CORRECT
{
type: 'object',
properties: {
foo: {
type: 'string'
}
},
required: ['foo'] // <-- correct way
}
// WRONG
{
type: 'object',
properties: {
foo: {
type: 'string',
required: true // nono way
}
}
}
```
## Credits
- Maintained by [@JouzaLoL](https://github.com/jouzalol)
- [Original Module](https://github.com/trainiac/express-jsonschema) by [@trainiac](https://github.com/trainiac)
- PRs: see Contributors
- Maintained by [@simonplend](https://github.com/simonplend/)
- Created and previously maintained by [@vacekj](https://github.com/vacekj/)
- Thank you to all of this project's [contributors](https://github.com/vacekj/express-json-validator-middleware/graphs/contributors)
- Based on the [express-json-schema](https://github.com/trainiac/express-jsonschema) library by [@trainiac](https://github.com/trainiac)

@@ -0,4 +1,5 @@

import { Request } from "express";
import { RequestHandler } from "express-serve-static-core";
import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema";
import { ErrorObject, Options as AjvOptions } from "ajv";
import { Ajv, ErrorObject, Options as AjvOptions } from "ajv";

@@ -12,4 +13,3 @@ declare module "express-json-validator-middleware" {

export type ValidateFunction =
| Function
type AllowedSchema =
| JSONSchema4

@@ -19,5 +19,11 @@ | JSONSchema6

export type ValidateFunction =
| ((req: Request) => AllowedSchema)
| AllowedSchema;
export class Validator {
constructor(options: AjvOptions);
ajv: Ajv;
validate(rules: List<ValidateFunction>): RequestHandler;

@@ -27,4 +33,5 @@ }

export class ValidationError extends Error {
public validationErrors: List<ErrorObject>;
constructor(validationErrors: List<ErrorObject[]>);
public validationErrors: List<ErrorObject[]>;
}
}

@@ -0,0 +0,0 @@ var Ajv = require("ajv");

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc