| language: node_js | ||
| node_js: | ||
| - 0.10 |
+125
| var Credible = require('../') | ||
| , should = require('should'); | ||
| describe('constructor', function () { | ||
| it('should create a validations array', function (ok) { | ||
| var credible = new Credible(); | ||
| should(credible.validations).be.instanceof(Array); | ||
| ok(); | ||
| }); | ||
| describe('arguments', function (){ | ||
| it('should create a rule if an object is passed', function (ok) { | ||
| var credible = new Credible({ | ||
| name: { | ||
| presence: true | ||
| } | ||
| }); | ||
| should(credible.validations.length).equal(1); | ||
| ok(); | ||
| }); | ||
| it('should create a rule for a parameter', function (ok) { | ||
| var credible = new Credible('name', { | ||
| presence: true | ||
| }); | ||
| should(credible.validations.length).equal(1); | ||
| should(credible.validations[0]._props.name).be.type('object'); | ||
| ok(); | ||
| }); | ||
| it('should create a rule for a parameter if rule is passed as string', function (ok) { | ||
| var credible = new Credible('name', 'presence', true); | ||
| should(credible.validations.length).equal(1); | ||
| should(credible.validations[0]._props.name).be.type('object'); | ||
| ok(); | ||
| }); | ||
| it('should create a rule if a function is passed', function (ok) { | ||
| var credible = new Credible(function () { | ||
| throw 'foo'; | ||
| }); | ||
| should(credible.validations.length).equal(1); | ||
| ok(); | ||
| }); | ||
| }); | ||
| }); | ||
| describe('.rule', function () { | ||
| it('should create a rule if an object is passed', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule({name: {presence: true}}); | ||
| should(credible.validations.length).equal(1); | ||
| ok(); | ||
| }); | ||
| it('should create a rule if an object is passed with multiple parameters', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule({name: {presence: true}, address: {presence: true}}); | ||
| should(credible.validations.length).equal(2); | ||
| ok(); | ||
| }); | ||
| it('should create a rule for a parameter', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule('name', {presence: true}); | ||
| should(credible.validations.length).equal(1); | ||
| should(credible.validations[0]._props.name).be.type('object'); | ||
| ok(); | ||
| }); | ||
| it('should create a rule for a parameter if rule is passed as string', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule('name', 'presence', true); | ||
| should(credible.validations.length).equal(1); | ||
| should(credible.validations[0]._props.name).be.type('object'); | ||
| ok(); | ||
| }); | ||
| it('should create a rule if a function is passed', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule(function () { | ||
| throw 'foo'; | ||
| }); | ||
| should(credible.validations.length).equal(1); | ||
| ok(); | ||
| }); | ||
| it('should create a rule with an if property', function (ok) { | ||
| var credible = new Credible(); | ||
| credible.rule({name: {presence: { if: function () { throw 'Foo' }}}}); | ||
| should(credible.validations.length).equal(1); | ||
| should(credible.validations[0]._ifAll.length).equal(1); | ||
| ok(); | ||
| }); | ||
| }); | ||
| describe('validators', function () { | ||
| it('should test for presence', function (ok) { | ||
| var credible = new Credible() | ||
| credible.rule('name', 'presence', true); | ||
| credible.run({name: ''}) | ||
| .catch(function (e) { | ||
| should(e.toString()).equal('name is required'); | ||
| ok(); | ||
| }); | ||
| }); | ||
| it('should test for length', function (ok) { | ||
| var credible = new Credible() | ||
| credible.rule('name', 'length', {greaterThan: 5}); | ||
| credible.run({name: ''}) | ||
| .catch(function (e) { | ||
| should(e.toString()).equal('name must be greater than 5 character(s)'); | ||
| ok(); | ||
| }); | ||
| }); | ||
| }) |
+365
-154
| (function(root){ | ||
| function __(_, Promise) { | ||
| function __(Promise) { | ||
| var _LOCALE_ = 'en', | ||
| _TYPES_ = { | ||
| ValidatorTypes = { | ||
| alpha: /^[a-z]+$/i, | ||
| alphaDash: /^[a-z0-9_\-]+$/i, | ||
| alphaNumeric: /^[a-z0-9]+$/i, | ||
| alphaUnderscore: /^[a-z0-9_]+$/i, | ||
| email: /^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,6}$/i, | ||
| integer: /^\-?[0-9]+$/, | ||
| url: /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, | ||
| natural: /^[0-9]+$/i, | ||
| naturalNonZero: /^[1-9][0-9]*$/i | ||
| naturalNonZero: /^[1-9][0-9]*$/i, | ||
| url: /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/ | ||
| }, | ||
| _VALIDATORS_ = { | ||
| Validators = { | ||
| length: function (obj, prop, options) { | ||
| var v = (obj[prop] || '').length, arr = [], errs = [], n; | ||
| if (options.greaterThan) { | ||
| arr.push([options.greaterThan, (v > options.greaterThan), 'lengthGreaterThan']); | ||
| } | ||
| if (options.lessThan) { | ||
| arr.push([options.lessThan, (v < options.lessThan), 'lengthLessThan']); | ||
| } | ||
| if (options.greaterThanOrEqualTo) { | ||
| arr.push([options.greaterThanOrEqualTo, (v >= options.greaterThanOrEqualTo), 'lengthGreaterThanOrEqualTo']); | ||
| } | ||
| if (options.lessThanOrEqualTo) { | ||
| arr.push([options.lessThanOrEqualTo, (v <= options.lessThanOrEqualTo), 'lengthLessThanOrEqualTo']); | ||
| } | ||
| if (options.equalTo) { | ||
| arr.push([options.equalTo, (v == options.equalTo), 'lengthEqualTo']); | ||
| } | ||
| for (var key in arr) { | ||
| if (!arr[key][1]) errs.push(new ValidatorMessage(arr[key][2], { property: prop, num: arr[key][0] })) | ||
| } | ||
| if (errs.length) throw errs; | ||
| }, | ||
| presence: function (obj, prop) { | ||
| if (!obj[prop]) throw _MESSAGE_('presence', {property: prop}); | ||
| if (!obj[prop]) throw new ValidatorMessage('presence', {property: prop}); | ||
| }, | ||
| operator: function (obj, lh, o, rh) { | ||
| var lhv = obj[lh] | ||
| , rhv = 'string' === typeof rh ? obj[rh] : rh | ||
| , b, m; | ||
| switch (o) { | ||
| case '>': | ||
| b = lhv > rhv; | ||
| m = 'greaterThan'; | ||
| break; | ||
| case '<': | ||
| b = lhv < rhv; | ||
| m = 'lessThan'; | ||
| break; | ||
| case '>=': | ||
| b = lhv >= rhv; | ||
| m = 'greaterThanOrEqualTo'; | ||
| break; | ||
| case '<=': | ||
| b = lhv <= rhv; | ||
| m = 'lessThanOrEqualTo'; | ||
| break; | ||
| case '=': | ||
| b = lhv == rhv; | ||
| m = 'equalTo'; | ||
| operator: function (obj, prop, options) { | ||
| var lhv = obj[prop] | ||
| , arr = [] | ||
| , errs = [] | ||
| , isProp | ||
| , rhv; | ||
| for (var key in options) { | ||
| isProp = 'string' === typeof options[key]; | ||
| rhv = isProp ? obj[options[key]] : options[key]; | ||
| if ('greaterThan' === key) { | ||
| arr.push([rhv, (lhv > rhv), 'greaterThan', isProp, options[key]]); | ||
| } else if ('lessThan' === key) { | ||
| arr.push([rhv, (lhv < rhv), 'lessThan', isProp, options[key]]); | ||
| } else if ('greaterThanOrEqualTo' === key) { | ||
| arr.push([rhv, (lhv >= rhv), 'greaterThanOrEqualTo', isProp, options[key]]); | ||
| } else if ('lessThanOrEqualTo' === key) { | ||
| arr.push([rhv, (lhv <= rhv), 'lessThanOrEqualTo', isProp, options[key]]); | ||
| } else if ('equalTo' === key) { | ||
| arr.push([rhv, (lhv == rhv), 'equalTo', isProp, options[key]]); | ||
| } | ||
| } | ||
| if (!b) throw _MESSAGE_(m, {lh: lh, rh: 'string' === typeof rh ? rh : rhv}); | ||
| }, | ||
| match: function (obj, prop, type) { | ||
| if (!_TYPES_[type].test(obj[prop])) | ||
| throw _MESSAGE_(type, {property: prop}); | ||
| for (var key in arr) { | ||
| if (!arr[key][1]) | ||
| errs.push(new ValidatorMessage(arr[key][2], { lh: prop, rh: arr[key][3] ? arr[key][4] : arr[key][0] })); | ||
| } | ||
| if (errs.length) throw errs; | ||
| } | ||
@@ -56,18 +76,28 @@ | ||
| _MESSAGES_ = { | ||
| presence: { | ||
| en: '{{property}} is required' | ||
| ValidationMatch = function (obj, prop, type) { | ||
| if (!ValidatorTypes[type].test(obj[prop])) | ||
| throw new ValidatorMessage(type, {property: prop}); | ||
| } | ||
| for (var type in ValidatorTypes) { | ||
| Validators[type] = (function (t) { | ||
| return function (obj, prop) { | ||
| ValidationMatch(obj, prop, t); | ||
| } | ||
| })(type); | ||
| } | ||
| var ValidatorMessages = { | ||
| alpha: { | ||
| en: '{{property}} must contain only letters' | ||
| }, | ||
| lessThan: { | ||
| en: '{{lh}} must be less than {{rh}}' | ||
| alphaDash: { | ||
| en: '{{property}} must contain only letters and dashes' | ||
| }, | ||
| greaterThan: { | ||
| en: '{{lh}} must be greater than {{rh}}' | ||
| alphaNumeric: { | ||
| en: '{{property}} must contain only letters and numbers' | ||
| }, | ||
| lessThanOrEqualTo: { | ||
| en: '{{lh}} must be less than or equal to {{rh}}' | ||
| alphaUnderscore: { | ||
| en: '{{property}} must contain only letters and underscores' | ||
| }, | ||
| greaterThanOrEqualTo: { | ||
| en: '{{lh}} must be greater than or equal to {{rh}}' | ||
| }, | ||
| equalTo: { | ||
@@ -79,8 +109,32 @@ en: '{{lh}} must be equal to {{rh}}' | ||
| }, | ||
| greaterThan: { | ||
| en: '{{lh}} must be greater than {{rh}}' | ||
| }, | ||
| greaterThanOrEqualTo: { | ||
| en: '{{lh}} must be greater than or equal to {{rh}}' | ||
| }, | ||
| integer: { | ||
| en: '{{property}} must be a valid integer' | ||
| }, | ||
| url: { | ||
| en: '{{property}} must be a valid URL' | ||
| lengthEqualTo: { | ||
| en: '{{property}} must have {{num}} character(s)' | ||
| }, | ||
| lengthGreaterThan: { | ||
| en: '{{property}} must be greater than {{num}} character(s)' | ||
| }, | ||
| lengthGreaterThanOrEqualTo: { | ||
| en: '{{property}} must be greater than or equal to {{num}} character(s)' | ||
| }, | ||
| lengthLessThan: { | ||
| en: '{{property}} must be less than {{num}} character(s)' | ||
| }, | ||
| lengthLessThanOrEqualTo: { | ||
| en: '{{property}} must be less than or equal to {{num}} character(s)' | ||
| }, | ||
| lessThan: { | ||
| en: '{{lh}} must be less than {{rh}}' | ||
| }, | ||
| lessThanOrEqualTo: { | ||
| en: '{{lh}} must be less than or equal to {{rh}}' | ||
| }, | ||
| natural: { | ||
@@ -91,16 +145,35 @@ en: '{{property}} must be a positive number' | ||
| en: '{{property}} must be a positive number and not be zero' | ||
| }, | ||
| presence: { | ||
| en: '{{property}} is required' | ||
| }, | ||
| url: { | ||
| en: '{{property}} must be a valid URL' | ||
| } | ||
| }, | ||
| Validation = function (name, args) { | ||
| if ('function' === typeof name) { | ||
| validator = props; | ||
| } else { | ||
| validator = _VALIDATOR_(name); | ||
| Validation = function (validator, options) { | ||
| if ('string' === typeof validator) { | ||
| validator = Validators[validator]; | ||
| } | ||
| this._validator = validator; | ||
| this._args = args; | ||
| this._ifAll = {}; | ||
| this._unlessAll = {}; | ||
| this._options = options; | ||
| this._ifAll = []; | ||
| this._unlessAll = []; | ||
| if ('object' === typeof options) { | ||
| if (options.if) { | ||
| this.if(options.if); | ||
| delete options.if; | ||
| } | ||
| if (options.unless) { | ||
| this.unless(options.unless); | ||
| delete options.unless; | ||
| } | ||
| if (options.catch) { | ||
| this.catch(options.catch); | ||
| delete options.catch; | ||
| } | ||
| } | ||
| }; | ||
@@ -112,9 +185,11 @@ | ||
| if (arguments.length == 2) { | ||
| var props = arguments[0] | ||
| , fn = arguments[1] | ||
| , prop; | ||
| if ('string' === typeof props) props = [props]; | ||
| var props = arguments[0], fn = arguments[1], prop; | ||
| if ('string' == typeof props) props = [props]; | ||
| for (var key in props) { | ||
| prop = props[key]; | ||
| this.prop(prop, {if: fn}); | ||
| prop = (this._props || {})[props[key]]; | ||
| if (prop) { | ||
| if (!prop.if) prop.if = []; | ||
| prop.if.push(fn); | ||
| this._props[props[key]] = prop; | ||
| } | ||
| } | ||
@@ -129,9 +204,11 @@ } else { | ||
| if (arguments.length == 2) { | ||
| var props = arguments[0] | ||
| , fn = arguments[1] | ||
| , prop; | ||
| if ('string' === typeof props) props = [props]; | ||
| var props = arguments[0], fn = arguments[1], prop; | ||
| if ('string' == typeof props) props = [props]; | ||
| for (var key in props) { | ||
| prop = props[key]; | ||
| this.prop(prop, {unless: fn}); | ||
| prop = (this._props || {})[props[key]]; | ||
| if (prop) { | ||
| if (!prop.unless) prop.unless = []; | ||
| prop.unless.push(fn); | ||
| this._props[props[key]] = prop; | ||
| } | ||
| } | ||
@@ -146,9 +223,10 @@ } else { | ||
| if (arguments.length == 2) { | ||
| var props = arguments[0] | ||
| , fn = arguments[1] | ||
| , prop; | ||
| if ('string' === typeof props) props = [props]; | ||
| var props = arguments[0], fn = arguments[1], prop; | ||
| if ('string' == typeof props) props = [props]; | ||
| for (var key in props) { | ||
| prop = props[key]; | ||
| this.prop(prop, {if: fn}); | ||
| prop = (this._props || {})[props[key]]; | ||
| if (prop) { | ||
| prop.catch = fn; | ||
| this._props[props[key]] = prop; | ||
| } | ||
| } | ||
@@ -161,10 +239,5 @@ } else { | ||
| of: function (props, args) { | ||
| return this.prop(props, args); | ||
| }, | ||
| prop: function (props, options) { | ||
| if ('string' === typeof props) props = [props]; | ||
| prop: function (props, args) { | ||
| args = args || {}; | ||
| if ('string' === typeof props) props = [props] | ||
| var name, prop; | ||
@@ -175,16 +248,19 @@ for (var key in props) { | ||
| if (!this._props) this._props = {}; | ||
| if (!(prop = this._props[name])) prop = {}; | ||
| if (!this._props[name]) this._props[name] = {}; | ||
| if (args.if) { | ||
| if (!prop.if) prop = []; | ||
| prop.if.push(args.if); | ||
| if ('object' === typeof options) { | ||
| if (options.if) { | ||
| this.if(name, options.if); | ||
| delete options.if; | ||
| } | ||
| if (options.unless) { | ||
| this.unless(name, options.unless); | ||
| delete options.unless; | ||
| } | ||
| if (options.catch) { | ||
| this.catch(name, options.catch); | ||
| delete options.catch; | ||
| } | ||
| } | ||
| if (args.unless) { | ||
| if (!prop.unless) unless = []; | ||
| prop.unless.push(args.unless); | ||
| } | ||
| if (args.catch) { | ||
| prop.catch = args.catch; | ||
| } | ||
| this._props[name] = prop; | ||
| } | ||
@@ -197,3 +273,4 @@ | ||
| var th = this | ||
| , errors = [] | ||
| , _errors = [] | ||
| , options = th._options || {} | ||
| , fn | ||
@@ -212,3 +289,3 @@ , promise; | ||
| for (name in th._props) { | ||
| prop = th._props[name], args = th._args || []; | ||
| prop = th._props[name]; | ||
| promises.push(function(){ | ||
@@ -227,12 +304,15 @@ if (prop.if) { | ||
| } | ||
| args.unshift(obj, name); | ||
| return Promise.method(th._validator).apply(null, args) | ||
| .catch(function (error){ | ||
| if (prop.catch) { | ||
| error = prop.catch(obj); | ||
| } else { | ||
| if (th._catchAll) th._catchAll(obj); | ||
| return Promise.method(th._validator)(obj, name, th._options) | ||
| .catch(function (name, prop) { | ||
| return function (error){ | ||
| if (prop.catch) { | ||
| try { | ||
| prop.catch(obj); | ||
| } catch (e) { | ||
| error = e; | ||
| } | ||
| } | ||
| _errors.push([error, name]); | ||
| } | ||
| errors.push(error); | ||
| }) | ||
| }(name, prop)) | ||
| }()); | ||
@@ -242,12 +322,26 @@ } | ||
| } else { | ||
| args = th._args || [] | ||
| args.unshift(obj); | ||
| promise = Promise.method(th._validator).apply(null, args) | ||
| promise = Promise.method(th._validator)(obj, th._options) | ||
| .catch(function(error) { | ||
| if (th._catchAll) th._catchAll(obj); | ||
| errors.push(error); | ||
| _errors.push([error]); | ||
| }) | ||
| } | ||
| return promise.then(function () { | ||
| if (errors.length) throw errors; | ||
| var errs = [], error; | ||
| if (_errors.length) { | ||
| if (th._catchAll) { | ||
| try { | ||
| th._catchAll(obj); | ||
| } catch (e) { | ||
| _errors = [e]; | ||
| } | ||
| } | ||
| for (var key in _errors) { | ||
| error = _errors[key]; | ||
| if (!(error[0] instanceof Array)) error[0] = [error[0]]; | ||
| for (var k in error[0]) { | ||
| errs = errs.concat(new ValidationError(error[0][k], error[1])); | ||
| } | ||
| } | ||
| throw errs; | ||
| } | ||
| return th; | ||
@@ -259,57 +353,176 @@ }); | ||
| function _VALIDATOR_ (name) { | ||
| return _VALIDATORS_[name]; | ||
| function ValidatorMessage (name, options) { | ||
| this.name = name; | ||
| this.options = options; | ||
| } | ||
| function _MESSAGE_ (name, options) { | ||
| var message = _MESSAGES_[name][_LOCALE_] | ||
| return message.replace(/\{\{([a-zA-Z]+)\}\}/g, function (match, key) { | ||
| return options[key]; | ||
| }); | ||
| ValidatorMessage.prototype = { | ||
| toString: function () { | ||
| var th = this | ||
| , message = ValidatorMessages[th.name][V.locale]; | ||
| return message.replace(/\{\{([a-zA-Z]+)\}\}/g, function (match, key) { | ||
| return th.options[key]; | ||
| }); | ||
| } | ||
| } | ||
| var V = function (rules) { | ||
| this.validations = []; | ||
| if (rules) { | ||
| var rule; | ||
| for (var prop in rules) { | ||
| rule = rules[prop]; | ||
| this.validateOf(prop, rule); | ||
| var ValidationError = function (error, prop) { | ||
| this.error = error; | ||
| this.prop = prop; | ||
| } | ||
| ValidationError.prototype = { | ||
| toString: function () { | ||
| return this.error.toString(); | ||
| } | ||
| } | ||
| var ValidationErrors = function (errors, obj) { | ||
| this.errors = errors; | ||
| this.obj = obj; | ||
| } | ||
| ValidationErrors.prototype = { | ||
| toString: function () { | ||
| var strings = [], error; | ||
| for (var key in this.errors) { | ||
| error = this.errors[key]; | ||
| strings.push(error.toString()); | ||
| } | ||
| return strings.join(', '); | ||
| }, | ||
| toJSON: function () { | ||
| var obj = {}, error, prop; | ||
| for (var key in this.errors) { | ||
| error = this.errors[key]; | ||
| if (prop = error.prop) { | ||
| if (!obj[prop]) obj[prop] = []; | ||
| obj[prop].push(error.toString()); | ||
| } else { | ||
| if (!obj.base) obj.base = []; | ||
| obj.base.push(error.toString()); | ||
| } | ||
| } | ||
| return obj; | ||
| } | ||
| } | ||
| var V = function () { | ||
| this.validations = []; | ||
| this.propCatches = {}; | ||
| if (arguments[0]) this.rule.apply(this, arguments); | ||
| } | ||
| V.prototype = { | ||
| validate: function (name) { | ||
| var args = Array.prototype.splice.call(arguments, 1) | ||
| , validation = new Validation(name, args); | ||
| rule: function () { | ||
| var props, rule, options, validation; | ||
| if (arguments.length > 1) { | ||
| if ('function' === typeof arguments[0]) { | ||
| rule = arguments[0]; | ||
| options = arguments[1]; | ||
| } else { | ||
| props = arguments[0]; | ||
| if ('object' === typeof arguments[1]) { | ||
| for (var name in arguments[1]) this.rule(props, name, arguments[1][name]); | ||
| return this; | ||
| } else { | ||
| rule = arguments[1]; | ||
| options = arguments[2]; | ||
| } | ||
| } | ||
| } else { | ||
| if ('object' === typeof arguments[0]) { | ||
| for (var name in arguments[0]) this.rule(name, arguments[0][name]); | ||
| return this; | ||
| } else { | ||
| rule = arguments[0]; | ||
| } | ||
| } | ||
| validation = new Validation(rule, options); | ||
| if (props) validation.prop(props); | ||
| this.validations.push(validation); | ||
| return validation; | ||
| return this; | ||
| }, | ||
| validateOf: function (props, name) { | ||
| return this.validate.apply(this, Array.prototype.splice.call(arguments, 1)).of(props); | ||
| if: function () { | ||
| var validation; | ||
| for (var key in this.validations) { | ||
| validation = this.validations[key]; | ||
| validation.if.apply(validation, arguments); | ||
| } | ||
| return this; | ||
| }, | ||
| unless: function () { | ||
| var validation; | ||
| for (var key in this.validations) { | ||
| validation = this.validations[key]; | ||
| validation.unless.apply(validation, arguments); | ||
| } | ||
| return this; | ||
| }, | ||
| catch: function () { | ||
| var fn, props, prop; | ||
| if (arguments.length == 2) { | ||
| props = arguments[0]; | ||
| fn = arguments[1]; | ||
| if ('string' === typeof props) props = [props]; | ||
| for (var key in props) { | ||
| prop = props[key]; | ||
| this.propCatches[prop] = fn; | ||
| } | ||
| } else { | ||
| fn = arguments[0]; | ||
| this._catch = fn; | ||
| } | ||
| return this; | ||
| }, | ||
| run: function (obj) { | ||
| var errors = [], th = this; | ||
| return Promise.map(this.validations, function (validation) { | ||
| var errors = [] | ||
| , th = this; | ||
| return Promise.map(th.validations, function (validation) { | ||
| return validation.run(obj) | ||
| .catch (function (error) { | ||
| errors.push(error); | ||
| if (error instanceof Array) { | ||
| errors = errors.concat(error); | ||
| } else { | ||
| errors.push(error); | ||
| } | ||
| }); | ||
| }).then(function (){ | ||
| var errs = []; | ||
| if (errors.length) { | ||
| var error; | ||
| for (key in errors) { | ||
| error = errors[key]; | ||
| if (error instanceof Array) { | ||
| errs = errs.concat(error); | ||
| } else { | ||
| errs.push(error); | ||
| if (th._catch) { | ||
| try { | ||
| th._catch(name); | ||
| } catch (e) { | ||
| errors = [e]; | ||
| } | ||
| } else { | ||
| for (var name in th.propCatches) { | ||
| for (var key in errors) { | ||
| error = errors[key]; | ||
| if (name == error.prop) errors.splice(key, 1); | ||
| } | ||
| try { | ||
| th.propCatches[name](obj); | ||
| } catch (e) { | ||
| errors.push(e); | ||
| } | ||
| } | ||
| } | ||
| throw errs; | ||
| throw new ValidationErrors(errors, obj); | ||
| } | ||
@@ -322,5 +535,3 @@ return th; | ||
| V.setLocale = function (locale) { | ||
| _LOCALE_ = locale; | ||
| } | ||
| V.locale = 'en'; | ||
@@ -331,10 +542,10 @@ return V; | ||
| if (typeof define === 'function' && define.amd) { | ||
| define(['lodash', 'bluebird'], __); | ||
| } else if (typeof exports == 'object') { | ||
| module.exports = __(require('lodash'), require('bluebird')); | ||
| if ('function' === typeof define && define.amd) { | ||
| define(['bluebird'], __); | ||
| } else if ('object' === typeof exports) { | ||
| module.exports = __(require('bluebird')); | ||
| } else { | ||
| root.V = __(root._, root.Promise); | ||
| root.Credible = __(root.Promise); | ||
| } | ||
| })(this); |
+4
-4
| { | ||
| "name": "credible", | ||
| "version": "0.0.1", | ||
| "version": "0.0.4", | ||
| "author": "Noah Portes Chaikin <noah.porteschaikin@carrotcreative.com>", | ||
@@ -15,4 +15,3 @@ "description": "Unopinionated validation framework for node and the browser.", | ||
| "dependencies": { | ||
| "bluebird": "*", | ||
| "lodash": "*" | ||
| "bluebird": "*" | ||
| }, | ||
@@ -23,4 +22,5 @@ "scripts": { | ||
| "devDependencies": { | ||
| "mocha": "1.x" | ||
| "mocha": "1.x", | ||
| "should": "^4.6.1" | ||
| } | ||
| } |
+45
-30
| credible | ||
| ======== | ||
| [](https://travis-ci.org/nporteschaikin/credible) | ||
| Credible is a library for validating objects in node.js or the browser. While it provides several validators out of the box, credible is very _unopinionated_; mostly, credible simply provides a framework for object validation. | ||
@@ -8,7 +10,4 @@ | ||
| Credible has two dependencies: | ||
| Credible has one dependency: An A+ promise library, (i.e. [bluebird](https://github.com/petkaantonov/bluebird) or [when.js](https://github.com/cujojs/when)) | ||
| - [underscore.js](http://underscorejs.org) or [lodash](http://lodash.com/) | ||
| - An A+ promise library, a la [bluebird](https://github.com/petkaantonov/bluebird) or [when.js](https://github.com/cujojs/when) | ||
| ### Node.js | ||
@@ -23,3 +22,2 @@ | ||
| ```html | ||
| <script src="/lodash.js"></script> | ||
| <script src="/bluebird.js"></script> | ||
@@ -33,9 +31,17 @@ <script src="/credible.js"></script> | ||
| var person = { | ||
| firstName: 'Noah', | ||
| firstName: '', | ||
| lastName: 'Portes Chaikin' | ||
| email: 'foo' | ||
| } | ||
| var credible = new Credible({ | ||
| firstName: 'alpha' | ||
| lastName: 'alpha' | ||
| firstName: { | ||
| presence: true | ||
| }, | ||
| lastName: { | ||
| presence: true | ||
| }, | ||
| email: { | ||
| email: true | ||
| } | ||
| }); | ||
@@ -45,3 +51,3 @@ | ||
| .catch(function(err) { | ||
| console.log(err); | ||
| console.log(err); // [ 'firstName is required', 'email must be a valid e-mail address' ] | ||
| }) | ||
@@ -54,8 +60,3 @@ | ||
| ```javascript | ||
| var rulesObject = { | ||
| username: 'alpha', | ||
| email: ['presence', 'email'] | ||
| } | ||
| new Credible(rulesObject); | ||
| var validator = new Credible(); | ||
| ``` | ||
@@ -65,24 +66,38 @@ | ||
| Rules can either reference a native validator or be a function: | ||
| ```javascript | ||
| validator.rule() | ||
| ``` | ||
| A variadic function. | ||
| ```javascript | ||
| var rulesObject = { | ||
| username: 'alpha', | ||
| email: function (model, attribute) { | ||
| if (!email) throw 'No e-mail provided' | ||
| } | ||
| } | ||
| new Credible(rulesObject); | ||
| validator | ||
| .rule(properties, rule, options) | ||
| .rule(properties, { rule1: options, rule2: options }) | ||
| .rule({ property: { rule1: options, rule2: options }, property2: { rule1: options, rule2: options } }) | ||
| .rule(fn) | ||
| ``` | ||
| `Credible.validate()` returns a chainable object. | ||
| All rules have `if`, `unless`, and `catch` options -- pass functions. | ||
| ```javascript | ||
| var credible = new Credible() | ||
| credible.validate(''); | ||
| validator | ||
| .if([properties], fn); | ||
| .unless([properties], fn); | ||
| .catch([properties], fn); | ||
| ``` | ||
| ### To Do | ||
| - [ ] Write tests | ||
| - [ ] Finish this documentation | ||
| | Name | Description | Options | ||
| | ------------- | ------------- | | ||
| | length | | | ||
| | presence | | | ||
| | operator | | | ||
| | alpha | | | ||
| | alphaDash | | | ||
| | alphaNumeric | | | ||
| | alphaUnderscore | | | ||
| | email | | | ||
| | integer | | | ||
| | natural | | | ||
| | naturalNonZero | | | ||
| | url | | |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
23329
87.64%1
-50%8
33.33%585
102.42%2
-33.33%98
18.07%2
100%1
Infinity%- Removed
- Removed