New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

value-validator

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

value-validator - npm Package Compare versions

Comparing version
1.0.0
to
2.0.0
+1
HISTORY.md
# History
module.exports = require('./src')
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _makeArray = require('make-array');
var _makeArray2 = _interopRequireDefault(_makeArray);
var _util = require('util');
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Validator = function () {
function Validator(rules) {
var _this = this;
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$codec = _ref.codec,
codec = _ref$codec === undefined ? default_codec : _ref$codec,
_ref$presets = _ref.presets,
presets = _ref$presets === undefined ? {} : _ref$presets;
_classCallCheck(this, Validator);
this._codec = codec;
this._presets = presets;
this._context = null;
this._rules = [];
(0, _makeArray2.default)(rules).forEach(function (rule) {
_this.add(rule);
});
}
_createClass(Validator, [{
key: 'context',
value: function context(_context) {
this._context = _context;
return this;
}
}, {
key: 'add',
value: function add(rule) {
this._add(rule);
return this;
}
}, {
key: 'validate',
value: function validate(v, callback) {
if (!callback) {
return this._validate(v);
}
this._validate(v).then(function (pass) {
callback(null, pass);
}).catch(function (err) {
console.log(err);
callback(err, false);
});
}
}, {
key: '_validate',
value: function _validate(v) {
var rules = this._rules;
// if no rules, treat it as success
if (!rules.length) {
return Promise.resolve(true);
}
var first = rules[0];
var result = rules.length === 1 ? first(v) : rules.reduce(function (prev, current, index) {
if (index === 0) {
return prev;
}
return prev instanceof Promise ? prev.then(function (pass) {
if (pass) {
return current(v);
}
return false;
})
// Not a promise
: wrap_non_promise_result(prev, current, v);
}, first(v));
return result instanceof Promise ? result : wrap_non_promise_result(result);
}
// @returns {function()} wrapped
}, {
key: '_add',
value: function _add(rule) {
if (typeof rule === 'string') {
return this._decodePreset(rule);
}
this._rules.push(this._wrapRule(rule));
}
// returns `function()`
}, {
key: '_wrapRule',
value: function _wrapRule(rule) {
if (typeof rule === 'function') {
return rule;
}
if (_util2.default.isRegExp(rule)) {
return function (v) {
return rule.test(v);
};
}
var str = rule && rule.toString ? rule.toString() : '';
throw new Error('value-validator: invalid rule "' + str + '"');
}
}, {
key: '_decodePreset',
value: function _decodePreset(rule) {
var _this2 = this;
return this._codec(rule).forEach(function (_ref2) {
var name = _ref2.name,
args = _ref2.args;
var preset = _this2._presets[name];
if (!preset) {
throw new Error('value-validator: unknown preset "' + name + '".');
}
if (typeof preset === 'function') {
_this2._rules.push(_this2._wrapWithArgs(preset, args));
return;
}
// if a preset is a set,
// then ignore args
if (_util2.default.isArray(preset)) {
preset.forEach(_this2._add, _this2);
}
});
}
}, {
key: '_wrapWithArgs',
value: function _wrapWithArgs(method, args) {
// The first argument is the value
var expectedArgLength = method.length - 1;
if (expectedArgLength !== args.length) {
var message = expectedArgLength === 1 ? 'one argument' : argLength + ' arguments.';
throw new Error('value-validator: preset "' + name + '" only accepts ' + message);
}
return function (v) {
return method.apply(undefined, [v].concat(_toConsumableArray(args)));
};
}
}]);
return Validator;
}();
Validator.defaults = function (_ref3) {
var presets = _ref3.presets,
codec = _ref3.codec;
return function (rules) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (presets) {
options.presets = presets;
}
if (codec) {
options.codec = codec;
}
return new Validator(rules, options);
};
};
exports.default = Validator;
function wrap_non_promise_result(result, next, v) {
return result instanceof Error
// If returns an error, then reject
? Promise.reject(result)
// else, as a result
: result
// Success
? next
// If has next, then go to next validator
? next(v)
// else, as success
: Promise.resolve(true)
// Failure
: Promise.resolve(false);
}
// @returns {Boolean}
function determine_pass(err, pass) {
return err ? false : pass === false ? false : true;
}
function default_codec(tester) {
return tester.split('|').filter(function (tester) {
return !!tester.trim();
}).map(function (tester) {
tester = tester.trim();
var index = tester.indexOf(':');
if (!~index) {
return {
name: tester,
args: []
};
}
var name = tester.slice(0, index).trim();
var args = tester.slice(index + 1).split(',').map(function (arg) {
return arg.trim();
});
return {
name: name,
args: args
};
});
}
import test from 'ava'
import V from '..'
const presets = {
'min-length': (v, min) => {
return v.length >= Number(min)
},
'max-length': (v, max) => {
return v.length <= Number(max)
},
mobile: (v) => {
return /1\d{10}/.test(v)
},
username: function (v) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (v === 'foo') {
return reject('foo already taken')
}
resolve(true)
}, 10)
})
},
between: (v, min, max) => {
return v.length >= Number(min) && v.length <= Number(max)
},
'min-length-6-username': [
'min-length:6',
'username'
]
}
const Validator = V.defaults({
presets
})
test.cb('simple global preset', t => {
new Validator('mobile').validate('18800001111', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('preset with arguments', t => {
new Validator('max-length:3').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('preset with improper length of arguments', t => {
try {
new Validator('max-length:1,2')
} catch (e) {
t.end()
return
}
t.fail('it should throw an error.')
t.end()
})
test.cb('multiple presets, [1, 3] test "12"', t => {
new Validator('max-length:3|min-length:1').validate('12', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('multiple presets, [1, 3] test "1234"', t => {
new Validator('max-length:3|min-length:1').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('multiple presets, [1, 3] test ""', t => {
new Validator('max-length:3|min-length:1').validate('', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:6, and username, foo, fail', t => {
new Validator('min-length:6|username').validate('foo', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('min-length-6-username, foo, fail', t => {
new Validator('min-length-6-username').validate('foo', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:3, and username, foo, fail', t => {
new Validator('min-length:3|username').validate('foo', (err, result) => {
t.is(err, 'foo already taken')
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:3, and username, bar, success', t => {
new Validator('min-length:3|username').validate('bar', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('preset with multiple arguments', t => {
new Validator('between:2,6').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})

Sorry, the diff of this file is too big to display

+17
-8
{
"name": "value-validator",
"version": "1.0.0",
"version": "2.0.0",
"description": "Low-level rule manager for validating values.",
"main": "./src",
"main": "./lib",
"scripts": {
"test": "ava --verbose --timeout=10s"
"build": "babel src --out-dir lib",
"test": "npm run build && ava --verbose --timeout=10s",
"prepublish": "npm run build"
},

@@ -17,3 +19,4 @@ "repository": {

"regexp",
"async"
"async",
"promise"
],

@@ -29,9 +32,15 @@ "engines": {

"devDependencies": {
"ava": "^0.16.0"
"ava": "^0.16.0",
"babel-cli": "^6.16.0",
"babel-plugin-syntax-trailing-function-commas": "^6.13.0",
"babel-plugin-transform-class-properties": "^6.16.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.16.0",
"babel-plugin-transform-exponentiation-operator": "^6.8.0",
"babel-plugin-transform-inline-environment-variables": "^6.8.0",
"babel-plugin-transform-object-rest-spread": "^6.16.0",
"babel-preset-es2015": "^6.16.0"
},
"dependencies": {
"async": "^2.0.1",
"make-array": "^1.0.1",
"wrap-as-async": "^1.2.2"
"make-array": "^1.0.1"
}
}
+37
-33

@@ -17,4 +17,4 @@ [![Build Status](https://travis-ci.org/kaelzhang/value-validator.svg?branch=master)](https://travis-ci.org/kaelzhang/value-validator)

Low-level rule manager for validating values.
## Install

@@ -34,33 +34,27 @@

function (v) {
const done = this.async()
asyncCheckExists(v, exists => {
if (exists) {
return done(new Error(`username "${v}" already exists.`))
}
done(null)
})
return checkExistsPromise(v)
}
])
validator.validate('foo', (err, pass) => {
err // null
validator
.valiate(value)
.then((result) => {
result // whether passes the validation
})
.catch((err) => {
err // if any error throws or returns
})
// Examples
validator.validate('foo').then(pass => {
pass // false, to short
})
validator.validate('foo.bar', (err, pass) => {
err // null
validator.validate('foo.bar').then(pass => {
pass // false, only letters, numbers and underscores.
})
validator.validate('steve', (err, pass) => {
validator.validate('steve').catch(err => {
err // maybe `new Error('username "steve" already exists.')`
pass // false
})
validator.validate('cook', (err, pass) => {
// maybe "cook" is a valid username
err // null
pass // true
})
```

@@ -70,4 +64,15 @@

- **rule** `RegExp|function()|String|Array.<mixed>` rule could be a regular expression, a function, a string (validator preset), or an array of mixed-type of the former three.
- **rule** `RegExp|function()|String|Array.<mixed>` rule could be
- regular expression,
- function either returns a `Promise` or normal value
- string (validator preset),
- or an array of mixed-type of the former three.
## .validate(value [, callback])
- **value** `any` value to be validated
- **callback** `function(err, pass)=`
returns a `Promise` if no `callback`, or `undefined`
### Sync Function-type `rule`

@@ -81,4 +86,3 @@

const validator = new Validator(v => v > 10)
validator.validate(5, (err, pass) => {
err // null
validator.validate(5).then(pass => {
pass // false

@@ -98,5 +102,4 @@ })

})
validator.validate(5, (err, pass) => {
validator.validate(5).catch(err => {
err // new Error('should larger than 10')
pass // false
})

@@ -107,12 +110,11 @@ ```

To define an asynchronous validator, we need to use the common [this.async()](https://www.npmjs.com/package/wrap-as-async) style.
To define an asynchronous validator, just returns a [`Promise`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise).
See the first example.
## Validator.defaults({preset=, codec=})
## Validator Presets
Validator presets are pre-defined abbreviation of a certain validation, or a set of validations.
```js
Validator.registerPresets({
const presets = {
// To define a function-typed preset

@@ -138,6 +140,8 @@ unique: function (v) {

]
})
}
const MyValidator = Validator.defaults({presets})
// Then we could use `username` as the test rule.
const validator = new Validator('username')
const validator = new MyValidator('username')
```

@@ -144,0 +148,0 @@

@@ -1,6 +0,7 @@

const ava = require('ava')
const Validator = require('..')
import ava from 'ava'
import Validator from '..'
const cases = [
{
// only: true,
test: /\d{2,6}/,

@@ -32,11 +33,11 @@ value: '1234'

test: function (v) {
const done = this.async()
setTimeout(() => {
if (v < 0) {
return done(null)
return new Promise((resolve, reject) => {
setTimeout(() => {
if (v < 0) {
return resolve(null)
}
}
done('not minus')
}, 10)
reject('not minus')
}, 10)
})
},

@@ -106,3 +107,3 @@ error: 'not minus',

if (err) {
t.is(err.message, error)
t.is(err.message || err, error)
} else {

@@ -109,0 +110,0 @@ t.is(err, null)

language: node_js
node_js:
# - "0.10"
# - "0.11"
# - "4.2"
# - "5.0"
# - "5.1"
# - "5.2"
# - "5.3"
- "6"
[{
test: RegExp,
message: String
}]
{}
'use strict'
const make_array = require('make-array')
const wrap = require('wrap-as-async')
const async = require('async')
const util = require('util')
class Validator {
constructor (rules, {
codec = default_codec
} = {}) {
this._codec = codec
this._context = null
this._rules = []
make_array(rules).forEach((rule) => {
this.add(rule)
})
}
context (context) {
this._context = context
return this
}
add (rule) {
this._add(rule)
return this
}
validate (v, callback) {
async.everySeries(this._rules, (tester, done) => {
const isAsync = tester.call(
this._context, v,
(err, pass) => {
err = typeof err === 'string'
? new Error(err)
: err || null
pass = determine_pass(err, pass)
done(err, pass)
}
)
}, (err, pass) => {
// async.everySeries sets `pass` as `undefined`
// if there is an error encountered.
callback(err, determine_pass(err, pass))
})
}
// @returns {function()} wrapped
_add (rule) {
if (typeof rule === 'string') {
return this._decodePreset(rule)
}
this._rules.push(this._wrapRule(rule))
}
_wrapRule (rule) {
if (typeof rule === 'function') {
return wrap(rule)
}
if (util.isRegExp(rule)) {
return wrap((v) => {
return rule.test(v)
})
}
const str = rule && rule.toString
? rule.toString()
: ''
throw new Error(`value-validator: invalid rule "${str}"`)
}
_decodePreset (rule) {
return this._codec(rule)
.forEach(({name, args}) => {
const preset = Validator.PRESETS[name]
if (!preset) {
throw new Error(`value-validator: unknown preset "${name}".`)
}
if (typeof preset === 'function') {
this._rules.push(this._wrapWithArgs(preset, args))
return
}
// if a preset is a set,
// then ignore args
if (util.isArray(preset)) {
preset.forEach(this._add, this)
}
})
}
_wrapWithArgs (method, args) {
// The first argument is the value
const expectedArgLength = method.length - 1
const wrapped = wrap(method)
if (expectedArgLength !== args.length) {
const message = expectedArgLength === 1
? `one argument`
: `${argLength} arguments.`
throw new Error(
`value-validator: preset "${name}" only accepts ${message}`
)
}
return function (v, callback) {
const realArgs = [v, ...args, callback]
return wrapped.apply(this, realArgs)
}
}
}
// @returns {Boolean}
function determine_pass (err, pass) {
return err
? false
: pass === false
? false
: true
}
function default_codec (tester) {
return tester.split('|')
.filter((tester) => {
return !!tester.trim()
})
.map((tester) => {
tester = tester.trim()
const index = tester.indexOf(':')
if (!~index) {
return {
name: tester,
args: []
}
}
const name = tester.slice(0, index).trim()
const args = tester.slice(index + 1)
.split(',')
.map((arg) => arg.trim())
return {
name,
args
}
})
}
Validator.PRESETS = {}
// Registers a global preset
Validator.registerPreset = (name, preset) => {
if (name in Validator.PRESETS) {
throw new Error(`value-validator: preset "${name}" defined.`)
}
if (typeof preset !== 'function' && !util.isArray(preset)) {
throw new TypeError(
`value-validator: preset only accepts function or array.`
)
}
Validator.PRESETS[name] = preset
return Validator
}
Validator.registerPresets = (map) => {
let key
for (key in map) {
Validator.registerPreset(key, map[key])
}
return Validator
}
module.exports = Validator
const test = require('ava')
const Validator = require('..')
Validator.registerPresets({
'min-length': (v, min) => {
return v.length >= Number(min)
},
'max-length': (v, max) => {
return v.length <= Number(max)
},
mobile: (v) => {
return /1\d{10}/.test(v)
},
username: function (v) {
const done = this.async()
setTimeout(() => {
if (v === 'foo') {
return done('foo already taken')
}
done(null)
}, 10)
},
between: (v, min, max) => {
return v.length >= Number(min) && v.length <= Number(max)
},
'min-length-6-username': [
'min-length:6',
'username'
]
})
test.cb('simple global preset', t => {
new Validator('mobile').validate('18800001111', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('preset with arguments', t => {
new Validator('max-length:3').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('preset with improper length of arguments', t => {
try {
new Validator('max-length:1,2')
} catch (e) {
t.end()
return
}
t.fail('it should throw an error.')
t.end()
})
test.cb('multiple presets, [1, 3] test "12"', t => {
new Validator('max-length:3|min-length:1').validate('12', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('multiple presets, [1, 3] test "1234"', t => {
new Validator('max-length:3|min-length:1').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('multiple presets, [1, 3] test ""', t => {
new Validator('max-length:3|min-length:1').validate('', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:6, and username, foo, fail', t => {
new Validator('min-length:6|username').validate('foo', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('min-length-6-username, foo, fail', t => {
new Validator('min-length-6-username').validate('foo', (err, result) => {
t.is(err, null)
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:3, and username, foo, fail', t => {
new Validator('min-length:3|username').validate('foo', (err, result) => {
t.is(err instanceof Error, true)
t.is(err.message, 'foo already taken')
t.is(result, false)
t.end()
})
})
test.cb('async preset, min:3, and username, bar, success', t => {
new Validator('min-length:3|username').validate('bar', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})
test.cb('preset with multiple arguments', t => {
new Validator('between:2,6').validate('1234', (err, result) => {
t.is(err, null)
t.is(result, true)
t.end()
})
})

Sorry, the diff of this file is not supported yet