Comparing version 0.0.1 to 0.0.4
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 | | |
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
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
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
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
1
8
585
2
98
2
1
- Removedlodash@*
- Removedlodash@4.17.21(transitive)