Comparing version 0.6.2 to 0.6.3
"use strict"; | ||
var babelHelpers = require("./util/babelHelpers.js"); | ||
var MixedSchema = require("./mixed"), | ||
Promise = require("es6-promise").Promise, | ||
locale = require("./locale.js").array, | ||
inherits = require("./util/_").inherits; | ||
var MixedSchema = require("./mixed"); | ||
var Promise = require("es6-promise").Promise; | ||
var _require = require("./locale.js"); | ||
var mixed = _require.mixed; | ||
var locale = _require.array; | ||
var inherits = require("./util/_").inherits; | ||
module.exports = ArraySchema; | ||
@@ -64,6 +68,4 @@ | ||
required: function (msg) { | ||
var _this = this; | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, function (value) { | ||
return _this.isType(value) && !!value.length; | ||
return this.validation({ name: "required", exclusive: true, message: msg || mixed.required }, function (value) { | ||
return value && value.length > 0; | ||
}); | ||
@@ -70,0 +72,0 @@ }, |
@@ -30,8 +30,4 @@ "use strict"; | ||
return /true|1/i.test(value); | ||
}, | ||
required: function (msg) { | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, isBool); | ||
} | ||
}); |
@@ -35,6 +35,2 @@ "use strict"; | ||
required: function (msg) { | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, isDate); | ||
}, | ||
min: function (min, msg) { | ||
@@ -46,3 +42,3 @@ var limit = this.cast(min); | ||
return this.validation({ message: msg, hashKey: "min", params: { min: min } }, function (value) { | ||
return this.validation({ name: "min", exclusive: true, message: msg, params: { min: min } }, function (value) { | ||
return value && value >= limit; | ||
@@ -57,3 +53,3 @@ }); | ||
return this.validation({ hashKey: "max", message: msg || locale.max, params: { max: max } }, function (value) { | ||
return this.validation({ name: "max", exclusive: true, message: msg || locale.max, params: { max: max } }, function (value) { | ||
return !value || value <= limit; | ||
@@ -60,0 +56,0 @@ }); |
@@ -22,8 +22,3 @@ | ||
boolean: { | ||
required: "${path} is a required field" | ||
}, | ||
number: { | ||
required: "${path} is a required field", | ||
min: "${path} must be at least ${min}", | ||
@@ -37,3 +32,2 @@ max: "${path} must be less than or equal to ${max}", | ||
date: { | ||
required: "${path} is a required field", | ||
min: "${path} field must be later than ${min}", | ||
@@ -43,6 +37,6 @@ max: "${path} field must be at earlier than ${max}" | ||
object: { | ||
required: "${path} is a required field" | ||
}, | ||
boolean: {}, | ||
object: {}, | ||
array: { | ||
@@ -49,0 +43,0 @@ required: "${path} is a required field", |
@@ -23,3 +23,3 @@ "use strict"; | ||
this._options = {}; | ||
this._activeTests = {}; | ||
this._exclusive = Object.create(null); | ||
this._whitelist = new BadSet(); | ||
@@ -46,3 +46,10 @@ this._blacklist = new BadSet(); | ||
concat: function (schema) { | ||
return _.merge(this.clone(), schema.clone()); | ||
var next = _.merge(this.clone(), schema.clone()); | ||
// trim exclusive validations, take the most recent ones | ||
next.validations = _.uniq(next.validations.reverse(), function (fn, idx) { | ||
return next[fn.VALIDATION_KEY] ? fn.VALIDATION_KEY : idx; | ||
}).reverse(); | ||
return next; | ||
}, | ||
@@ -162,3 +169,3 @@ | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, function (value) { | ||
return this.validation({ name: "required", exclusive: true, message: msg || locale.required }, function (value) { | ||
return value !== undefined && _this.isType(value); | ||
@@ -180,9 +187,9 @@ }); | ||
validation: function (msg, validator, passInDoneCallback) { | ||
var opts = msg, | ||
validation: function (message, validator, passInDoneCallback) { | ||
var opts = message, | ||
next = this.clone(), | ||
hashKey, | ||
errorMsg; | ||
errorMsg, | ||
isExclusive; | ||
if (typeof msg === "string") opts = { message: msg }; | ||
if (typeof message === "string") opts = { message: message, exclusive: false, name: validator.name || undefined }; | ||
@@ -192,9 +199,17 @@ if (next._whitelist.length) throw new TypeError("Cannot add validations when specific valid values are specified"); | ||
errorMsg = interpolate(opts.message); | ||
hashKey = opts.hashKey; | ||
isExclusive = opts.name && next._exclusive[opts.name] === true; | ||
if (!hashKey || !_.has(next._activeTests, hashKey)) { | ||
if (hashKey) next._activeTests[hashKey] = true; | ||
next.validations.push(validate); | ||
if (opts.exclusive) { | ||
if (!opts.name) throw new TypeError("You cannot have an exclusive validation without a name to identify it"); | ||
next._exclusive[opts.name] = true; | ||
validate.VALIDATION_KEY = opts.name; | ||
} | ||
if (isExclusive) next.validations = next.validations.filter(function (fn) { | ||
return fn.VALIDATION_KEY !== opts.name; | ||
}); | ||
next.validations.push(validate); | ||
return next; | ||
@@ -205,11 +220,9 @@ | ||
var result = new Promise(function (resolve, reject) { | ||
return new Promise(function (resolve, reject) { | ||
!passInDoneCallback ? resolve(validator.call(_this, value)) : validator.call(_this, value, function (err, valid) { | ||
return err ? reject(err) : resolve(valid); | ||
}); | ||
}).then(function (valid) { | ||
if (!valid) throw new ValidationError(errorMsg(babelHelpers._extends({ path: state.path }, opts.params))); | ||
}); | ||
return result.then(function (valid) { | ||
if (!valid) throw new ValidationError(errorMsg(babelHelpers._extends({}, state, opts.params))); | ||
}); | ||
} | ||
@@ -216,0 +229,0 @@ }, |
@@ -31,12 +31,4 @@ "use strict"; | ||
required: function (msg) { | ||
var _this = this; | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, function (v) { | ||
return v != null && _this.isType(v); | ||
}); | ||
}, | ||
min: function (min, msg) { | ||
return this.validation({ hashKey: "min", params: { min: min }, message: msg || locale.min }, function (value) { | ||
return this.validation({ name: "min", exclusive: true, params: { min: min }, message: msg || locale.min }, function (value) { | ||
return value == null || value >= min; | ||
@@ -47,3 +39,3 @@ }); | ||
max: function (max, msg) { | ||
return this.validation({ hashKey: "max", params: { max: max }, message: msg || locale.max }, function (value) { | ||
return this.validation({ name: "max", exclusive: true, params: { max: max }, message: msg || locale.max }, function (value) { | ||
return value == null || value <= max; | ||
@@ -50,0 +42,0 @@ }); |
@@ -116,11 +116,16 @@ "use strict"; | ||
concat: function (schema) { | ||
var next = MixedSchema.prototype.concat.call(this, schema); | ||
next._nodes = sortFields(next.fields); | ||
return next; | ||
}, | ||
shape: function (schema) { | ||
var next = this.clone(), | ||
toposort = new Topo(), | ||
fields = assign(next.fields, schema); | ||
for (var key in schema) if (has(schema, key)) toposort.add(key, { after: schema[key]._deps, group: key }); | ||
next.fields = fields; | ||
next._nodes = toposort.nodes; | ||
next._nodes = sortFields(fields); | ||
@@ -130,8 +135,2 @@ return next; | ||
required: function (msg) { | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, function (value) { | ||
return value != null; | ||
}); | ||
}, | ||
from: function (from, to, alias) { | ||
@@ -167,2 +166,10 @@ return this.transform(function (obj) { | ||
} | ||
}); | ||
}); | ||
function sortFields(fields) { | ||
var toposort = new Topo(); | ||
for (var key in fields) if (has(fields, key)) toposort.add(key, { after: fields[key]._deps, group: key }); | ||
return toposort.nodes; | ||
} |
"use strict"; | ||
var MixedSchema = require("./mixed"), | ||
locale = require("./locale.js").string, | ||
inherits = require("./util/_").inherits; | ||
var MixedSchema = require("./mixed"); | ||
var _require = require("./locale.js"); | ||
var mixed = _require.mixed; | ||
var locale = _require.string; | ||
var inherits = require("./util/_").inherits; | ||
var rEmail = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; | ||
@@ -29,4 +33,4 @@ var rUrl = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; | ||
required: function (msg) { | ||
return this.validation({ hashKey: "required", message: msg || locale.required }, function (value) { | ||
return value && !!value.length; | ||
return this.validation({ name: "required", exclusive: true, message: msg || mixed.required }, function (value) { | ||
return value != null && value.length > 0; | ||
}); | ||
@@ -38,3 +42,3 @@ }, | ||
return this.validation({ hashKey: "min", message: msg, params: { min: min } }, function (value) { | ||
return this.validation({ name: "min", exclusive: true, message: msg, params: { min: min } }, function (value) { | ||
return value == null || value.length >= min; | ||
@@ -46,3 +50,3 @@ }); | ||
msg = msg || locale.max; | ||
return this.validation({ hashKey: "max", message: msg, params: { max: max } }, function (value) { | ||
return this.validation({ name: "max", exclusive: true, message: msg, params: { max: max } }, function (value) { | ||
return value == null || value.length <= max; | ||
@@ -49,0 +53,0 @@ }); |
@@ -16,2 +16,6 @@ | ||
var isSchema = function (obj) { | ||
return obj && obj.__isYupSchema__; | ||
}; | ||
function assign(target) { | ||
@@ -27,2 +31,13 @@ for (var i = 1; i < arguments.length; i++) { | ||
function uniq(arr, iter) { | ||
var seen = {}; | ||
return arr.filter(function (item, idx) { | ||
var key = iter(item, idx); | ||
if (has(seen, key)) return false; | ||
return seen[key] = true; | ||
}); | ||
} | ||
function transform(obj, cb, seed) { | ||
@@ -38,6 +53,15 @@ cb = cb.bind(null, seed = seed || (Array.isArray(obj) ? [] : {})); | ||
for (var key in source) if (has(source, key)) { | ||
var targetVal = target[key]; | ||
var sourceVal = source[key]; | ||
var targetVal = target[key], | ||
sourceVal = source[key], | ||
sameType; | ||
if (isObject(targetVal) || isObject(sourceVal)) target[key] = merge(targetVal, sourceVal);else if (Array.isArray(targetVal) || Array.isArray(sourceVal)) target[key] = sourceVal.concat ? sourceVal.concat(targetVal) : targetVal.concat(sourceVal);else target[key] = source[key]; | ||
if (sourceVal === undefined) continue; | ||
if (isSchema(sourceVal)) { | ||
target[key] = isSchema(targetVal) ? targetVal.concat(sourceVal) : sourceVal; | ||
} else if (isObject(sourceVal)) { | ||
target[key] = isObject(targetVal) ? merge(targetVal, sourceVal) : sourceVal; | ||
} else if (Array.isArray(sourceVal)) { | ||
target[key] = Array.isArray(targetVal) ? targetVal.concat(sourceVal) : sourceVal; | ||
} else target[key] = source[key]; | ||
} | ||
@@ -67,3 +91,3 @@ | ||
module.exports = { | ||
inherits: inherits, has: has, assign: assign, merge: merge, transform: transform, isObject: isObject, isPlainObject: isPlainObject, isDate: isDate | ||
inherits: inherits, uniq: uniq, has: has, assign: assign, merge: merge, transform: transform, isSchema: isSchema, isObject: isObject, isPlainObject: isPlainObject, isDate: isDate | ||
}; |
{ | ||
"name": "yup", | ||
"version": "0.6.2", | ||
"version": "0.6.3", | ||
"description": "Dead simple Object schema validation", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
'use strict'; | ||
var MixedSchema = require('./mixed') | ||
, Promise = require('es6-promise').Promise | ||
, locale = require('./locale.js').array | ||
, { mixed, array: locale } = require('./locale.js') | ||
, inherits = require('./util/_').inherits; | ||
@@ -69,4 +69,4 @@ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
value => this.isType(value) && !!value.length) | ||
{ name: 'required', exclusive: true, message: msg || mixed.required } | ||
, value => value && value.length > 0) | ||
}, | ||
@@ -73,0 +73,0 @@ |
@@ -29,8 +29,2 @@ 'use strict'; | ||
return (/true|1/i).test(value) | ||
}, | ||
required(msg){ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
isBool) | ||
} | ||
@@ -37,0 +31,0 @@ |
@@ -35,8 +35,2 @@ 'use strict'; | ||
required(msg){ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
isDate) | ||
}, | ||
min(min, msg){ | ||
@@ -50,3 +44,3 @@ var limit = this.cast(min); | ||
return this.validation( | ||
{ message: msg, hashKey: 'min', params: { min: min } } | ||
{ name: 'min', exclusive: true, message: msg, params: { min: min } } | ||
, value => value && (value >= limit)) | ||
@@ -62,3 +56,3 @@ }, | ||
return this.validation( | ||
{ hashKey: 'max', message: msg || locale.max, params: { max: max } } | ||
{ name: 'max', exclusive: true, message: msg || locale.max, params: { max: max } } | ||
, value => !value || (value <= limit)) | ||
@@ -65,0 +59,0 @@ } |
@@ -22,8 +22,3 @@ | ||
boolean: { | ||
required: '${path} is a required field' | ||
}, | ||
number: { | ||
required: '${path} is a required field', | ||
min: '${path} must be at least ${min}', | ||
@@ -37,3 +32,2 @@ max: '${path} must be less than or equal to ${max}', | ||
date: { | ||
required: '${path} is a required field', | ||
min: '${path} field must be later than ${min}', | ||
@@ -43,6 +37,6 @@ max: '${path} field must be at earlier than ${max}' | ||
object: { | ||
required: '${path} is a required field' | ||
}, | ||
boolean: {}, | ||
object: {}, | ||
array: { | ||
@@ -49,0 +43,0 @@ required: '${path} is a required field', |
@@ -21,3 +21,3 @@ 'use strict'; | ||
this._options = {} | ||
this._activeTests = {} | ||
this._exclusive = Object.create(null) | ||
this._whitelist = new BadSet() | ||
@@ -45,3 +45,9 @@ this._blacklist = new BadSet() | ||
concat(schema){ | ||
return _.merge(this.clone(), schema.clone()) | ||
var next = _.merge(this.clone(), schema.clone()) | ||
// trim exclusive validations, take the most recent ones | ||
next.validations = _.uniq(next.validations.reverse(), | ||
(fn, idx) => next[fn.VALIDATION_KEY] ? fn.VALIDATION_KEY : idx).reverse() | ||
return next | ||
}, | ||
@@ -169,3 +175,3 @@ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
{ name: 'required', exclusive: true, message: msg || locale.required }, | ||
value => value !== undefined && this.isType(value)) | ||
@@ -186,9 +192,9 @@ }, | ||
validation(msg, validator, passInDoneCallback){ | ||
var opts = msg | ||
validation(message, validator, passInDoneCallback) { | ||
var opts = message | ||
, next = this.clone() | ||
, hashKey, errorMsg; | ||
, errorMsg, isExclusive; | ||
if(typeof msg === 'string') | ||
opts = { message: msg } | ||
if(typeof message === 'string') | ||
opts = { message, exclusive: false, name: validator.name || undefined } | ||
@@ -199,13 +205,21 @@ if( next._whitelist.length ) | ||
errorMsg = interpolate(opts.message) | ||
hashKey = opts.hashKey | ||
isExclusive = opts.name && next._exclusive[opts.name] === true | ||
if( !hashKey || !_.has(next._activeTests, hashKey) ){ | ||
if( hashKey ) next._activeTests[hashKey] = true | ||
next.validations.push(validate) | ||
if( opts.exclusive ){ | ||
if (!opts.name) | ||
throw new TypeError('You cannot have an exclusive validation without a name to identify it') | ||
next._exclusive[opts.name] = true | ||
validate.VALIDATION_KEY = opts.name | ||
} | ||
if( isExclusive ) | ||
next.validations = next.validations.filter( fn => fn.VALIDATION_KEY !== opts.name) | ||
next.validations.push(validate) | ||
return next | ||
function validate(value, state) { | ||
var result = new Promise((resolve, reject) => { | ||
return new Promise((resolve, reject) => { | ||
!passInDoneCallback | ||
@@ -215,8 +229,6 @@ ? resolve(validator.call(this, value)) | ||
}) | ||
return result | ||
.then(function(valid){ | ||
if (!valid) | ||
throw new ValidationError(errorMsg({ ...state, ...opts.params })) | ||
}) | ||
.then(valid => { | ||
if (!valid) | ||
throw new ValidationError(errorMsg({ path: state.path, ...opts.params })) | ||
}) | ||
} | ||
@@ -223,0 +235,0 @@ }, |
@@ -28,11 +28,5 @@ 'use strict'; | ||
required(msg){ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required } | ||
, v => v != null && this.isType(v)) | ||
}, | ||
min(min, msg) { | ||
return this.validation( | ||
{ hashKey: 'min', params: { min: min }, message: msg || locale.min } | ||
{ name: 'min', exclusive: true, params: { min: min }, message: msg || locale.min } | ||
, value => value == null || value >= min) | ||
@@ -43,3 +37,3 @@ }, | ||
return this.validation( | ||
{ hashKey: 'max', params: { max: max }, message: msg || locale.max } | ||
{ name: 'max', exclusive: true, params: { max: max }, message: msg || locale.max } | ||
, value => value == null || value <= max) | ||
@@ -46,0 +40,0 @@ }, |
@@ -36,3 +36,4 @@ 'use strict'; | ||
value = JSON.parse(value) | ||
} catch (err){ value = null } | ||
} | ||
catch (err){ value = null } | ||
} | ||
@@ -122,12 +123,16 @@ | ||
concat(schema){ | ||
var next = MixedSchema.prototype.concat.call(this, schema) | ||
next._nodes = sortFields(next.fields) | ||
return next | ||
}, | ||
shape(schema) { | ||
var next = this.clone() | ||
, toposort = new Topo() | ||
, fields = assign(next.fields, schema); | ||
for( var key in schema ) if ( has(schema, key)) | ||
toposort.add(key, { after: schema[key]._deps, group: key }) | ||
next.fields = fields | ||
next._nodes = toposort.nodes | ||
next._nodes = sortFields(fields) | ||
@@ -137,8 +142,2 @@ return next | ||
required(msg) { | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
value => value != null) | ||
}, | ||
from(from, to, alias) { | ||
@@ -169,1 +168,9 @@ return this.transform( obj => { | ||
function sortFields(fields){ | ||
var toposort = new Topo() | ||
for( var key in fields ) if ( has(fields, key)) | ||
toposort.add(key, { after: fields[key]._deps, group: key }) | ||
return toposort.nodes | ||
} |
'use strict'; | ||
var MixedSchema = require('./mixed') | ||
, locale = require('./locale.js').string | ||
, { mixed, string: locale } = require('./locale.js') | ||
, inherits = require('./util/_').inherits; | ||
@@ -32,4 +32,4 @@ | ||
return this.validation( | ||
{ hashKey: 'required', message: msg || locale.required }, | ||
value => value && !!value.length) | ||
{ name: 'required', exclusive: true, message: msg || mixed.required } | ||
, value => value != null && value.length > 0) | ||
}, | ||
@@ -41,3 +41,3 @@ | ||
return this.validation( | ||
{ hashKey: 'min', message: msg, params: { min: min } } | ||
{ name: 'min', exclusive: true, message: msg, params: { min: min } } | ||
, value => value == null || value.length >= min) | ||
@@ -49,3 +49,3 @@ }, | ||
return this.validation( | ||
{ hashKey: 'max', message: msg, params: { max: max } } | ||
{ name: 'max', exclusive: true, message: msg, params: { max: max } } | ||
, value => value == null || value.length <= max) | ||
@@ -52,0 +52,0 @@ }, |
@@ -10,2 +10,5 @@ | ||
let isSchema = obj => obj && obj.__isYupSchema__ | ||
function assign(target) { | ||
@@ -22,2 +25,13 @@ for (var i = 1; i < arguments.length; i++) { | ||
function uniq(arr, iter){ | ||
var seen = {} | ||
return arr.filter( (item, idx) => { | ||
var key = iter(item,idx) | ||
if ( has(seen, key) ) return false | ||
return seen[key] = true | ||
}) | ||
} | ||
function transform(obj, cb, seed){ | ||
@@ -38,11 +52,23 @@ cb = cb.bind(null, seed = seed || (Array.isArray(obj) ? [] : {})) | ||
var targetVal = target[key] | ||
var sourceVal = source[key] | ||
, sourceVal = source[key] | ||
, sameType; | ||
if ( isObject(targetVal) || isObject(sourceVal) ) | ||
target[key] = merge(targetVal, sourceVal) | ||
if ( sourceVal === undefined ) | ||
continue | ||
else if ( Array.isArray(targetVal) || Array.isArray(sourceVal)) | ||
target[key] = sourceVal.concat | ||
? sourceVal.concat(targetVal) | ||
: targetVal.concat(sourceVal); | ||
if ( isSchema(sourceVal) ) { | ||
target[key] = isSchema(targetVal) | ||
? targetVal.concat(sourceVal) | ||
: sourceVal | ||
} | ||
else if ( isObject(sourceVal) ) { | ||
target[key] = isObject(targetVal) | ||
? merge(targetVal, sourceVal) | ||
: sourceVal | ||
} | ||
else if ( Array.isArray(sourceVal) ) { | ||
target[key] = Array.isArray(targetVal) | ||
? targetVal.concat(sourceVal) | ||
: sourceVal | ||
} | ||
else | ||
@@ -74,3 +100,3 @@ target[key] = source[key]; | ||
module.exports = { | ||
inherits, has, assign, merge, transform, isObject, isPlainObject, isDate | ||
inherits, uniq, has, assign, merge, transform, isSchema, isObject, isPlainObject, isDate | ||
} |
@@ -8,3 +8,5 @@ 'use strict'; | ||
, mixed = require('../lib/mixed') | ||
, string = require('../lib/string'); | ||
, object = require('../lib/object') | ||
, string = require('../lib/string') | ||
, reach = require('../lib/util/reach'); | ||
@@ -38,3 +40,3 @@ chai.use(chaiAsPromised); | ||
inst.validate(6).should.be.rejected.then(function(err){ | ||
inst.validate(6).should.be.rejected.then(function(err) { | ||
err.errors[0].should.equal('this must be one the following values: hello, 5') | ||
@@ -71,2 +73,39 @@ }) | ||
it('should respect exclusive validation', function(){ | ||
var inst = mixed() | ||
.validation({ msg: 'invalid', exclusive: true, name: 'test'}, function(){}) | ||
.validation({ msg: 'also invalid', name: 'test'}, function(){}) | ||
inst.validations.length.should.equal(1) | ||
inst = mixed() | ||
.validation({ msg: 'invalid', name: 'test'}, function(){}) | ||
.validation({ msg: 'also invalid', name: 'test'}, function(){}) | ||
inst.validations.length.should.equal(2) | ||
}) | ||
it('exclusive validations should throw without a name', function(){ | ||
;(function(){ | ||
mixed().validation({ msg: 'invalid', exclusive: true }, function(){}) | ||
}).should.throw() | ||
}) | ||
it('exclusive validations should replace previous ones', function(){ | ||
var inst = mixed().validation({ message: 'invalid', exclusive: true, name: 'max'}, function(v){ | ||
return v < 5 | ||
}) | ||
return Promise.all([ | ||
inst.isValid(8).should.eventually.become(false), | ||
inst.validation({ message: 'invalid', exclusive: true, name: 'max'}, function(v){ | ||
return v < 10 | ||
}) | ||
.isValid(8).should.eventually.become(true) | ||
]) | ||
}) | ||
it('should allow custom validation of either style', function(){ | ||
@@ -108,2 +147,40 @@ var inst = string() | ||
it('should concat schemas', function(){ | ||
var inst = object({ | ||
str: string().required(), | ||
obj: object({ | ||
str: string() | ||
}) | ||
}) | ||
var next = inst.concat(object({ | ||
str: string().required().trim(), | ||
str2: string().required(), | ||
obj: object({ | ||
str: string().required() | ||
}) | ||
})) | ||
reach(next, 'str').validations.length.should.equal(2) // presence and length | ||
reach(next, 'str').validations[0].VALIDATION_KEY.should.equal('required') // make sure they are in the right order | ||
return Promise.all([ | ||
inst.isValid({ str: 'hi', str2: 'hi', obj: {} }).should.become(true), | ||
next.validate({ str: ' hi ', str2: 'hi', obj: { str: 'hi' } }).should.be.fulfilled.then(function(value){ | ||
value.should.deep.eql({ str: 'hi', str2: 'hi', obj: {str: 'hi'} }) | ||
}), | ||
next.validate({ str: 'hi', str2: 'hi', obj: {} }).should.be.rejected.then(function(err){ | ||
err.message.should.contain('this.obj.str is a required field') | ||
}), | ||
next.validate({ str2: 'hi', obj: { str: 'hi'} }).should.be.rejected.then(function(err){ | ||
err.message.should.contain('this.str is a required field') | ||
}) | ||
]) | ||
}) | ||
it('should handle conditionals', function(){ | ||
@@ -110,0 +187,0 @@ var inst = mixed().when('prop', { is: 5, then: mixed().required() }) |
@@ -82,2 +82,5 @@ 'use strict'; | ||
v.isValid(35738787838).should.eventually.equal(true), | ||
v.min(10).min(15).isValid(14).should.eventually.equal(false), | ||
v.isValid(new Date).should.eventually.equal(true), | ||
@@ -102,2 +105,4 @@ | ||
v.max(10).max(15).isValid(16).should.eventually.equal(false), | ||
v.isValid(null).should.eventually.equal(false), // null -> NaN fails type check | ||
@@ -104,0 +109,0 @@ |
@@ -8,3 +8,4 @@ 'use strict'; | ||
, bool = require('../lib/boolean') | ||
, object = require('../lib/object'); | ||
, object = require('../lib/object') | ||
, _ = require('../lib/util/_'); | ||
@@ -17,7 +18,32 @@ | ||
it('should export', function(){ | ||
var yup = require('../lib') | ||
}) | ||
it('should uniq', function(){ | ||
_.uniq([1, 1, 2, 3, 4, 3], function(i){ return i}) | ||
.should.eql([1, 2, 3, 4]) | ||
_.uniq([{ a: 1}, { a: 2}, { a: 3}, { a: 1}], function(i){ return i.a}) | ||
.should.deep.eql([{ a: 1}, { a: 2}, { a: 3}]) | ||
}) | ||
it('should merge', function(){ | ||
var a = { a: 1, b: 'hello', c: [1,2,3], d: { a: /hi/ }, e: { b: 5} } | ||
var b = { a: 4, c: [4,5,3], d: { b: 'hello' }, f: { c: 5}, g: null } | ||
_.merge(a, b).should.deep.eql({ | ||
a: 4, | ||
b: 'hello', | ||
c: [1,2,3, 4,5,3], | ||
d: { | ||
a: /hi/, | ||
b: 'hello' | ||
}, | ||
e: { b: 5 }, | ||
f: { c: 5 }, | ||
g: null | ||
}) | ||
}) | ||
it('should REACH correctly', function(done){ | ||
@@ -40,3 +66,3 @@ var num = number() | ||
reach(inst, 'nested.arr[].num').isValid(5, function(err, valid){ | ||
reach(inst, 'nested.arr[].num').isValid(5, function(err, valid) { | ||
valid.should.equal(true) | ||
@@ -47,2 +73,4 @@ done() | ||
// it.only('should REACH with conditions', function(){ | ||
@@ -49,0 +77,0 @@ // var num = number() |
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
139379
3089