sjv
An easy-to-write yet powerful schema validator for objects.
## Features
- ES5-compatible, uses Promises
- Elegant, minimal syntax
- Comprehensive error reporting - all validation failures, not just first one
- Asynchronous custom validators
- Type-matching
- No other library dependencies (small browser footprint)
Installation
This package requires Node 4 or above
$ npm install sjv
To use in the browser ensure you must have a working Promise implementation
(e.g. bluebird) available at window.Promise
.
Usage
Here is a schema with all the possible field types:
var schema = {
name: String,
isMarried: Boolean,
numCars: {
type: Number
},
born: {
type: Date
},
jobDetails: {
type: Object
},
favouriteNumbers: {
type: Array
},
address: {
type: {
houseNum: {
type: Number
},
taxBand: {
type: String,
enum: ['low', 'medium', 'high'],
},
},
},
children: {
type: [{
name: {
type: String,
validate: [
function(value) {
if ('john' === value) {
return Promise.reject(new Error('cannot be john'));
} else {
return Promise.resolve();
}
}
]
},
age: {
type: Number
}
}],
},
}
Example
First we define the schema:
var EmployeeSchema = {
name: {
type: String,
required: true
},
born: {
type: Date,
}
numChildren: {
type: Number,
},
address: {
type: {
houseNum: {
type: Number
},
street: {
type: String
},
country: {
type: String,
required: true
},
},
},
spouse: {
type: {
name: {
type: String,
required: true
}
}
},
};
var CompanySchema = {
name: {
type: String,
required: true
},
employees: {
type: [EmployeeSchema],
required: true
},
};
Now we can validate data against it:
var schema = require('sjv')(CompanySchema);
schema.validate({
name: 'my company',
employees: [
{
name: 'john',
born: 'last year',
numChildren: 1,
address: {
houseNum: 12,
street: 'view road',
country: 'uk',
}
},
{
name: 'mark',
born: new Date(),
numChildren: null,
address: {
houseNum: 25,
street: 'view road'
},
spouse: {
name: 23,
age: 23
}
},
]
})
.catch(function(err) {
console.log(err.toString());
console.log(err.failures);
});
Type matching
When stringifying JSON you often lose type information (e.g. Date
instances get converted to strings). When the stringified version gets parsed back into a JSON object you can use the typeify()
function to help restore type information:
var schema = {
name: {
type: String
},
isMarried: {
type: Boolean
},
numCars: {
type: Number
},
born: {
type: Date
}
};
var object = {
name: 'John',
isMarried: true,
numCars: 3,
born: new Date(2015,0,1)
}
var str = JSON.stringify(object);
var newObject = JSON.parse(str);
var typedObject = schema.typeify(newObject);
The type-ification process is quite tolerant of values. For example, for boolean values;
false
<- "false"
or "FALSE"
or "no"
or "NO"
or "0"
or 0
true
<- "true"
or "TRUE"
or "yes"
or "YES"
or "1"
or 1
To take the previous example again:
var newObject = {
name: 'John'
isMarried: 'no'
numCars: '76'
born: '2014-12-31T16:00:00.000Z'
};
var typedObject = schema.typeify(newObject);
It is also smart enough to know when a conversion isn't possible. Instead of throwing an error it will simply pass through the original value.
Using the schema from our previous example:
var newObject = {
name: null
isMarried: function() {}
numCars: false,
born: 'blabla'
};
var typedObject = schema.typeify(newObject);
You can limit type-ification to certain types only by setting the
limitTypes
option:
var newObject = {
name: 23,
isMarried: '0',
numCars: '3',
born: '2018-01-01'
};
var typedObject = schema.typeify(newObject, { limitTypes: [String]});
Building
To run the tests:
$ npm install -g gulp
$ npm install
$ npm test
Contributing
Contributions are welcome! Please see CONTRIBUTING.md.
License
MIT - see LICENSE.md