Comparing version 0.29.3 to 0.30.0
@@ -0,1 +1,30 @@ | ||
# [0.30.0](https://github.com/jquense/yup/compare/v0.29.3...v0.30.0) (2020-11-19) | ||
### Bug Fixes | ||
* defined() so it doesn't mark a schema as nullable ([f08d507](https://github.com/jquense/yup/commit/f08d507)) | ||
* IE11 clone() ([#1029](https://github.com/jquense/yup/issues/1029)) ([7fd80aa](https://github.com/jquense/yup/commit/7fd80aa)) | ||
* security Fix for Prototype Pollution - huntr.dev ([#1088](https://github.com/jquense/yup/issues/1088)) ([15a0f43](https://github.com/jquense/yup/commit/15a0f43)) | ||
* uuid's regexp ([#1112](https://github.com/jquense/yup/issues/1112)) ([57d42a8](https://github.com/jquense/yup/commit/57d42a8)) | ||
### Features | ||
* exposes context on mixed.test function and add originalValue to context ([#1021](https://github.com/jquense/yup/issues/1021)) ([6096064](https://github.com/jquense/yup/commit/6096064)) | ||
### Performance Improvements | ||
* reduce function calls for shallower stacks ([#1022](https://github.com/jquense/yup/issues/1022)) ([01da7e1](https://github.com/jquense/yup/commit/01da7e1)) | ||
### BREAKING CHANGES | ||
* defined() now doesn't automatically allow null, this was a bug. to mimic the old behavior add nullable() to schema with defined() | ||
## [0.29.3](https://github.com/jquense/yup/compare/v0.29.2...v0.29.3) (2020-08-04) | ||
@@ -2,0 +31,0 @@ |
@@ -1,32 +0,9 @@ | ||
import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/esm/taggedTemplateLiteralLoose"; | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
function _templateObject2() { | ||
var data = _taggedTemplateLiteralLoose(["", "[", "]"]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = _taggedTemplateLiteralLoose(["", "[", "]"]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
import inherits from './util/inherits'; | ||
import isAbsent from './util/isAbsent'; | ||
import isSchema from './util/isSchema'; | ||
import makePath from './util/makePath'; | ||
import printValue from './util/printValue'; | ||
import MixedSchema from './mixed'; | ||
import { array as locale } from './locale'; | ||
import runValidations, { propagateErrors } from './util/runValidations'; | ||
import runTests from './util/runTests'; | ||
export default ArraySchema; | ||
@@ -73,3 +50,3 @@ | ||
var castElement = _this2.innerType.cast(v, _extends({}, _opts, { | ||
path: makePath(_templateObject(), _opts.path, idx) | ||
path: (_opts.path || '') + "[" + idx + "]" | ||
})); | ||
@@ -85,3 +62,3 @@ | ||
}, | ||
_validate: function _validate(_value, options) { | ||
_validate: function _validate(_value, options, callback) { | ||
var _this3 = this; | ||
@@ -103,6 +80,13 @@ | ||
var originalValue = options.originalValue != null ? options.originalValue : _value; | ||
return MixedSchema.prototype._validate.call(this, _value, options).catch(propagateErrors(endEarly, errors)).then(function (value) { | ||
MixedSchema.prototype._validate.call(this, _value, options, function (err, value) { | ||
if (err) { | ||
if (endEarly) return void callback(err); | ||
errors.push(err); | ||
value = err.value; | ||
} | ||
if (!recursive || !innerType || !_this3._typeCheck(value)) { | ||
if (errors.length) throw errors[0]; | ||
return value; | ||
callback(errors[0] || null, value); | ||
return; | ||
} | ||
@@ -112,12 +96,10 @@ | ||
var validations = new Array(value.length); | ||
var tests = new Array(value.length); | ||
for (var idx = 0; idx < value.length; idx++) { | ||
var _loop = function _loop(idx) { | ||
var item = value[idx]; | ||
var path = (options.path || '') + "[" + idx + "]"; // object._validate note for isStrict explanation | ||
var _path = makePath(_templateObject2(), options.path, idx); // object._validate note for isStrict explanation | ||
var innerOptions = _extends({}, options, { | ||
path: _path, | ||
path: path, | ||
strict: true, | ||
@@ -129,6 +111,12 @@ parent: value, | ||
validations[idx] = innerType.validate ? innerType.validate(item, innerOptions) : true; | ||
tests[idx] = function (_, cb) { | ||
return innerType.validate ? innerType.validate(item, innerOptions, cb) : cb(null); | ||
}; | ||
}; | ||
for (var idx = 0; idx < value.length; idx++) { | ||
_loop(idx); | ||
} | ||
return runValidations({ | ||
runTests({ | ||
sync: sync, | ||
@@ -139,4 +127,4 @@ path: path, | ||
endEarly: endEarly, | ||
validations: validations | ||
}); | ||
tests: tests | ||
}, callback); | ||
}); | ||
@@ -143,0 +131,0 @@ }, |
@@ -46,3 +46,3 @@ import has from "lodash-es/has"; | ||
var values = this.refs.map(function (ref) { | ||
return ref.getValue(options); | ||
return ref.getValue(options == null ? void 0 : options.value, options == null ? void 0 : options.parent, options == null ? void 0 : options.context); | ||
}); | ||
@@ -49,0 +49,0 @@ var schema = this.fn.apply(base, values.concat(base, options)); |
@@ -22,4 +22,4 @@ import isSchema from './util/isSchema'; | ||
_proto.validate = function validate(value, options) { | ||
return this._resolve(value, options).validate(value, options); | ||
_proto.validate = function validate(value, options, maybeCb) { | ||
return this._resolve(value, options).validate(value, options, maybeCb); | ||
}; | ||
@@ -26,0 +26,0 @@ |
@@ -0,1 +1,2 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import printValue from './util/printValue'; | ||
@@ -57,3 +58,3 @@ export var mixed = { | ||
}; | ||
export default { | ||
export default _extends(Object.create(null), { | ||
mixed: mixed, | ||
@@ -66,2 +67,2 @@ string: string, | ||
boolean: boolean | ||
}; | ||
}); |
114
es/mixed.js
@@ -15,3 +15,3 @@ import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import Condition from './Condition'; | ||
import runValidations from './util/runValidations'; | ||
import runTests from './util/runTests'; | ||
import prependDeep from './util/prependDeep'; | ||
@@ -143,4 +143,8 @@ import isSchema from './util/isSchema'; | ||
return cloneDeepWith(this, function (value) { | ||
if (isSchema(value) && value !== _this2) return value; | ||
return cloneDeepWith(this, function (value, key) { | ||
if (isSchema(value) && value !== _this2) return value; // fix for ie11 when cloning Set and Map | ||
if (key === '_whitelist' || key === '_blacklist') { | ||
return value.clone(); | ||
} | ||
}); | ||
@@ -206,2 +210,10 @@ }, | ||
}, | ||
/** | ||
* | ||
* @param {*} value | ||
* @param {Object} options | ||
* @param {*=} options.parent | ||
* @param {*=} options.context | ||
*/ | ||
cast: function cast(value, options) { | ||
@@ -212,5 +224,5 @@ if (options === void 0) { | ||
var resolvedSchema = this.resolve(_extends({}, options, { | ||
var resolvedSchema = this.resolve(_extends({ | ||
value: value | ||
})); | ||
}, options)); | ||
@@ -240,3 +252,3 @@ var result = resolvedSchema._cast(value, options); | ||
}, | ||
_validate: function _validate(_value, options) { | ||
_validate: function _validate(_value, options, cb) { | ||
var _this4 = this; | ||
@@ -248,57 +260,58 @@ | ||
var _options = options, | ||
sync = _options.sync, | ||
path = _options.path, | ||
_options$from = _options.from, | ||
from = _options$from === void 0 ? [] : _options$from, | ||
_options$originalValu = _options.originalValue, | ||
originalValue = _options$originalValu === void 0 ? _value : _options$originalValu, | ||
_options$strict = _options.strict, | ||
strict = _options$strict === void 0 ? this._options.strict : _options$strict, | ||
_options$abortEarly = _options.abortEarly, | ||
abortEarly = _options$abortEarly === void 0 ? this._options.abortEarly : _options$abortEarly; | ||
var value = _value; | ||
var originalValue = options.originalValue != null ? options.originalValue : _value; | ||
var isStrict = this._option('strict', options); | ||
var endEarly = this._option('abortEarly', options); | ||
var sync = options.sync; | ||
var path = options.path; | ||
var label = this._label; | ||
if (!isStrict) { | ||
if (!strict) { | ||
this._validating = true; | ||
value = this._cast(value, _extends({ | ||
assert: false | ||
}, options)); | ||
this._validating = false; | ||
} // value is cast, we can check if it meets type requirements | ||
var validationParams = { | ||
var args = { | ||
value: value, | ||
path: path, | ||
schema: this, | ||
options: options, | ||
label: label, | ||
originalValue: originalValue, | ||
sync: sync | ||
schema: this, | ||
label: this._label, | ||
sync: sync, | ||
from: from | ||
}; | ||
if (options.from) { | ||
validationParams.from = options.from; | ||
} | ||
var initialTests = []; | ||
if (this._typeError) initialTests.push(this._typeError(validationParams)); | ||
if (this._whitelistError) initialTests.push(this._whitelistError(validationParams)); | ||
if (this._blacklistError) initialTests.push(this._blacklistError(validationParams)); | ||
return runValidations({ | ||
validations: initialTests, | ||
endEarly: endEarly, | ||
if (this._typeError) initialTests.push(this._typeError); | ||
if (this._whitelistError) initialTests.push(this._whitelistError); | ||
if (this._blacklistError) initialTests.push(this._blacklistError); | ||
return runTests({ | ||
args: args, | ||
value: value, | ||
path: path, | ||
sync: sync | ||
}).then(function (value) { | ||
return runValidations({ | ||
sync: sync, | ||
tests: initialTests, | ||
endEarly: abortEarly | ||
}, function (err) { | ||
if (err) return void cb(err); | ||
runTests({ | ||
tests: _this4.tests, | ||
args: args, | ||
path: path, | ||
sync: sync, | ||
value: value, | ||
endEarly: endEarly, | ||
validations: _this4.tests.map(function (fn) { | ||
return fn(validationParams); | ||
}) | ||
}); | ||
endEarly: abortEarly | ||
}, cb); | ||
}); | ||
}, | ||
validate: function validate(value, options) { | ||
validate: function validate(value, options, maybeCb) { | ||
if (options === void 0) { | ||
@@ -310,4 +323,9 @@ options = {}; | ||
value: value | ||
})); | ||
return schema._validate(value, options); | ||
})); // callback case is for nested validations | ||
return typeof maybeCb === 'function' ? schema._validate(value, options, maybeCb) : new Promise(function (resolve, reject) { | ||
return schema._validate(value, options, function (err, value) { | ||
if (err) reject(err);else resolve(value); | ||
}); | ||
}); | ||
}, | ||
@@ -322,13 +340,11 @@ validateSync: function validateSync(value, options) { | ||
})); | ||
var result, err; | ||
var result; | ||
schema._validate(value, _extends({}, options, { | ||
sync: true | ||
})).then(function (r) { | ||
return result = r; | ||
}).catch(function (e) { | ||
return err = e; | ||
}), function (err, value) { | ||
if (err) throw err; | ||
result = value; | ||
}); | ||
if (err) throw err; | ||
return result; | ||
@@ -602,3 +618,3 @@ }, | ||
return this.nullable().test({ | ||
return this.test({ | ||
message: message, | ||
@@ -605,0 +621,0 @@ name: 'defined', |
192
es/object.js
@@ -1,34 +0,9 @@ | ||
import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/esm/taggedTemplateLiteralLoose"; | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
function _templateObject3() { | ||
var data = _taggedTemplateLiteralLoose(["", "[\"", "\"]"]); | ||
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); } | ||
_templateObject3 = function _templateObject3() { | ||
return data; | ||
}; | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
return data; | ||
} | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } | ||
function _templateObject2() { | ||
var data = _taggedTemplateLiteralLoose(["", ".", ""]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = _taggedTemplateLiteralLoose(["", ".", ""]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
import has from "lodash-es/has"; | ||
@@ -45,5 +20,3 @@ import _snakeCase from "lodash-es/snakeCase"; | ||
import inherits from './util/inherits'; | ||
import makePath from './util/makePath'; | ||
import runValidations, { propagateErrors } from './util/runValidations'; | ||
import { SynchronousPromise } from 'synchronous-promise'; | ||
import runTests from './util/runTests'; | ||
@@ -54,6 +27,2 @@ var isObject = function isObject(obj) { | ||
var promise = function promise(sync) { | ||
return sync ? SynchronousPromise : Promise; | ||
}; | ||
function unknown(ctx, value) { | ||
@@ -86,2 +55,3 @@ var known = Object.keys(ctx.fields); | ||
this.fields = Object.create(null); | ||
this._sortErrors = sortByKeyOrder([]); | ||
this._nodes = []; | ||
@@ -119,3 +89,3 @@ this._excludedEdges = []; | ||
var value = MixedSchema.prototype._cast.call(this, _value, options); //should ignore nulls here | ||
var value = MixedSchema.prototype._cast.call(this, _value); //should ignore nulls here | ||
@@ -140,3 +110,5 @@ | ||
var isChanged = false; | ||
props.forEach(function (prop) { | ||
for (var _iterator = _createForOfIteratorHelperLoose(props), _step; !(_step = _iterator()).done;) { | ||
var prop = _step.value; | ||
var field = fields[prop]; | ||
@@ -146,6 +118,6 @@ var exists = has(value, prop); | ||
if (field) { | ||
var fieldValue; | ||
var fieldValue = void 0; | ||
var strict = field._options && field._options.strict; // safe to mutate since this is fired in sequence | ||
innerOptions.path = makePath(_templateObject(), options.path, prop); | ||
innerOptions.path = (options.path ? options.path + "." : '') + prop; | ||
innerOptions.value = value[prop]; | ||
@@ -156,14 +128,47 @@ field = field.resolve(innerOptions); | ||
isChanged = isChanged || prop in value; | ||
return; | ||
continue; | ||
} | ||
fieldValue = !options.__validating || !strict ? field.cast(value[prop], innerOptions) : value[prop]; | ||
if (fieldValue !== undefined) intermediateValue[prop] = fieldValue; | ||
} else if (exists && !strip) intermediateValue[prop] = value[prop]; | ||
if (intermediateValue[prop] !== value[prop]) isChanged = true; | ||
}); | ||
if (fieldValue !== undefined) { | ||
intermediateValue[prop] = fieldValue; | ||
} | ||
} else if (exists && !strip) { | ||
intermediateValue[prop] = value[prop]; | ||
} | ||
if (intermediateValue[prop] !== value[prop]) { | ||
isChanged = true; | ||
} | ||
} | ||
return isChanged ? intermediateValue : value; | ||
}, | ||
_validate: function _validate(_value, opts) { | ||
/** | ||
* @typedef {Object} Ancestor | ||
* @property {Object} schema - a string property of SpecialType | ||
* @property {*} value - a number property of SpecialType | ||
*/ | ||
/** | ||
* | ||
* @param {*} _value | ||
* @param {Object} opts | ||
* @param {string=} opts.path | ||
* @param {*=} opts.parent | ||
* @param {Object=} opts.context | ||
* @param {boolean=} opts.sync | ||
* @param {boolean=} opts.stripUnknown | ||
* @param {boolean=} opts.strict | ||
* @param {boolean=} opts.recursive | ||
* @param {boolean=} opts.abortEarly | ||
* @param {boolean=} opts.__validating | ||
* @param {Object=} opts.originalValue | ||
* @param {Ancestor[]=} opts.from | ||
* @param {Object} [opts.from] | ||
* @param {Function} callback | ||
*/ | ||
_validate: function _validate(_value, opts, callback) { | ||
var _this4 = this; | ||
@@ -175,61 +180,69 @@ | ||
var endEarly, recursive; | ||
var sync = opts.sync; | ||
var errors = []; | ||
var originalValue = opts.originalValue != null ? opts.originalValue : _value; | ||
var from = [{ | ||
var _opts = opts, | ||
sync = _opts.sync, | ||
_opts$from = _opts.from, | ||
from = _opts$from === void 0 ? [] : _opts$from, | ||
_opts$originalValue = _opts.originalValue, | ||
originalValue = _opts$originalValue === void 0 ? _value : _opts$originalValue, | ||
_opts$abortEarly = _opts.abortEarly, | ||
abortEarly = _opts$abortEarly === void 0 ? this._options.abortEarly : _opts$abortEarly, | ||
_opts$recursive = _opts.recursive, | ||
recursive = _opts$recursive === void 0 ? this._options.recursive : _opts$recursive; | ||
from = [{ | ||
schema: this, | ||
value: originalValue | ||
}].concat(opts.from || []); | ||
endEarly = this._option('abortEarly', opts); | ||
recursive = this._option('recursive', opts); | ||
opts = _extends({}, opts, { | ||
__validating: true, | ||
originalValue: originalValue, | ||
from: from | ||
}); | ||
return MixedSchema.prototype._validate.call(this, _value, opts).catch(propagateErrors(endEarly, errors)).then(function (value) { | ||
}].concat(from); // this flag is needed for handling `strict` correctly in the context of | ||
// validation vs just casting. e.g strict() on a field is only used when validating | ||
opts.__validating = true; | ||
opts.originalValue = originalValue; | ||
opts.from = from; | ||
MixedSchema.prototype._validate.call(this, _value, opts, function (err, value) { | ||
if (err) { | ||
if (abortEarly) return void callback(err); | ||
errors.push(err); | ||
value = err.value; | ||
} | ||
if (!recursive || !isObject(value)) { | ||
// only iterate though actual objects | ||
if (errors.length) throw errors[0]; | ||
return value; | ||
callback(errors[0] || null, value); | ||
return; | ||
} | ||
from = originalValue ? [].concat(from) : [{ | ||
schema: _this4, | ||
value: originalValue || value | ||
}].concat(opts.from || []); | ||
originalValue = originalValue || value; | ||
var validations = _this4._nodes.map(function (key) { | ||
var path = key.indexOf('.') === -1 ? makePath(_templateObject2(), opts.path, key) : makePath(_templateObject3(), opts.path, key); | ||
var field = _this4.fields[key]; | ||
var tests = _this4._nodes.map(function (key) { | ||
return function (_, cb) { | ||
var path = key.indexOf('.') === -1 ? (opts.path ? opts.path + "." : '') + key : (opts.path || '') + "[\"" + key + "\"]"; | ||
var field = _this4.fields[key]; | ||
var innerOptions = _extends({}, opts, { | ||
path: path, | ||
from: from, | ||
parent: value, | ||
originalValue: originalValue[key] | ||
}); | ||
if (field && field.validate) { | ||
field.validate(value[key], _extends({}, opts, { | ||
path: path, | ||
from: from, | ||
// inner fields are always strict: | ||
// 1. this isn't strict so the casting will also have cast inner values | ||
// 2. this is strict in which case the nested values weren't cast either | ||
strict: true, | ||
parent: value, | ||
originalValue: originalValue[key] | ||
}), cb); | ||
return; | ||
} | ||
if (field && field.validate) { | ||
// inner fields are always strict: | ||
// 1. this isn't strict so the casting will also have cast inner values | ||
// 2. this is strict in which case the nested values weren't cast either | ||
innerOptions.strict = true; | ||
return field.validate(value[key], innerOptions); | ||
} | ||
return promise(sync).resolve(true); | ||
cb(null); | ||
}; | ||
}); | ||
return runValidations({ | ||
runTests({ | ||
sync: sync, | ||
validations: validations, | ||
tests: tests, | ||
value: value, | ||
errors: errors, | ||
endEarly: endEarly, | ||
path: opts.path, | ||
sort: sortByKeyOrder(_this4.fields) | ||
}); | ||
endEarly: abortEarly, | ||
sort: _this4._sortErrors, | ||
path: opts.path | ||
}, callback); | ||
}); | ||
@@ -252,2 +265,3 @@ }, | ||
next.fields = fields; | ||
next._sortErrors = sortByKeyOrder(Object.keys(fields)); | ||
@@ -254,0 +268,0 @@ if (excludes.length) { |
@@ -1,2 +0,1 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import { getter } from 'property-expr'; | ||
@@ -28,13 +27,19 @@ var prefixes = { | ||
_proto.getValue = function getValue(options) { | ||
var result = this.isContext ? options.context : this.isValue ? options.value : options.parent; | ||
_proto.getValue = function getValue(value, parent, context) { | ||
var result = this.isContext ? context : this.isValue ? value : parent; | ||
if (this.getter) result = this.getter(result || {}); | ||
if (this.map) result = this.map(result); | ||
return result; | ||
}; | ||
} | ||
/** | ||
* | ||
* @param {*} value | ||
* @param {Object} options | ||
* @param {Object=} options.context | ||
* @param {Object=} options.parent | ||
*/ | ||
; | ||
_proto.cast = function cast(value, options) { | ||
return this.getValue(_extends({}, options, { | ||
value: value | ||
})); | ||
return this.getValue(value, options == null ? void 0 : options.parent, options == null ? void 0 : options.context); | ||
}; | ||
@@ -41,0 +46,0 @@ |
@@ -10,3 +10,3 @@ import inherits from './util/inherits'; | ||
var rUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; | ||
var rUUID = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; | ||
@@ -13,0 +13,0 @@ var isTrimmed = function isTrimmed(value) { |
@@ -0,92 +1,43 @@ | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; | ||
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import mapValues from "lodash-es/mapValues"; | ||
import ValidationError from '../ValidationError'; | ||
import Ref from '../Reference'; | ||
import { SynchronousPromise } from 'synchronous-promise'; | ||
var formatError = ValidationError.formatError; | ||
export default function createValidation(config) { | ||
function validate(_ref, cb) { | ||
var value = _ref.value, | ||
path = _ref.path, | ||
label = _ref.label, | ||
options = _ref.options, | ||
originalValue = _ref.originalValue, | ||
sync = _ref.sync, | ||
rest = _objectWithoutPropertiesLoose(_ref, ["value", "path", "label", "options", "originalValue", "sync"]); | ||
var thenable = function thenable(p) { | ||
return p && typeof p.then === 'function' && typeof p.catch === 'function'; | ||
}; | ||
var name = config.name, | ||
test = config.test, | ||
params = config.params, | ||
message = config.message; | ||
var parent = options.parent, | ||
context = options.context; | ||
function runTest(testFn, ctx, value, sync) { | ||
var result = testFn.call(ctx, value); | ||
if (!sync) return Promise.resolve(result); | ||
function resolve(item) { | ||
return Ref.isRef(item) ? item.getValue(value, parent, context) : item; | ||
} | ||
if (thenable(result)) { | ||
throw new Error("Validation test of type: \"" + ctx.type + "\" returned a Promise during a synchronous validate. " + "This test will finish after the validate call has returned"); | ||
} | ||
function createError(overrides) { | ||
if (overrides === void 0) { | ||
overrides = {}; | ||
} | ||
return SynchronousPromise.resolve(result); | ||
} | ||
function resolveParams(oldParams, newParams, resolve) { | ||
return mapValues(_extends({}, oldParams, newParams), resolve); | ||
} | ||
export function createErrorFactory(_ref) { | ||
var value = _ref.value, | ||
label = _ref.label, | ||
resolve = _ref.resolve, | ||
originalValue = _ref.originalValue, | ||
opts = _objectWithoutPropertiesLoose(_ref, ["value", "label", "resolve", "originalValue"]); | ||
return function createError(_temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
_ref2$path = _ref2.path, | ||
path = _ref2$path === void 0 ? opts.path : _ref2$path, | ||
_ref2$message = _ref2.message, | ||
message = _ref2$message === void 0 ? opts.message : _ref2$message, | ||
_ref2$type = _ref2.type, | ||
type = _ref2$type === void 0 ? opts.name : _ref2$type, | ||
params = _ref2.params; | ||
params = _extends({ | ||
path: path, | ||
value: value, | ||
originalValue: originalValue, | ||
label: label | ||
}, resolveParams(opts.params, params, resolve)); | ||
return _extends(new ValidationError(formatError(message, params), value, path, type), { | ||
params: params | ||
}); | ||
}; | ||
} | ||
export default function createValidation(options) { | ||
var name = options.name, | ||
message = options.message, | ||
test = options.test, | ||
params = options.params; | ||
function validate(_ref3) { | ||
var value = _ref3.value, | ||
path = _ref3.path, | ||
label = _ref3.label, | ||
options = _ref3.options, | ||
originalValue = _ref3.originalValue, | ||
sync = _ref3.sync, | ||
rest = _objectWithoutPropertiesLoose(_ref3, ["value", "path", "label", "options", "originalValue", "sync"]); | ||
var parent = options.parent; | ||
var resolve = function resolve(item) { | ||
return Ref.isRef(item) ? item.getValue({ | ||
var nextParams = mapValues(_extends({ | ||
value: value, | ||
parent: parent, | ||
context: options.context | ||
}) : item; | ||
}; | ||
originalValue: originalValue, | ||
label: label, | ||
path: overrides.path || path | ||
}, params, overrides.params), resolve); | ||
var error = new ValidationError(ValidationError.formatError(overrides.message || message, nextParams), value, nextParams.path, overrides.type || name); | ||
error.params = nextParams; | ||
return error; | ||
} | ||
var createError = createErrorFactory({ | ||
message: message, | ||
path: path, | ||
value: value, | ||
originalValue: originalValue, | ||
params: params, | ||
label: label, | ||
resolve: resolve, | ||
name: name | ||
}); | ||
var ctx = _extends({ | ||
@@ -98,12 +49,38 @@ path: path, | ||
resolve: resolve, | ||
options: options | ||
options: options, | ||
originalValue: originalValue | ||
}, rest); | ||
return runTest(test, ctx, value, sync).then(function (validOrError) { | ||
if (ValidationError.isError(validOrError)) throw validOrError;else if (!validOrError) throw createError(); | ||
}); | ||
if (!sync) { | ||
try { | ||
Promise.resolve(test.call(ctx, value, ctx)).then(function (validOrError) { | ||
if (ValidationError.isError(validOrError)) cb(validOrError);else if (!validOrError) cb(createError());else cb(null, validOrError); | ||
}); | ||
} catch (err) { | ||
cb(err); | ||
} | ||
return; | ||
} | ||
var result; | ||
try { | ||
var _result; | ||
result = test.call(ctx, value, ctx); | ||
if (typeof ((_result = result) == null ? void 0 : _result.then) === 'function') { | ||
throw new Error("Validation test of type: \"" + ctx.type + "\" returned a Promise during a synchronous validate. " + "This test will finish after the validate call has returned"); | ||
} | ||
} catch (err) { | ||
cb(err); | ||
return; | ||
} | ||
if (ValidationError.isError(result)) cb(result);else if (!result) cb(createError());else cb(null, result); | ||
} | ||
validate.OPTIONS = options; | ||
validate.OPTIONS = config; | ||
return validate; | ||
} |
@@ -12,4 +12,3 @@ function findIndex(arr, err) { | ||
export default function sortByKeyOrder(fields) { | ||
var keys = Object.keys(fields); | ||
export default function sortByKeyOrder(keys) { | ||
return function (a, b) { | ||
@@ -16,0 +15,0 @@ return findIndex(keys, a) - findIndex(keys, b); |
@@ -11,4 +11,4 @@ import has from "lodash-es/has"; | ||
var edges = [], | ||
nodes = []; | ||
var edges = []; | ||
var nodes = []; | ||
@@ -21,3 +21,3 @@ function addNode(depPath, key) { | ||
for (var key in fields) { | ||
var _loop = function _loop(key) { | ||
if (has(fields, key)) { | ||
@@ -30,2 +30,6 @@ var value = fields[key]; | ||
} | ||
}; | ||
for (var key in fields) { | ||
_loop(key); | ||
} | ||
@@ -32,0 +36,0 @@ |
import printValue from './util/printValue'; | ||
var strReg = /\$\{\s*(\w+)\s*\}/g; | ||
var replace = function replace(str) { | ||
return function (params) { | ||
return str.replace(strReg, function (_, key) { | ||
return printValue(params[key]); | ||
}); | ||
}; | ||
}; | ||
export default function ValidationError(errors, value, field, type) { | ||
@@ -36,10 +27,8 @@ var _this = this; | ||
ValidationError.formatError = function (message, params) { | ||
if (typeof message === 'string') message = replace(message); | ||
var fn = function fn(params) { | ||
params.path = params.label || params.path || 'this'; | ||
return typeof message === 'function' ? message(params) : message; | ||
}; | ||
return arguments.length === 1 ? fn : fn(params); | ||
params.path = params.label || params.path || 'this'; | ||
if (typeof message === 'string') return message.replace(strReg, function (_, key) { | ||
return printValue(params[key]); | ||
}); | ||
if (typeof message === 'function') return message(params); | ||
return message; | ||
}; |
"use strict"; | ||
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
@@ -10,4 +8,2 @@ | ||
var _taggedTemplateLiteralLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteralLoose")); | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
@@ -21,4 +17,2 @@ | ||
var _makePath = _interopRequireDefault(require("./util/makePath")); | ||
var _printValue = _interopRequireDefault(require("./util/printValue")); | ||
@@ -30,24 +24,4 @@ | ||
var _runValidations = _interopRequireWildcard(require("./util/runValidations")); | ||
var _runTests = _interopRequireDefault(require("./util/runTests")); | ||
function _templateObject2() { | ||
var data = (0, _taggedTemplateLiteralLoose2.default)(["", "[", "]"]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = (0, _taggedTemplateLiteralLoose2.default)(["", "[", "]"]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var _default = ArraySchema; | ||
@@ -97,3 +71,3 @@ exports.default = _default; | ||
var castElement = _this2.innerType.cast(v, (0, _extends2.default)({}, _opts, { | ||
path: (0, _makePath.default)(_templateObject(), _opts.path, idx) | ||
path: (_opts.path || '') + "[" + idx + "]" | ||
})); | ||
@@ -109,3 +83,3 @@ | ||
}, | ||
_validate: function _validate(_value, options) { | ||
_validate: function _validate(_value, options, callback) { | ||
var _this3 = this; | ||
@@ -127,6 +101,13 @@ | ||
var originalValue = options.originalValue != null ? options.originalValue : _value; | ||
return _mixed.default.prototype._validate.call(this, _value, options).catch((0, _runValidations.propagateErrors)(endEarly, errors)).then(function (value) { | ||
_mixed.default.prototype._validate.call(this, _value, options, function (err, value) { | ||
if (err) { | ||
if (endEarly) return void callback(err); | ||
errors.push(err); | ||
value = err.value; | ||
} | ||
if (!recursive || !innerType || !_this3._typeCheck(value)) { | ||
if (errors.length) throw errors[0]; | ||
return value; | ||
callback(errors[0] || null, value); | ||
return; | ||
} | ||
@@ -136,12 +117,10 @@ | ||
var validations = new Array(value.length); | ||
var tests = new Array(value.length); | ||
for (var idx = 0; idx < value.length; idx++) { | ||
var _loop = function _loop(idx) { | ||
var item = value[idx]; | ||
var path = (options.path || '') + "[" + idx + "]"; // object._validate note for isStrict explanation | ||
var _path = (0, _makePath.default)(_templateObject2(), options.path, idx); // object._validate note for isStrict explanation | ||
var innerOptions = (0, _extends2.default)({}, options, { | ||
path: _path, | ||
path: path, | ||
strict: true, | ||
@@ -152,6 +131,13 @@ parent: value, | ||
}); | ||
validations[idx] = innerType.validate ? innerType.validate(item, innerOptions) : true; | ||
tests[idx] = function (_, cb) { | ||
return innerType.validate ? innerType.validate(item, innerOptions, cb) : cb(null); | ||
}; | ||
}; | ||
for (var idx = 0; idx < value.length; idx++) { | ||
_loop(idx); | ||
} | ||
return (0, _runValidations.default)({ | ||
(0, _runTests.default)({ | ||
sync: sync, | ||
@@ -162,4 +148,4 @@ path: path, | ||
endEarly: endEarly, | ||
validations: validations | ||
}); | ||
tests: tests | ||
}, callback); | ||
}); | ||
@@ -166,0 +152,0 @@ }, |
@@ -54,3 +54,3 @@ "use strict"; | ||
var values = this.refs.map(function (ref) { | ||
return ref.getValue(options); | ||
return ref.getValue(options == null ? void 0 : options.value, options == null ? void 0 : options.parent, options == null ? void 0 : options.context); | ||
}); | ||
@@ -57,0 +57,0 @@ var schema = this.fn.apply(base, values.concat(base, options)); |
@@ -29,4 +29,4 @@ "use strict"; | ||
_proto.validate = function validate(value, options) { | ||
return this._resolve(value, options).validate(value, options); | ||
_proto.validate = function validate(value, options, maybeCb) { | ||
return this._resolve(value, options).validate(value, options, maybeCb); | ||
}; | ||
@@ -33,0 +33,0 @@ |
@@ -8,2 +8,4 @@ "use strict"; | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _printValue = _interopRequireDefault(require("./util/printValue")); | ||
@@ -73,3 +75,4 @@ | ||
exports.array = array; | ||
var _default = { | ||
var _default = (0, _extends2.default)(Object.create(null), { | ||
mixed: mixed, | ||
@@ -82,3 +85,4 @@ string: string, | ||
boolean: boolean | ||
}; | ||
}); | ||
exports.default = _default; |
114
lib/mixed.js
@@ -22,3 +22,3 @@ "use strict"; | ||
var _runValidations = _interopRequireDefault(require("./util/runValidations")); | ||
var _runTests = _interopRequireDefault(require("./util/runTests")); | ||
@@ -162,4 +162,8 @@ var _prependDeep = _interopRequireDefault(require("./util/prependDeep")); | ||
return (0, _cloneDeepWith.default)(this, function (value) { | ||
if ((0, _isSchema.default)(value) && value !== _this2) return value; | ||
return (0, _cloneDeepWith.default)(this, function (value, key) { | ||
if ((0, _isSchema.default)(value) && value !== _this2) return value; // fix for ie11 when cloning Set and Map | ||
if (key === '_whitelist' || key === '_blacklist') { | ||
return value.clone(); | ||
} | ||
}); | ||
@@ -225,2 +229,10 @@ }, | ||
}, | ||
/** | ||
* | ||
* @param {*} value | ||
* @param {Object} options | ||
* @param {*=} options.parent | ||
* @param {*=} options.context | ||
*/ | ||
cast: function cast(value, options) { | ||
@@ -231,5 +243,5 @@ if (options === void 0) { | ||
var resolvedSchema = this.resolve((0, _extends2.default)({}, options, { | ||
var resolvedSchema = this.resolve((0, _extends2.default)({ | ||
value: value | ||
})); | ||
}, options)); | ||
@@ -259,3 +271,3 @@ var result = resolvedSchema._cast(value, options); | ||
}, | ||
_validate: function _validate(_value, options) { | ||
_validate: function _validate(_value, options, cb) { | ||
var _this4 = this; | ||
@@ -267,57 +279,58 @@ | ||
var _options = options, | ||
sync = _options.sync, | ||
path = _options.path, | ||
_options$from = _options.from, | ||
from = _options$from === void 0 ? [] : _options$from, | ||
_options$originalValu = _options.originalValue, | ||
originalValue = _options$originalValu === void 0 ? _value : _options$originalValu, | ||
_options$strict = _options.strict, | ||
strict = _options$strict === void 0 ? this._options.strict : _options$strict, | ||
_options$abortEarly = _options.abortEarly, | ||
abortEarly = _options$abortEarly === void 0 ? this._options.abortEarly : _options$abortEarly; | ||
var value = _value; | ||
var originalValue = options.originalValue != null ? options.originalValue : _value; | ||
var isStrict = this._option('strict', options); | ||
var endEarly = this._option('abortEarly', options); | ||
var sync = options.sync; | ||
var path = options.path; | ||
var label = this._label; | ||
if (!isStrict) { | ||
if (!strict) { | ||
this._validating = true; | ||
value = this._cast(value, (0, _extends2.default)({ | ||
assert: false | ||
}, options)); | ||
this._validating = false; | ||
} // value is cast, we can check if it meets type requirements | ||
var validationParams = { | ||
var args = { | ||
value: value, | ||
path: path, | ||
schema: this, | ||
options: options, | ||
label: label, | ||
originalValue: originalValue, | ||
sync: sync | ||
schema: this, | ||
label: this._label, | ||
sync: sync, | ||
from: from | ||
}; | ||
if (options.from) { | ||
validationParams.from = options.from; | ||
} | ||
var initialTests = []; | ||
if (this._typeError) initialTests.push(this._typeError(validationParams)); | ||
if (this._whitelistError) initialTests.push(this._whitelistError(validationParams)); | ||
if (this._blacklistError) initialTests.push(this._blacklistError(validationParams)); | ||
return (0, _runValidations.default)({ | ||
validations: initialTests, | ||
endEarly: endEarly, | ||
if (this._typeError) initialTests.push(this._typeError); | ||
if (this._whitelistError) initialTests.push(this._whitelistError); | ||
if (this._blacklistError) initialTests.push(this._blacklistError); | ||
return (0, _runTests.default)({ | ||
args: args, | ||
value: value, | ||
path: path, | ||
sync: sync | ||
}).then(function (value) { | ||
return (0, _runValidations.default)({ | ||
sync: sync, | ||
tests: initialTests, | ||
endEarly: abortEarly | ||
}, function (err) { | ||
if (err) return void cb(err); | ||
(0, _runTests.default)({ | ||
tests: _this4.tests, | ||
args: args, | ||
path: path, | ||
sync: sync, | ||
value: value, | ||
endEarly: endEarly, | ||
validations: _this4.tests.map(function (fn) { | ||
return fn(validationParams); | ||
}) | ||
}); | ||
endEarly: abortEarly | ||
}, cb); | ||
}); | ||
}, | ||
validate: function validate(value, options) { | ||
validate: function validate(value, options, maybeCb) { | ||
if (options === void 0) { | ||
@@ -329,4 +342,9 @@ options = {}; | ||
value: value | ||
})); | ||
return schema._validate(value, options); | ||
})); // callback case is for nested validations | ||
return typeof maybeCb === 'function' ? schema._validate(value, options, maybeCb) : new Promise(function (resolve, reject) { | ||
return schema._validate(value, options, function (err, value) { | ||
if (err) reject(err);else resolve(value); | ||
}); | ||
}); | ||
}, | ||
@@ -341,13 +359,11 @@ validateSync: function validateSync(value, options) { | ||
})); | ||
var result, err; | ||
var result; | ||
schema._validate(value, (0, _extends2.default)({}, options, { | ||
sync: true | ||
})).then(function (r) { | ||
return result = r; | ||
}).catch(function (e) { | ||
return err = e; | ||
}), function (err, value) { | ||
if (err) throw err; | ||
result = value; | ||
}); | ||
if (err) throw err; | ||
return result; | ||
@@ -621,3 +637,3 @@ }, | ||
return this.nullable().test({ | ||
return this.test({ | ||
message: message, | ||
@@ -624,0 +640,0 @@ name: 'defined', |
"use strict"; | ||
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
@@ -10,4 +8,2 @@ | ||
var _taggedTemplateLiteralLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteralLoose")); | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
@@ -37,38 +33,10 @@ | ||
var _makePath = _interopRequireDefault(require("./util/makePath")); | ||
var _runTests = _interopRequireDefault(require("./util/runTests")); | ||
var _runValidations = _interopRequireWildcard(require("./util/runValidations")); | ||
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); } | ||
var _synchronousPromise = require("synchronous-promise"); | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _templateObject3() { | ||
var data = (0, _taggedTemplateLiteralLoose2.default)(["", "[\"", "\"]"]); | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } | ||
_templateObject3 = function _templateObject3() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject2() { | ||
var data = (0, _taggedTemplateLiteralLoose2.default)(["", ".", ""]); | ||
_templateObject2 = function _templateObject2() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
function _templateObject() { | ||
var data = (0, _taggedTemplateLiteralLoose2.default)(["", ".", ""]); | ||
_templateObject = function _templateObject() { | ||
return data; | ||
}; | ||
return data; | ||
} | ||
var isObject = function isObject(obj) { | ||
@@ -78,6 +46,2 @@ return Object.prototype.toString.call(obj) === '[object Object]'; | ||
var promise = function promise(sync) { | ||
return sync ? _synchronousPromise.SynchronousPromise : Promise; | ||
}; | ||
function unknown(ctx, value) { | ||
@@ -112,2 +76,3 @@ var known = Object.keys(ctx.fields); | ||
this.fields = Object.create(null); | ||
this._sortErrors = (0, _sortByKeyOrder.default)([]); | ||
this._nodes = []; | ||
@@ -146,3 +111,3 @@ this._excludedEdges = []; | ||
var value = _mixed.default.prototype._cast.call(this, _value, options); //should ignore nulls here | ||
var value = _mixed.default.prototype._cast.call(this, _value); //should ignore nulls here | ||
@@ -166,3 +131,5 @@ | ||
var isChanged = false; | ||
props.forEach(function (prop) { | ||
for (var _iterator = _createForOfIteratorHelperLoose(props), _step; !(_step = _iterator()).done;) { | ||
var prop = _step.value; | ||
var field = fields[prop]; | ||
@@ -172,6 +139,6 @@ var exists = (0, _has.default)(value, prop); | ||
if (field) { | ||
var fieldValue; | ||
var fieldValue = void 0; | ||
var strict = field._options && field._options.strict; // safe to mutate since this is fired in sequence | ||
innerOptions.path = (0, _makePath.default)(_templateObject(), options.path, prop); | ||
innerOptions.path = (options.path ? options.path + "." : '') + prop; | ||
innerOptions.value = value[prop]; | ||
@@ -182,14 +149,47 @@ field = field.resolve(innerOptions); | ||
isChanged = isChanged || prop in value; | ||
return; | ||
continue; | ||
} | ||
fieldValue = !options.__validating || !strict ? field.cast(value[prop], innerOptions) : value[prop]; | ||
if (fieldValue !== undefined) intermediateValue[prop] = fieldValue; | ||
} else if (exists && !strip) intermediateValue[prop] = value[prop]; | ||
if (intermediateValue[prop] !== value[prop]) isChanged = true; | ||
}); | ||
if (fieldValue !== undefined) { | ||
intermediateValue[prop] = fieldValue; | ||
} | ||
} else if (exists && !strip) { | ||
intermediateValue[prop] = value[prop]; | ||
} | ||
if (intermediateValue[prop] !== value[prop]) { | ||
isChanged = true; | ||
} | ||
} | ||
return isChanged ? intermediateValue : value; | ||
}, | ||
_validate: function _validate(_value, opts) { | ||
/** | ||
* @typedef {Object} Ancestor | ||
* @property {Object} schema - a string property of SpecialType | ||
* @property {*} value - a number property of SpecialType | ||
*/ | ||
/** | ||
* | ||
* @param {*} _value | ||
* @param {Object} opts | ||
* @param {string=} opts.path | ||
* @param {*=} opts.parent | ||
* @param {Object=} opts.context | ||
* @param {boolean=} opts.sync | ||
* @param {boolean=} opts.stripUnknown | ||
* @param {boolean=} opts.strict | ||
* @param {boolean=} opts.recursive | ||
* @param {boolean=} opts.abortEarly | ||
* @param {boolean=} opts.__validating | ||
* @param {Object=} opts.originalValue | ||
* @param {Ancestor[]=} opts.from | ||
* @param {Object} [opts.from] | ||
* @param {Function} callback | ||
*/ | ||
_validate: function _validate(_value, opts, callback) { | ||
var _this4 = this; | ||
@@ -201,60 +201,69 @@ | ||
var endEarly, recursive; | ||
var sync = opts.sync; | ||
var errors = []; | ||
var originalValue = opts.originalValue != null ? opts.originalValue : _value; | ||
var from = [{ | ||
var _opts = opts, | ||
sync = _opts.sync, | ||
_opts$from = _opts.from, | ||
from = _opts$from === void 0 ? [] : _opts$from, | ||
_opts$originalValue = _opts.originalValue, | ||
originalValue = _opts$originalValue === void 0 ? _value : _opts$originalValue, | ||
_opts$abortEarly = _opts.abortEarly, | ||
abortEarly = _opts$abortEarly === void 0 ? this._options.abortEarly : _opts$abortEarly, | ||
_opts$recursive = _opts.recursive, | ||
recursive = _opts$recursive === void 0 ? this._options.recursive : _opts$recursive; | ||
from = [{ | ||
schema: this, | ||
value: originalValue | ||
}].concat(opts.from || []); | ||
endEarly = this._option('abortEarly', opts); | ||
recursive = this._option('recursive', opts); | ||
opts = (0, _extends2.default)({}, opts, { | ||
__validating: true, | ||
originalValue: originalValue, | ||
from: from | ||
}); | ||
return _mixed.default.prototype._validate.call(this, _value, opts).catch((0, _runValidations.propagateErrors)(endEarly, errors)).then(function (value) { | ||
}].concat(from); // this flag is needed for handling `strict` correctly in the context of | ||
// validation vs just casting. e.g strict() on a field is only used when validating | ||
opts.__validating = true; | ||
opts.originalValue = originalValue; | ||
opts.from = from; | ||
_mixed.default.prototype._validate.call(this, _value, opts, function (err, value) { | ||
if (err) { | ||
if (abortEarly) return void callback(err); | ||
errors.push(err); | ||
value = err.value; | ||
} | ||
if (!recursive || !isObject(value)) { | ||
// only iterate though actual objects | ||
if (errors.length) throw errors[0]; | ||
return value; | ||
callback(errors[0] || null, value); | ||
return; | ||
} | ||
from = originalValue ? [].concat(from) : [{ | ||
schema: _this4, | ||
value: originalValue || value | ||
}].concat(opts.from || []); | ||
originalValue = originalValue || value; | ||
var validations = _this4._nodes.map(function (key) { | ||
var path = key.indexOf('.') === -1 ? (0, _makePath.default)(_templateObject2(), opts.path, key) : (0, _makePath.default)(_templateObject3(), opts.path, key); | ||
var field = _this4.fields[key]; | ||
var innerOptions = (0, _extends2.default)({}, opts, { | ||
path: path, | ||
from: from, | ||
parent: value, | ||
originalValue: originalValue[key] | ||
}); | ||
var tests = _this4._nodes.map(function (key) { | ||
return function (_, cb) { | ||
var path = key.indexOf('.') === -1 ? (opts.path ? opts.path + "." : '') + key : (opts.path || '') + "[\"" + key + "\"]"; | ||
var field = _this4.fields[key]; | ||
if (field && field.validate) { | ||
// inner fields are always strict: | ||
// 1. this isn't strict so the casting will also have cast inner values | ||
// 2. this is strict in which case the nested values weren't cast either | ||
innerOptions.strict = true; | ||
return field.validate(value[key], innerOptions); | ||
} | ||
if (field && field.validate) { | ||
field.validate(value[key], (0, _extends2.default)({}, opts, { | ||
path: path, | ||
from: from, | ||
// inner fields are always strict: | ||
// 1. this isn't strict so the casting will also have cast inner values | ||
// 2. this is strict in which case the nested values weren't cast either | ||
strict: true, | ||
parent: value, | ||
originalValue: originalValue[key] | ||
}), cb); | ||
return; | ||
} | ||
return promise(sync).resolve(true); | ||
cb(null); | ||
}; | ||
}); | ||
return (0, _runValidations.default)({ | ||
(0, _runTests.default)({ | ||
sync: sync, | ||
validations: validations, | ||
tests: tests, | ||
value: value, | ||
errors: errors, | ||
endEarly: endEarly, | ||
path: opts.path, | ||
sort: (0, _sortByKeyOrder.default)(_this4.fields) | ||
}); | ||
endEarly: abortEarly, | ||
sort: _this4._sortErrors, | ||
path: opts.path | ||
}, callback); | ||
}); | ||
@@ -276,2 +285,3 @@ }, | ||
next.fields = fields; | ||
next._sortErrors = (0, _sortByKeyOrder.default)(Object.keys(fields)); | ||
@@ -278,0 +288,0 @@ if (excludes.length) { |
"use strict"; | ||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | ||
exports.__esModule = true; | ||
exports.default = void 0; | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _propertyExpr = require("property-expr"); | ||
@@ -37,13 +33,19 @@ | ||
_proto.getValue = function getValue(options) { | ||
var result = this.isContext ? options.context : this.isValue ? options.value : options.parent; | ||
_proto.getValue = function getValue(value, parent, context) { | ||
var result = this.isContext ? context : this.isValue ? value : parent; | ||
if (this.getter) result = this.getter(result || {}); | ||
if (this.map) result = this.map(result); | ||
return result; | ||
}; | ||
} | ||
/** | ||
* | ||
* @param {*} value | ||
* @param {Object} options | ||
* @param {Object=} options.context | ||
* @param {Object=} options.parent | ||
*/ | ||
; | ||
_proto.cast = function cast(value, options) { | ||
return this.getValue((0, _extends2.default)({}, options, { | ||
value: value | ||
})); | ||
return this.getValue(value, options == null ? void 0 : options.parent, options == null ? void 0 : options.context); | ||
}; | ||
@@ -50,0 +52,0 @@ |
@@ -21,3 +21,3 @@ "use strict"; | ||
var rUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; | ||
var rUUID = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; | ||
@@ -24,0 +24,0 @@ var isTrimmed = function isTrimmed(value) { |
@@ -6,9 +6,8 @@ "use strict"; | ||
exports.__esModule = true; | ||
exports.createErrorFactory = createErrorFactory; | ||
exports.default = createValidation; | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); | ||
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | ||
var _mapValues = _interopRequireDefault(require("lodash/mapValues")); | ||
@@ -20,87 +19,38 @@ | ||
var _synchronousPromise = require("synchronous-promise"); | ||
function createValidation(config) { | ||
function validate(_ref, cb) { | ||
var value = _ref.value, | ||
path = _ref.path, | ||
label = _ref.label, | ||
options = _ref.options, | ||
originalValue = _ref.originalValue, | ||
sync = _ref.sync, | ||
rest = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["value", "path", "label", "options", "originalValue", "sync"]); | ||
var name = config.name, | ||
test = config.test, | ||
params = config.params, | ||
message = config.message; | ||
var parent = options.parent, | ||
context = options.context; | ||
var formatError = _ValidationError.default.formatError; | ||
function resolve(item) { | ||
return _Reference.default.isRef(item) ? item.getValue(value, parent, context) : item; | ||
} | ||
var thenable = function thenable(p) { | ||
return p && typeof p.then === 'function' && typeof p.catch === 'function'; | ||
}; | ||
function createError(overrides) { | ||
if (overrides === void 0) { | ||
overrides = {}; | ||
} | ||
function runTest(testFn, ctx, value, sync) { | ||
var result = testFn.call(ctx, value); | ||
if (!sync) return Promise.resolve(result); | ||
if (thenable(result)) { | ||
throw new Error("Validation test of type: \"" + ctx.type + "\" returned a Promise during a synchronous validate. " + "This test will finish after the validate call has returned"); | ||
} | ||
return _synchronousPromise.SynchronousPromise.resolve(result); | ||
} | ||
function resolveParams(oldParams, newParams, resolve) { | ||
return (0, _mapValues.default)((0, _extends2.default)({}, oldParams, newParams), resolve); | ||
} | ||
function createErrorFactory(_ref) { | ||
var value = _ref.value, | ||
label = _ref.label, | ||
resolve = _ref.resolve, | ||
originalValue = _ref.originalValue, | ||
opts = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["value", "label", "resolve", "originalValue"]); | ||
return function createError(_temp) { | ||
var _ref2 = _temp === void 0 ? {} : _temp, | ||
_ref2$path = _ref2.path, | ||
path = _ref2$path === void 0 ? opts.path : _ref2$path, | ||
_ref2$message = _ref2.message, | ||
message = _ref2$message === void 0 ? opts.message : _ref2$message, | ||
_ref2$type = _ref2.type, | ||
type = _ref2$type === void 0 ? opts.name : _ref2$type, | ||
params = _ref2.params; | ||
params = (0, _extends2.default)({ | ||
path: path, | ||
value: value, | ||
originalValue: originalValue, | ||
label: label | ||
}, resolveParams(opts.params, params, resolve)); | ||
return (0, _extends2.default)(new _ValidationError.default(formatError(message, params), value, path, type), { | ||
params: params | ||
}); | ||
}; | ||
} | ||
function createValidation(options) { | ||
var name = options.name, | ||
message = options.message, | ||
test = options.test, | ||
params = options.params; | ||
function validate(_ref3) { | ||
var value = _ref3.value, | ||
path = _ref3.path, | ||
label = _ref3.label, | ||
options = _ref3.options, | ||
originalValue = _ref3.originalValue, | ||
sync = _ref3.sync, | ||
rest = (0, _objectWithoutPropertiesLoose2.default)(_ref3, ["value", "path", "label", "options", "originalValue", "sync"]); | ||
var parent = options.parent; | ||
var resolve = function resolve(item) { | ||
return _Reference.default.isRef(item) ? item.getValue({ | ||
var nextParams = (0, _mapValues.default)((0, _extends2.default)({ | ||
value: value, | ||
parent: parent, | ||
context: options.context | ||
}) : item; | ||
}; | ||
originalValue: originalValue, | ||
label: label, | ||
path: overrides.path || path | ||
}, params, overrides.params), resolve); | ||
var error = new _ValidationError.default(_ValidationError.default.formatError(overrides.message || message, nextParams), value, nextParams.path, overrides.type || name); | ||
error.params = nextParams; | ||
return error; | ||
} | ||
var createError = createErrorFactory({ | ||
message: message, | ||
path: path, | ||
value: value, | ||
originalValue: originalValue, | ||
params: params, | ||
label: label, | ||
resolve: resolve, | ||
name: name | ||
}); | ||
var ctx = (0, _extends2.default)({ | ||
@@ -112,11 +62,40 @@ path: path, | ||
resolve: resolve, | ||
options: options | ||
options: options, | ||
originalValue: originalValue | ||
}, rest); | ||
return runTest(test, ctx, value, sync).then(function (validOrError) { | ||
if (_ValidationError.default.isError(validOrError)) throw validOrError;else if (!validOrError) throw createError(); | ||
}); | ||
if (!sync) { | ||
try { | ||
Promise.resolve(test.call(ctx, value, ctx)).then(function (validOrError) { | ||
if (_ValidationError.default.isError(validOrError)) cb(validOrError);else if (!validOrError) cb(createError());else cb(null, validOrError); | ||
}); | ||
} catch (err) { | ||
cb(err); | ||
} | ||
return; | ||
} | ||
var result; | ||
try { | ||
var _result; | ||
result = test.call(ctx, value, ctx); | ||
if (typeof ((_result = result) == null ? void 0 : _result.then) === 'function') { | ||
throw new Error("Validation test of type: \"" + ctx.type + "\" returned a Promise during a synchronous validate. " + "This test will finish after the validate call has returned"); | ||
} | ||
} catch (err) { | ||
cb(err); | ||
return; | ||
} | ||
if (_ValidationError.default.isError(result)) cb(result);else if (!result) cb(createError());else cb(null, result); | ||
} | ||
validate.OPTIONS = options; | ||
validate.OPTIONS = config; | ||
return validate; | ||
} | ||
} | ||
module.exports = exports.default; |
@@ -17,4 +17,3 @@ "use strict"; | ||
function sortByKeyOrder(fields) { | ||
var keys = Object.keys(fields); | ||
function sortByKeyOrder(keys) { | ||
return function (a, b) { | ||
@@ -21,0 +20,0 @@ return findIndex(keys, a) - findIndex(keys, b); |
@@ -23,4 +23,4 @@ "use strict"; | ||
var edges = [], | ||
nodes = []; | ||
var edges = []; | ||
var nodes = []; | ||
@@ -33,3 +33,3 @@ function addNode(depPath, key) { | ||
for (var key in fields) { | ||
var _loop = function _loop(key) { | ||
if ((0, _has.default)(fields, key)) { | ||
@@ -42,2 +42,6 @@ var value = fields[key]; | ||
} | ||
}; | ||
for (var key in fields) { | ||
_loop(key); | ||
} | ||
@@ -44,0 +48,0 @@ |
@@ -12,10 +12,2 @@ "use strict"; | ||
var replace = function replace(str) { | ||
return function (params) { | ||
return str.replace(strReg, function (_, key) { | ||
return (0, _printValue.default)(params[key]); | ||
}); | ||
}; | ||
}; | ||
function ValidationError(errors, value, field, type) { | ||
@@ -46,12 +38,10 @@ var _this = this; | ||
ValidationError.formatError = function (message, params) { | ||
if (typeof message === 'string') message = replace(message); | ||
var fn = function fn(params) { | ||
params.path = params.label || params.path || 'this'; | ||
return typeof message === 'function' ? message(params) : message; | ||
}; | ||
return arguments.length === 1 ? fn : fn(params); | ||
params.path = params.label || params.path || 'this'; | ||
if (typeof message === 'string') return message.replace(strReg, function (_, key) { | ||
return (0, _printValue.default)(params[key]); | ||
}); | ||
if (typeof message === 'function') return message(params); | ||
return message; | ||
}; | ||
module.exports = exports.default; |
{ | ||
"name": "yup", | ||
"version": "0.29.3", | ||
"version": "0.30.0", | ||
"description": "Dead simple Object schema validation", | ||
@@ -9,5 +9,6 @@ "main": "lib/index.js", | ||
"scripts": { | ||
"test": "npm run lint && npm run test-all -- --runInBand", | ||
"test": "yarn lint && yarn test-all --runInBand", | ||
"testonly": "jest", | ||
"test-all": "npm run testonly -- --projects ./jest-sync.config.json --projects ./package.json", | ||
"test-sync": "yarn testonly --projects ./jest-sync.config.json", | ||
"test-all": "yarn testonly --projects ./jest-sync.config.json --projects ./package.json", | ||
"tdd": "jest --watch", | ||
@@ -18,6 +19,6 @@ "lint": "eslint src test", | ||
"release": "rollout", | ||
"build": "yarn build:commonjs && yarn build:modules && npm run toc", | ||
"build": "yarn build:commonjs && yarn build:modules && yarn toc", | ||
"build:commonjs": "babel src --out-dir lib --delete-dir-on-start", | ||
"build:modules": "babel src --out-dir es --delete-dir-on-start --env-name modules", | ||
"prepublishOnly": "npm run build" | ||
"prepublishOnly": "yarn build" | ||
}, | ||
@@ -55,3 +56,3 @@ "files": [ | ||
"globals": { | ||
"YUP_USE_SYNC": true | ||
"YUP_USE_SYNC": false | ||
}, | ||
@@ -72,7 +73,7 @@ "testEnvironment": "node", | ||
"@4c/rollout": "^2.1.10", | ||
"@babel/cli": "7.10.5", | ||
"@babel/core": "7.11.0", | ||
"@babel/cli": "7.12.1", | ||
"@babel/core": "7.12.3", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-eslint": "^10.1.0", | ||
"babel-jest": "^26.2.2", | ||
"babel-jest": "^26.6.1", | ||
"babel-plugin-transform-rename-import": "^2.3.0", | ||
@@ -85,14 +86,14 @@ "babel-preset-jason": "^6.3.0", | ||
"doctoc": "^1.4.0", | ||
"eslint": "^7.6.0", | ||
"eslint": "^7.12.0", | ||
"eslint-config-jason": "^7.0.1", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-jest": "^23.20.0", | ||
"eslint-plugin-react": "^7.20.5", | ||
"eslint-plugin-react-hooks": "^4.0.8", | ||
"husky": "^4.2.5", | ||
"jest": "^26.2.2", | ||
"lint-staged": "^10.2.11", | ||
"prettier": "^2.0.5", | ||
"rollup": "^2.23.0", | ||
"eslint-config-prettier": "^6.14.0", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-jest": "^24.1.0", | ||
"eslint-plugin-react": "^7.21.5", | ||
"eslint-plugin-react-hooks": "^4.2.0", | ||
"husky": "^4.3.0", | ||
"jest": "^26.6.1", | ||
"lint-staged": "^10.4.2", | ||
"prettier": "^2.1.2", | ||
"rollup": "^2.32.1", | ||
"rollup-plugin-babel": "^4.4.0", | ||
@@ -102,12 +103,11 @@ "rollup-plugin-filesize": "^8.0.2", | ||
"rollup-plugin-size-snapshot": "^0.12.0", | ||
"sinon": "^9.0.2", | ||
"sinon-chai": "^3.5.0" | ||
"sinon": "^9.2.0", | ||
"sinon-chai": "^3.5.0", | ||
"synchronous-promise": "^2.0.15" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.10.5", | ||
"fn-name": "~3.0.0", | ||
"lodash": "^4.17.15", | ||
"lodash": "^4.17.20", | ||
"lodash-es": "^4.17.11", | ||
"property-expr": "^2.0.2", | ||
"synchronous-promise": "^2.0.13", | ||
"property-expr": "^2.0.4", | ||
"toposort": "^2.0.2" | ||
@@ -114,0 +114,0 @@ }, |
@@ -695,10 +695,10 @@ # Yup | ||
All tests must provide a `name`, an error `message` and a validation function that must return | ||
`true` or `false` or a `ValidationError`. To make a test async return a promise that resolves `true` | ||
or `false` or a `ValidationError`. | ||
`true` when the current `value` is valid and `false` or a `ValidationError` otherwise. | ||
To make a test async return a promise that resolves `true` or `false` or a `ValidationError`. | ||
for the `message` argument you can provide a string which will interpolate certain values | ||
For the `message` argument you can provide a string which will interpolate certain values | ||
if specified using the `${param}` syntax. By default all test messages are passed a `path` value | ||
which is valuable in nested schemas. | ||
the `test` function is called with the current `value`. For more advanced validations you can | ||
The `test` function is called with the current `value`. For more advanced validations you can | ||
use the alternate signature to provide more options (see below): | ||
@@ -710,3 +710,3 @@ | ||
'${path} is not Jimmy', | ||
value => value === 'jimmy', | ||
(value, context) => value === 'jimmy', | ||
); | ||
@@ -718,3 +718,3 @@ | ||
'${path} is not Jimmy', | ||
async (value) => (await fetch('/is-jimmy/' + value)).responseText === 'true', | ||
async (value, context) => (await fetch('/is-jimmy/' + value)).responseText === 'true', | ||
}); | ||
@@ -726,3 +726,6 @@ | ||
test functions are called with a special context, or `this` value, that exposes some useful metadata and functions. Note that to use the `this` context the test function must be a function expression (`function test(value) {}`), not an arrow function, since arrow functions have lexical context. | ||
Test functions are called with a special context, or `this` value, that exposes some useful metadata | ||
and functions. Older versions just expose the `this` context using `function ()`, not arrow-func, | ||
but now it's exposed too as a second argument of the test functions. It's allow you decide which | ||
approach you prefer. | ||
@@ -733,2 +736,3 @@ - `this.path`: the string path of the current validation | ||
- `this.parent`: in the case of nested schema, this is the value of the parent object | ||
- `this.originalValue`: the original value that is being tested | ||
- `this.createError(Object: { path: String, message: String, params: Object })`: create and return a | ||
@@ -735,0 +739,0 @@ validation error. Useful for dynamically setting the `path`, `params`, or more likely, the error `message`. |
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
228914
5
4340
1375
32
- Removedfn-name@~3.0.0
- Removedsynchronous-promise@^2.0.13
- Removedfn-name@3.0.0(transitive)
- Removedsynchronous-promise@2.0.17(transitive)
Updatedlodash@^4.17.20
Updatedproperty-expr@^2.0.4