felv
felv is a fast easy and light (synchronous and asynchronous) JavaScript validator.
- Take only 2 minutes to know if felv is made for you.
- Take only 5 minutes to try it.
- Take only 15 minutes to read this page and learn everything you need to know!
Installation
Run the following command to add the package to your dev dependencies:
$ npm install --save felv
Use
const felv = ;
Example
const schema = // Value of 'a' key is required and must be a number. a: required: true type: 'number' // Value of 'b' key is an array of numbers and strings. b: type: Array items: type: 'string' 'number' // Value of 'c' key is an instance of Object // with properties i and j which are booleans // of default value `true`. c: type: Object properties: i: default: true type: 'boolean' j: default: true type: 'boolean' // Value of 'd' key is an instance of Object // with properties of variable names and string values. d: type: Object items: type: 'string' ; const validatedValue = felv;
validatedValue
is equal to:
a: 1 b: 2 'foo' 4 c: i: false j: true d: x: 'foo' y: 'bar'
Validation
Simple
You can easily validate a value from a schema:
const validatedValue = felv;
From a compiled schema
For repetitive validations, you should compile a validator to optimize validation performances. This can also be useful to detect schema format errors before validation occurs.
const validator = felv;const validatedValue = validator;
Schema
A schema is used to describe the format of a value. Each attribute of a schema is called a validation processor. A schema can embed other schemas to describe embedded structures thanks to some validation processors.
Validation processors list
Type
You can check the type of the value of a key:
foo: type: 'number' bar: type: Date foobar: type: 'number' 'string' // number or string items
Matching values:
foo: 2 bar: foobar: 3 foo: 2 bar: foobar: 'foo'
Default
You can specify a default value:
foo: default: 3 type: 'number' bar: default: 6
Matching value:
foo: 2
Validated value:
foo: 2 bar: 6
Required
You can specify a required value:
foo: required: true type: 'number' bar: type: 'number'
Matching value:
foo: 2
Items
You can specify embedded items of arrays and objects:
foo: type: Array items: type: 'number' bar: type: Object items: type: 'number'
Matching value:
foo: 2 3 7 bar: a: 1 b: 5
Properties
You can specify properties of objects:
foo: type: Object properties: a: required: true type: 'number' b: default: 'bar' type: 'string'
Matching value:
foo: a: 4
Validated value:
foo: a: 4 b: 'bar'
Format
You can give a function to format input values:
foo: Array ? value : value type: Array items: type: 'string'
Matching value:
foo: 'bar'
Validated value:
foo: 'bar'
Validate
You can give a function to make custom validations and format output values:
foo: type: 'number' { if value < 1 || value > 9 // Throw a validation error. ; return value; } bar: type: 'number' // Alter validated value. value > 1 ? value * 10 : value
Matching value:
foo: 4 bar: 2
Validated value:
foo: 4 bar: 20
Error
You can specify a custom error message that will be set on error occurrence:
const schema = foo: required: true type: 'number' error: 'You must specify a number for "foo"' ; try felv; catcherror console; // Display `You must specify a number for "foo"`.
Validation ways
You can specify different validation ways givin an array of schemas:
foo: required: true type: 'number' default: 'bar' type: 'string'
Matching values:
foo: 2 foo: 'foo' {}
Corresponding validated values:
foo: 2 foo: 'foo' foo: 'bar'
Asynchronous validation
You can use asynchronous functions in validation processors accepting a function (like format
and validate
) or directly return a Promise
. In that case, a Promise
will be returned by the validate
method.
Example:
const asyncSchema = foo: validate: async { const validatedValue = await ; return validatedValue + 1; } bar: { return { ; }; } ;const validatedValue = await felv;
Validation processors dependencies
For simplicity, validation processors are independent from each other.
Validation processors order
Validation processors are processed in a specific order:
- format
- default
- required
- type
- items
- properties
- validate
- error
Options
You can modulate validation with following options:
- async
- convert
- formatting
- full
- immutable
- list
- namespace
- required
- validation
Async
Whether or not to force a Promise
result even on synchronous return.
Default value:
async: false
Convert
Whether or not to automatically convert some value types.
Default value:
convert: true
string
=>boolean
:"false"
=>false
"true"
=>true
"0"
=>false
"1"
=>true
number
=>boolean
:0
=>false
!== 0
=>true
string
=>number
:"100"
=>100
boolean
=>number
:false
=>0
true
=>1
Formatting
A validation object to be passed as second argument (options
) in format
validation processors:
foo: { // Format value from options. }
Default value:
formatting: {}
Full
Whether or not to process full validation event after a first error occurred.
Default value:
full: false
Immutable
Whether or not to use the original value for validated value. This increase performances but must not be used for cases where the original value must be preserved.
Default value:
immutable: false
List
Whether or not to process schema on a list of items (array or object) instead of an object with defined properties.
Default value:
list: false
Namespace
A namespace to prefix paths in error messages.
Default value:
namespace: '$'
Required
Whether or not fields are required by default.
Default value:
required: false
Validation
A validation object to be passed as third argument (options
) in validate
validation processors:
foo: { // Validate 'value' from 'options'. // Throw validation error with 'expected'. }
expected
function take 3 arguments:
{string} expectedType
: Expected type (or value description){Array.<*>} [expectedValues]
: Optional expected values{string} [customMessage]
: Optional custom error message
Default value:
validation: {}
Error handling
Simple example
const validator = felv;try const validatedValue = validator; catch error // Error type: 'ValidationError' console; // Explicit message: '[$.foo](type) Expected value to be a string, got a number of value `3` instead' console; // Path of the failing value: '$.foo' console; // Failing schema attribute/validation processor: 'type' console; // Subject of failure: 'value' console; // Expected type: 'string' console; // Expected values: [] console; // Got(gotten) type: 'number' console; // Got(gotten) value: 3 console; // Custom message (not defined here): '' console;
Full validation example
You can process full validation to retrieve all validation errors of a value against a schema. This can be useful to validate a user form and return all errors for instance:
// Compile form schema at program initialization.const schema = firstname: required: true type: 'string' // Define custom error message of occuring validation error. error: 'Firstname must be filled' lastname: required: true type: 'string' email: required: true type: 'string' { if !/@/ // Define custom error message with third argument // of expected function. ; return value; } // `error` attribute does not overwrite already defined custom message // like 'Email is incorrect' in above validate attribute function. error: 'Email must be filled' password: required: true type: 'string' { if valuelength < 8 ; else if !/[A-Z]/ ; return value; } error: 'Password must at least contains 8 characters with at least one uppercase letter' ;const options = namespace: 'form' full: true;const validator = felv;
// Use compiled validator to validate user input on user subscription.// We assume `req.body` equals `{email: 'dumb', password: 'dumb'}`try const validatedValue = validator; // Do stuff like persisting user in database... catch error // Error type: 'FullValidationError' console; // Use `error.pathErrorMessages` to get validation error messages associated with failing paths. assert; // Use `error.pathErrors` to get the validation errors instead of messages. // Use `error.errorMessages` to get validation error message list. assert; // Use `error.errors` to get the validation errors instead of messages.
Testing
Many npm
scripts are available to help testing:
$ npm run {script}
check
: lint and check unit and integration testslint
: linttest
: check unit teststest-coverage
: check coverage of unit teststest-debug
: debug unit teststest-integration
: check integration teststest-performance
: check performance (just for fun)test-watch
: work in TDD!
Use npm run check
to check that everything is ok.
Contributing
If you want to contribute, just fork this repository and make a pull request!
Your development must respect these rules:
- fast
- easy
- light
You must keep test coverage at 100%.