Comparing version 0.8.0 to 0.9.0
@@ -7,5 +7,7 @@ 'use strict'; | ||
var email = { | ||
_regex: { | ||
default: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/ | ||
}, | ||
default: function _default(context) { | ||
var emailRegEx = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; | ||
if (!emailRegEx.test(context.value)) { | ||
if (!context.value.match(email._regex.default)) { | ||
context.fail('Value must be a valid email'); | ||
@@ -12,0 +14,0 @@ } |
@@ -7,5 +7,8 @@ 'use strict'; | ||
var ip = { | ||
_regex: { | ||
v4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, | ||
v6: /^((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7}$/ | ||
}, | ||
v4: function v4(context) { | ||
var ipv4RegEx = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; | ||
if (!ipv4RegEx.test(context.value)) { | ||
if (!context.value.match(ip._regex.v4)) { | ||
context.fail('Value must be a valid IPv4 address'); | ||
@@ -15,4 +18,3 @@ } | ||
v6: function v6(context) { | ||
var ipv6RegEx = /^((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*::((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4}))*|((?:[0-9A-Fa-f]{1,4}))((?::[0-9A-Fa-f]{1,4})){7}$/; | ||
if (!ipv6RegEx.test(context.value)) { | ||
if (!context.value.match(ip._regex.v6)) { | ||
context.fail('Value must be a valid IPv6 address'); | ||
@@ -19,0 +21,0 @@ } |
@@ -7,2 +7,5 @@ 'use strict'; | ||
var string = { | ||
_regex: { | ||
alphanumeric: /^[a-zA-Z0-9]*$/ | ||
}, | ||
default: function _default(context) { | ||
@@ -12,2 +15,7 @@ if (typeof context.value !== 'string') { | ||
} | ||
}, | ||
alphanumeric: function alphanumeric(context) { | ||
if (!context.value.match(string._regex.alphanumeric)) { | ||
context.fail('Value must contain only letters and/or numbers'); | ||
} | ||
} | ||
@@ -14,0 +22,0 @@ }; |
@@ -7,5 +7,7 @@ 'use strict'; | ||
var url = { | ||
_regex: { | ||
default: /^((http|https|ftp):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/ | ||
}, | ||
default: function _default(context) { | ||
var urlRegEx = /^((http|https|ftp):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/; | ||
if (!urlRegEx.test(context.value)) { | ||
if (!context.value.match(url._regex.default)) { | ||
context.fail('Value must be a valid URL'); | ||
@@ -12,0 +14,0 @@ } |
@@ -7,5 +7,7 @@ 'use strict'; | ||
var uuid = { | ||
_regex: { | ||
default: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/ | ||
}, | ||
default: function _default(context) { | ||
var uuidRegEx = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/; | ||
if (!uuidRegEx.test(context.value)) { | ||
if (!context.value.match(uuid._regex.default)) { | ||
context.fail('Value must be a valid UUID'); | ||
@@ -12,0 +14,0 @@ } |
{ | ||
"name": "obey", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "Data modelling and validation library", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
108
README.md
@@ -0,1 +1,5 @@ | ||
# Obey | ||
Asynchronous Data Modelling and Validation. | ||
[![CircleCI](https://img.shields.io/circleci/project/TechnologyAdvice/obey.svg)](https://circleci.com/gh/TechnologyAdvice/obey) | ||
@@ -7,13 +11,13 @@ [![Code Climate](https://img.shields.io/codeclimate/github/TechnologyAdvice/obey.svg)](https://codeclimate.com/github/TechnologyAdvice/obey) | ||
# Obey | ||
## Introduction | ||
Data validation and modelling library for those of us with better things to do. | ||
Obey is a library for creating asynchronous data models and rules. The core goal of the project is to provide methods for managing data models both through synchronous and asynchronous validation and alignment using [JavaScript Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). | ||
## Installation | ||
Obey can be installed via NPM: `npm install obey --save` | ||
Obey can be installed via [NPM](https://www.npmjs.com/package/obey): `npm install obey --save` | ||
## Creating Rules | ||
## Rules | ||
Rules are core definitions of how a value should be validated: | ||
> Rules are core definitions of how a value should be validated: | ||
@@ -26,24 +30,7 @@ ```javascript | ||
#### Validating with a Rule | ||
## Models | ||
A rule creates a reference which then can be validated with data: | ||
> Models allow for creating validation rules for entire object schemas. The following demonstrates a model being created with Obey: | ||
```javascript | ||
firstName.validate('John') | ||
.then((data) => { | ||
// Passes back `data` value, includes any defaults set, | ||
// generated, or modified data | ||
}) | ||
.catch(error => { | ||
// Returns instance of ValidationError | ||
// `error.message` => String format error messages | ||
// `error.collection` => Raw array of error objects | ||
}) | ||
``` | ||
## Creating Models | ||
Models allow for creating validation rules for entire object schemas. The following demonstrates a basic model being created with Obey: | ||
```javascript | ||
import obey from 'obey' | ||
@@ -54,3 +41,3 @@ | ||
email: { type: 'email', required: true }, | ||
password: { type: 'string', modifier: 'encryptPassword', required: true } | ||
password: { type: 'string', modifier: 'encryptPassword', required: true }, | ||
fname: { type: 'string', description: 'First Name' }, | ||
@@ -68,3 +55,3 @@ lname: { type: 'string', description: 'Last Name' }, | ||
street: { type: 'string', max: 45 }, | ||
city: { type: 'string', max: 45 } | ||
city: { type: 'string', max: 45 }, | ||
state: { type: 'string', max: 2, modifier: 'upperCase' }, | ||
@@ -81,8 +68,8 @@ zip: { type: 'number', min: 10000, max: 99999 } | ||
#### Validating with a Model | ||
## Validation | ||
Using the example above, validation is done, similar to validating with a rule, by calling the `validate` method and supplying data: | ||
Using the example above, validation is done by calling the `validate` method and supplying data. This applies to both individual rules and data models: | ||
```javascript | ||
userModel.validate({ /* some data object */ }) | ||
userModel.validate({ /* some data */ }) | ||
.then((data) => { | ||
@@ -101,9 +88,9 @@ // Passes back `data` object, includes any defaults set, | ||
## Properties of Rules | ||
## Definition Properties | ||
The properties used can each be explained as: | ||
When setting definitions for rules or model properties, the following are supported: | ||
* `type`: The type of value with (optional) sub-type see [Types](#types) | ||
* `keys`: Property of `object` type, indicates nested object properties | ||
* `values`: Defines value specification for arrays or key-independent object tests | ||
* `values`: Defines value specification for arrays or key-independent objects | ||
* `modifier`: uses a method and accepts a passed value to modify or transform data, see [Modifiers](#modifiers) | ||
@@ -119,18 +106,2 @@ * `generator`: uses a method to create a default value if no value is supplied, see [Generators](#generators) | ||
## Strict Mode | ||
By default, Obey enforces strict matching on objects; meaning an object must define any keys that will be present in the data object being validated. | ||
To disable strict mode on a rule or object set the `strict` property to false: | ||
```javascript | ||
foo: { type: 'object', strict: false, keys: { /* ... */ } } | ||
``` | ||
To disable strict mode on a model pass the (optional) strict argument as `false`: | ||
```javascript | ||
const model = obey.model({ /* definition */ }, false) | ||
``` | ||
## Types | ||
@@ -140,3 +111,3 @@ | ||
Types are basic checks against native types, built-ins or customs. The library includes native types (`boolean`, `number`, `string`, `array`, and `object`) as well other common types. A [list of built-in types](/src/types) is contained in the source. | ||
> Types are basic checks against native types, built-ins or customs. The library includes native types (`boolean`, `number`, `string`, `array`, and `object`) as well other common types. A [list of built-in types](/src/types) is contained in the source. | ||
@@ -202,4 +173,17 @@ The `type` definition can also specify a sub-type, for example: | ||
Types can be synchronous or asynchronous. Types _can_ return/resolve a value, though it is not required and is recommended any coercion be handled with a modifier. | ||
Types can be synchronous or asynchronous. For example, if a unique email is required the following could be used to define a `uniqueEmail` type: | ||
```javascript | ||
obey.type('uniqueEmail', context => { | ||
return someDataSource.find({ email: context.value }) | ||
.then(record => { | ||
if (record.length >= 1) { | ||
context.fail(`${context.key} already exists`) | ||
} | ||
}) | ||
} | ||
``` | ||
Types _can_ return/resolve a value, though it is not required and is recommended any coercion be handled with a modifier. | ||
Regardless of if a value is returned/resolved, asynchronous types must resolve. Errors should be handled with the `context.fail()` method. | ||
@@ -209,3 +193,3 @@ | ||
Modifiers allow custom methods to return values which are modified/transformed versions of the received value. | ||
> Modifiers allow custom methods to return values which are modified/transformed versions of the received value. | ||
@@ -222,7 +206,7 @@ ### Creating Modifiers | ||
Modifiers can be synchronous or asynchronous. In both cases they must either return (or resolve) the final value. | ||
Similar to types, modifiers may be synchronous (returning a value) or asynchronous (returning a promise). | ||
## Generators | ||
Generators allow custom methods to return values which set the value similar to the `default` property. When validating, if a value is not provided the generator assigned will be used to set the value. | ||
> Generators allow custom methods to return values which set the value similar to the `default` property. When validating, if a value is not provided the generator assigned will be used to set the value. | ||
@@ -245,4 +229,20 @@ ### Creating Generators | ||
Generators can be synchronous or asynchronous. In both cases they must either return (or resolve) the final value. | ||
Similar to modifiers, generators may be synchronous (returning a value) or asynchronous (returning a promise). | ||
## Strict Mode | ||
By default, Obey enforces strict matching on objects; meaning an object must define any keys that will be present in the data object being validated. | ||
To disable strict mode on a rule or object set the `strict` property to false: | ||
```javascript | ||
foo: { type: 'object', strict: false, keys: { /* ... */ } } | ||
``` | ||
To disable strict mode on a model pass the (optional) strict argument as `false`: | ||
```javascript | ||
const model = obey.model({ /* definition */ }, false) | ||
``` | ||
## Asynchronous Validation | ||
@@ -249,0 +249,0 @@ |
33550
22
621