Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

credible

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

credible - npm Package Compare versions

Comparing version 0.0.1 to 0.0.4

.travis.yml

519

index.js
(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);
{
"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"
}
}
credible
========
[![Build Status](https://travis-ci.org/nporteschaikin/credible.svg)](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 | |
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc