Comparing version 2.1.4 to 2.2.1
@@ -1,3 +0,22 @@ | ||
# Config changelog | ||
# 2valid changelog | ||
## [2.2.1](http://github.com/ivanoff/2valid/tree/2.2.1) (2017-01-24) | ||
[Full Changelog](http://github.com/ivanoff/2valid/compare/2.1.5...2.2.1) | ||
**What Was Done:** | ||
- add boolean type | ||
- add array type | ||
- add examples for each type | ||
- made 100% testing code coverage | ||
## [2.1.5](http://github.com/ivanoff/2valid/tree/2.1.5) (2016-11-17) | ||
[Full Changelog](http://github.com/ivanoff/2valid/compare/2.1.4...2.1.5) | ||
**What Was Done:** | ||
- add notRequired option | ||
## [2.1.4](http://github.com/ivanoff/2valid/tree/2.1.4) (2016-09-24) | ||
@@ -4,0 +23,0 @@ [Full Changelog](http://github.com/ivanoff/2valid/compare/2.1.3...2.1.4) |
69
index.js
/*! | ||
* validate-me | ||
* Copyright(c) 2015 ivanoff .$ curl -A cv ivanoff.org.ua | ||
* Copyright(c) 2015-2017 ivanoff .$ curl -A cv ivanoff.org.ua | ||
* MIT Licensed | ||
@@ -28,3 +28,3 @@ */ | ||
&& types[ obj[key].type ].min > obj[key].min ) { | ||
throw new Error('In model '+ modelName +', key '+ key +' minimal value ( '+ obj[key].min | ||
throw new Error('Key '+ key +' minimal value ( '+ obj[key].min | ||
+' ) is less than acceptable minimal in Types ( ' | ||
@@ -36,5 +36,5 @@ + types[ obj[key].type ].min + ' )' ); | ||
&& types[ obj[key].type ].max < obj[key].max ) { | ||
throw new Error('In model '+ modelName +', key '+ key +' maximal value ( '+ obj[key].max | ||
throw new Error('Key '+ key +' maximal value ( '+ obj[key].max | ||
+' ) is in excess of maximal acceptable value in Types ( ' | ||
+ types[ obj[key].type ].min + ' )' ); | ||
+ types[ obj[key].type ].max + ' )' ); | ||
} | ||
@@ -68,12 +68,13 @@ } | ||
exports.showModels = function( params ) { | ||
var res = []; | ||
if ( typeof( params ) === 'undefined' ) params = { displayEverything: false }; | ||
if ( ! this.registeredModels ) { | ||
console.log( 'There is no registered models' ); | ||
if ( ! this.registeredModels || Object.keys(this.registeredModels).length === 0 ) { | ||
res.push( 'There is no registered models' ); | ||
} else { | ||
console.log( 'List of registered models' ); | ||
res.push( 'List of registered models' ); | ||
for( var modelName in this.registeredModels ){ | ||
console.log( ' - ' + modelName ); | ||
res.push( ' - ' + modelName ); | ||
if( params.displayEverything ) { | ||
for( var key in this.registeredModels[ modelName ] ){ | ||
console.log( ' ' + key + ' : ' + this.registeredModels[ modelName ][ key ].type ); | ||
res.push( ' ' + key + ' : ' + this.registeredModels[ modelName ][ key ].type ); | ||
} | ||
@@ -83,2 +84,3 @@ } | ||
} | ||
return res.join("\n"); | ||
} | ||
@@ -88,22 +90,22 @@ | ||
exports.showModelsExpanded = function() { | ||
this.showModels( { displayEverything: true } ); | ||
return this.showModels( { displayEverything: true } ); | ||
} | ||
// check for required fields recursively | ||
function validateObjectRequired ( modelObject, entity, parents, errors ) { | ||
if( !errors ) errors = {}; | ||
function validateObjectRequired ( options, modelObject, entity, parents, errors ) { | ||
if( !options ) options = {}; | ||
for( var key in modelObject ){ | ||
if ( !modelObject[ key ].type ) { | ||
validateObjectRequired ( | ||
options, | ||
modelObject[ key ], | ||
entity? entity[ key ] : {}, | ||
parents? `${parents}.${key}` : key, | ||
entity[ key ], | ||
parents + '.' + key, | ||
errors ) | ||
} | ||
else if( modelObject[ key ].required && ( !entity || !entity[ key ] ) ) { | ||
} | ||
else if( !options.notRequired && modelObject[ key ].required && ( !entity || !entity[ key ] ) ) { | ||
if(!errors.notFound) errors.notFound = []; | ||
errors.notFound.push(`${parents}.${key}`); | ||
if(!errors.text) errors.text = []; | ||
errors.text.push(`Field ${parents}.${key} not found`); | ||
var fieldName = parents + '.' + key; | ||
errors.notFound.push(fieldName); | ||
errors.text.push('Field ' + fieldName + ' not found'); | ||
} | ||
@@ -116,19 +118,22 @@ } | ||
if( !errors ) errors = {}; | ||
if( !parents ) parents = []; | ||
for( var key in entity ){ | ||
var fieldName = parents + '.' + key; | ||
if ( !modelObject[ key ] ) { | ||
if(!errors.notRequired) errors.notRequired = []; | ||
errors.notRequired.push(`${parents}.${key}`); | ||
errors.notRequired.push(fieldName); | ||
if(!errors.text) errors.text = []; | ||
errors.text.push(`Field ${parents}.${key} not required`); | ||
errors.text.push('Field ' + fieldName + ' not required'); | ||
} | ||
else if ( !modelObject[ key ].type ) { | ||
validateObjectEntity ( modelObject[ key ], entity[ key ], parents? [ parents, key ] : key, errors ) | ||
validateObjectEntity ( modelObject[ key ], entity[ key ], [parents, key], errors ) | ||
} | ||
else if( !modelObject[ key ].check( entity[ key ] ) ) { | ||
if(!errors.notMatched) errors.notMatched = {}; | ||
errors.notMatched[`${parents}.${key}`] = modelObject[key].type; | ||
if(!errors.text) errors.text = []; | ||
if(!errors.text) errors.text = []; | ||
errors.text.push(`Field ${parents}.${key} not matched with type ${modelObject[key].type}`); | ||
errors.notMatched[fieldName] = modelObject[key].type; | ||
errors.text.push('Field ' + fieldName + ' not matched with type ' + modelObject[key].type); | ||
} | ||
@@ -140,3 +145,8 @@ } | ||
// Check if entity pass modelName's validation | ||
exports.validate = function( modelName, entity, next ) { | ||
exports.validate = function( modelName, entity, options, next ) { | ||
if(typeof options === "function") { | ||
next = options; | ||
options = {}; | ||
} | ||
var modelObject = this.registeredModels[modelName]; | ||
@@ -152,4 +162,4 @@ | ||
var errors = validateObjectRequired ( | ||
modelObject, entity, [], | ||
validateObjectEntity ( modelObject, entity, [] ) | ||
options, modelObject, entity, [], | ||
validateObjectEntity ( modelObject, entity ) | ||
); | ||
@@ -170,2 +180,1 @@ if(errors && errors.text) errors.text = errors.text.join('. '); | ||
} | ||
{ | ||
"name": "2valid", | ||
"version": "2.1.4", | ||
"version": "2.2.1", | ||
"description": "JavaScript simple data validator", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "make test" | ||
"test": "node_modules/.bin/mocha" | ||
}, | ||
@@ -9,0 +9,0 @@ "repository": { |
@@ -0,1 +1,10 @@ | ||
[![NPM version][npm-version-image]][npm-url] | ||
[![NPM downloads][npm-downloads-image]][npm-url] | ||
[![MIT License][license-image]][license-url] | ||
[![Build Status: Linux][travis-image]][travis-url] | ||
[![Build Status: Windows][appveyor-image]][appveyor-url] | ||
[![Coverage Status][coveralls-image]][coveralls-url] | ||
# 2valid | ||
@@ -5,3 +14,3 @@ | ||
v2.1.4 | ||
v2.2.1 | ||
@@ -40,2 +49,4 @@ | ||
| float | float number | | ||
| boolean | boolean | | ||
| array | array type | | ||
| date | date methods | | ||
@@ -359,2 +370,3 @@ | email | simple e-mail | | ||
* 2.0.1 Rename project to 2valid | ||
* 2.2.1 Add boolean and array types, add examples | ||
@@ -368,1 +380,17 @@ | ||
[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat | ||
[license-url]: LICENSE | ||
[npm-url]: https://npmjs.org/package/2valid | ||
[npm-version-image]: http://img.shields.io/npm/v/2valid.svg?style=flat | ||
[npm-downloads-image]: http://img.shields.io/npm/dm/2valid.svg?style=flat | ||
[travis-url]: https://travis-ci.org/ivanoff/2valid | ||
[travis-image]: https://travis-ci.org/ivanoff/2valid.svg?branch=master | ||
[appveyor-url]: https://ci.appveyor.com/project/ivanoff/2valid/branch/master | ||
[appveyor-image]: https://ci.appveyor.com/api/projects/status/lp3nhnam1eyyqh33/branch/master?svg=true | ||
[coveralls-url]: https://coveralls.io/github/ivanoff/2valid | ||
[coveralls-image]: https://coveralls.io/repos/github/ivanoff/2valid/badge.svg |
@@ -17,5 +17,61 @@ 'use strict'; | ||
this.vm.registerModel( ).should.equal('Name is not defined'); | ||
this.vm.registerModel( 'noObj' ).should.equal('Model in noObj is not defined'); | ||
}); | ||
it('register same name model', function() { | ||
this.vm.registerModel( 'sameName', { id: {type: 'integer'} } ); | ||
this.vm.registerModel( 'sameName', { name: {type: 'string'} } ).should.equal('Model sameName is already registered'); | ||
}); | ||
}); | ||
}); | ||
describe('Simple model to validate', function () { | ||
var userModel = { | ||
id: {type: 'notype'}, | ||
}; | ||
it('notype model error', function(done) { | ||
try { | ||
this.vm.validate( userModel, { id: 111 }, function() { should.fail() }); | ||
} | ||
catch (err) { | ||
err.should.eql(Error('No type notype in Types: key id')); | ||
done(); | ||
} | ||
}); | ||
}); | ||
describe('Min length validate', function () { | ||
var userModel = { | ||
password: {type: 'password', min: 1}, | ||
}; | ||
it('in registerModel', function(done) { | ||
try { | ||
this.vm.registerModel( 'userPassMin', userModel ); | ||
} | ||
catch (err) { | ||
(err instanceof Error).should.equal(true); | ||
String(err).should.eql('Error: Key password minimal value ( 1 ) is less than acceptable minimal in Types ( 4 )'); | ||
done(); | ||
} | ||
}); | ||
}); | ||
describe('Max length validate', function () { | ||
var userModel = { | ||
password: {type: 'password', max: 100001}, | ||
}; | ||
it('in registerModel', function(done) { | ||
try { | ||
this.vm.registerModel( 'userPassMax', userModel ); | ||
} | ||
catch (err) { | ||
(err instanceof Error).should.equal(true); | ||
String(err).should.eql('Error: Key password maximal value ( 100001 ) is in excess of maximal acceptable value in Types ( 1000 )'); | ||
done(); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -35,3 +35,3 @@ 'use strict'; | ||
var userModel = { | ||
id: {type: 'integer'}, | ||
id: {type: 'integer', required: true}, | ||
name: {type: 'string', required: true} | ||
@@ -60,2 +60,24 @@ }; | ||
it('validate failed', function(done) { | ||
this.vm.validate( userModel, | ||
{ id: 'Max', name: 123 }, | ||
function(err) { | ||
err.should.eql({ notMatched: { '.id': 'integer', '.name' : 'string' }, | ||
text: 'Field .id not matched with type integer. Field .name not matched with type string' | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('validate failed', function(done) { | ||
this.vm.validate( userModel, | ||
{ secondName: 'Validator', pages: 12 }, | ||
function(err) { | ||
err.should.eql({ | ||
text: 'Field .secondName not required. Field .pages not required. Field .id not found. Field .name not found', | ||
notRequired: [ '.secondName', '.pages' ], notFound: [ '.id', '.name' ] }); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -104,2 +126,28 @@ | ||
describe('Model to validate not required data', function () { | ||
it('validate passed', function(done) { | ||
this.vm.validate( 'user', { | ||
id : '61cecfb4-da43-4b65-aaa0-f1c3be81ec53', | ||
name : { first : 'Alex', last: 'Validates', }, | ||
metadata: { tt1:1, tt2:2 }, | ||
}, {notRequired: 1}, function(err) { | ||
should.not.exist(err); | ||
done(); | ||
}); | ||
}); | ||
it('validate failed', function(done) { | ||
this.vm.validate( 'user', { | ||
id : '61cecfb4-da43-4b65-aaa0-f1c3be81ec53', | ||
name : { last: 'Validates', }, | ||
metadata: { tt1:1, tt2:2 }, | ||
}, {notRequired: 1}, function(err) { | ||
should.not.exist(err); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('Model to validate match data', function () { | ||
@@ -106,0 +154,0 @@ |
@@ -24,2 +24,5 @@ 'use strict'; | ||
email: { type: 'email' }, | ||
birthday: { type: 'date' }, | ||
alive: { type: 'boolean' }, | ||
childrens: { type: 'array' }, | ||
metadata: { type: 'object' }, | ||
@@ -38,2 +41,6 @@ }).should.be.false; | ||
metadata: { tt1:1, tt2:2 }, | ||
email : 'max.validator@my.site', | ||
birthday : new Date('1980-04-01'), | ||
childrens : ['Maria', 'Alexandra'], | ||
alive: true, | ||
createdAt : new Date(), | ||
@@ -44,3 +51,21 @@ }).should.eql({ notFound: [ '.name.first' ], notRequired: [ '.createdAt' ], | ||
}); | ||
describe('Model to validate notRequired data', function () { | ||
it('register new model', function() { | ||
this.vm.validate( 'user_sync', { | ||
id : '61cecfb4-da43-4b65-aaa0-f1c3be81ec53', | ||
name : { first : 'Alex', last: 'Validates', }, | ||
metadata: { tt1:1, tt2:2 }, | ||
}, {notRequired: 1} ).should.eql({}); | ||
this.vm.validate( 'user_sync', { | ||
id : '61cecfb4-da43-4b65-aaa0-f1c3be81ec53', | ||
name : { last: 'Validates', }, | ||
metadata: { tt1:1, tt2:2 }, | ||
}, {notRequired: 1} ).should.eql({}); | ||
}); | ||
}); | ||
@@ -47,0 +72,0 @@ |
16
types.js
@@ -26,3 +26,3 @@ /**** List of types to validate ****/ | ||
&& number <= this.max | ||
&& !`${number}`.match(/\./); | ||
&& !number.toString().match(/\./); | ||
}, | ||
@@ -57,3 +57,3 @@ }, | ||
check : function( email ){ // date.check Maximum length of the string | ||
return `${email}`.match( this.match ); | ||
return email.toString().match( this.match ); | ||
}, | ||
@@ -64,3 +64,3 @@ }, | ||
min : 4, // minimum length of the password | ||
max : Infinity, | ||
max : 1000, // maximum length of the password | ||
// at least one caps and one small letter, digit and special | ||
@@ -79,3 +79,3 @@ match : /^.*(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W]).*$/, | ||
check : function( md5 ){ | ||
return md5 && `${md5}`.match( this.match ); | ||
return md5 && md5.toString().match( this.match ); | ||
}, | ||
@@ -87,6 +87,12 @@ }, | ||
check : function( uuid ){ | ||
return uuid && `${uuid}`.match( this.match ); | ||
return uuid && uuid.toString().match( this.match ); | ||
}, | ||
}, | ||
array : { | ||
check : function( arr ){ | ||
return typeof arr === 'object' && Array.isArray(arr); | ||
}, | ||
}, | ||
object : { | ||
@@ -93,0 +99,0 @@ check : function(){ return 1 } |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
47609
16
803
393