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

yup

Package Overview
Dependencies
Maintainers
1
Versions
127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yup - npm Package Compare versions

Comparing version 0.14.2 to 0.15.0

8

CHANGELOG.md

@@ -0,1 +1,9 @@

v0.15.0 - Tue, 29 Mar 2016 14:56:15 GMT
---------------------------------------
- [3ae5fdc](../../commit/3ae5fdc) [changed] `null` is not considered an empty value for isValid
- [9eb42c6](../../commit/9eb42c6) [added] refs!
v0.14.2 - Tue, 29 Mar 2016 14:48:37 GMT

@@ -2,0 +10,0 @@ ---------------------------------------

4

lib/array.js

@@ -131,3 +131,3 @@ 'use strict';

test: function test(value) {
return isAbsent(value) || value.length >= _min;
return isAbsent(value) || value.length >= this.resolve(_min);
}

@@ -145,3 +145,3 @@ });

test: function test(value) {
return isAbsent(value) || value.length <= _max;
return isAbsent(value) || value.length <= this.resolve(_max);
}

@@ -148,0 +148,0 @@ });

@@ -50,3 +50,3 @@ 'use strict';

test: function test(value) {
return isAbsent(value) || value >= limit;
return isAbsent(value) || value >= this.resolve(limit);
}

@@ -67,3 +67,3 @@ });

test: function test(value) {
return isAbsent(value) || value <= limit;
return isAbsent(value) || value <= this.resolve(limit);
}

@@ -70,0 +70,0 @@ });

'use strict';
var mixed = require('./mixed'),
bool = require('./boolean');
bool = require('./boolean'),
Ref = require('./util/reference');

@@ -22,2 +23,5 @@ var isSchema = function isSchema(schema) {

ValidationError: require('./util/validation-error'),
ref: function ref(key, options) {
return new Ref(key, options);
},

@@ -24,0 +28,0 @@ isSchema: isSchema,

@@ -5,3 +5,2 @@ 'use strict';

Condition = require('./util/condition'),
ValidationError = require('./util/validation-error'),
locale = require('./locale.js').mixed,

@@ -12,3 +11,4 @@ _ = require('./util/_'),

createValidation = require('./util/createValidation'),
BadSet = require('./util/set');
BadSet = require('./util/set'),
Ref = require('./util/reference');

@@ -33,2 +33,3 @@ var notEmpty = function notEmpty(value) {

this._deps = [];
this._conditions = [];
this._options = { abortEarly: true, recursive: true };

@@ -104,5 +105,7 @@ this._exclusive = Object.create(null);

cast: function cast(_value, _opts) {
var schema = this._resolve((_opts || {}).context);
return schema._cast(_value, _opts);
cast: function cast(value) {
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var schema = this._resolve(opts.context, opts.parent);
return schema._cast(value, opts);
},

@@ -123,4 +126,4 @@

_resolve: function _resolve(context, parent) {
if (this._deps.length) {
return this._deps.reduce(function (schema, match) {
if (this._conditions.length) {
return this._conditions.reduce(function (schema, match) {
return match.resolve(schema, match.getValue(parent, context));

@@ -270,8 +273,14 @@ }, this);

when: function when(key, options) {
when: function when(keys, options) {
var next = this.clone(),
dep = new Condition(key, next._type, options);
deps = [].concat(keys).map(function (key) {
return new Ref(key);
});
next._deps.push(dep);
deps.forEach(function (dep) {
if (!dep.isContext) next._deps.push(dep.key);
});
next._conditions.push(new Condition(deps, options));
return next;

@@ -288,3 +297,5 @@ },

if (value !== undefined && !this.schema.isType(value)) return this.createError({
params: { type: this.schema._type }
params: {
type: this.schema._type
}
});

@@ -314,3 +325,7 @@ return true;

var valids = this.schema._whitelist;
if (valids.length && !(valids.has(value) || isAbsent(value))) return this.createError({ params: { values: valids.values().join(', ') } });
if (valids.length && !(value === undefined || valids.has(value))) return this.createError({
params: {
values: valids.values().join(', ')
}
});
return true;

@@ -338,3 +353,7 @@ }

var invalids = this.schema._blacklist;
if (invalids.length && invalids.has(value)) return this.createError({ params: { values: invalids.values().join(', ') } });
if (invalids.length && invalids.has(value)) return this.createError({
params: {
values: invalids.values().join(', ')
}
});
return true;

@@ -341,0 +360,0 @@ }

@@ -50,3 +50,3 @@ 'use strict';

test: function test(value) {
return isAbsent(value) || value >= _min;
return isAbsent(value) || value >= this.resolve(_min);
}

@@ -63,3 +63,3 @@ });

test: function test(value) {
return isAbsent(value) || value <= _max;
return isAbsent(value) || value <= this.resolve(_max);
}

@@ -66,0 +66,0 @@ });

@@ -10,2 +10,3 @@ 'use strict';

var split = require('property-expr').split;
var Ref = require('./util/reference');
var c = require('case');

@@ -20,2 +21,3 @@

var collectErrors = _require.collectErrors;
var isSchema = _require.isSchema;
var has = _require.has;

@@ -35,3 +37,5 @@

var childSchema = function childSchema(field, parent) {
return isRecursive(field) ? field.of ? field.of(parent) : parent : field;
if (!isRecursive(field)) return field;
return field.of ? field.of(parent) : parent;
};

@@ -91,3 +95,5 @@

_cast: function _cast(_value, _opts) {
_cast: function _cast(_value) {
var _opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var schema = this,

@@ -107,19 +113,29 @@ value = MixedSchema.prototype._cast.call(schema, _value);

schema.withMutation(function () {
var innerOptions = _extends({}, _opts, { context: {} });
var innerOptions = _extends({}, _opts, { parent: {} });
value = transform(props, function (obj, prop) {
var field = fields[prop];
var exists = has(value, prop);
if (exists && fields[prop]) {
var fieldSchema = childSchema(fields[prop], schema['default'](undefined));
if (Ref.isRef(field)) {
var refValue = field.getValue(obj, innerOptions.context);
if (refValue !== undefined) obj[prop] = refValue;
} else if (exists && field) {
// ugly optimization avoiding a clone. clears default for recursive
// cast and resets it below;
var hasDflt = has(schema, '_default'),
dflt = schema._default;
var fieldSchema = childSchema(field, schema['default'](undefined));
obj[prop] = fieldSchema.cast(value[prop], innerOptions);
} else if (exists && !strip) obj[prop] = value[prop];else if (fields[prop]) {
var fieldDefault = fields[prop]['default'] ? fields[prop]['default']() : undefined;
if (hasDflt) schema['default'](dflt);else delete schema._default;
} else if (exists && !strip) obj[prop] = value[prop];else if (field) {
var fieldDefault = field['default'] ? field['default']() : undefined;
if (fieldDefault !== undefined) obj[prop] = fieldDefault;
}
}, innerOptions.context);
delete schema._default;
}, innerOptions.parent);
});

@@ -265,14 +281,16 @@

for (var key in fields) if (has(fields, key)) {
var value = fields[key];
if (! ~nodes.indexOf(key)) nodes.push(key);
fields[key]._deps && fields[key]._deps.forEach(function (dep) {
var addNode = function addNode(depPath) {
//eslint-disable-line no-loop-func
if (dep.isContext) return;
var node = split(depPath)[0];
var node = split(dep.key)[0];
if (! ~nodes.indexOf(node)) nodes.push(node);
if (! ~excludes.indexOf(key + '-' + node)) edges.push([key, node]);
});
};
if (Ref.isRef(value) && !value.isContext) addNode(value.path);else if (isSchema(value)) value._deps.forEach(addNode);
}

@@ -279,0 +297,0 @@

@@ -57,3 +57,3 @@ 'use strict';

test: function test(value) {
return isAbsent(value) || value.length >= _min;
return isAbsent(value) || value.length >= this.resolve(_min);
}

@@ -70,3 +70,3 @@ });

test: function test(value) {
return isAbsent(value) || value.length <= _max;
return isAbsent(value) || value.length <= this.resolve(_max);
}

@@ -73,0 +73,0 @@ });

@@ -7,5 +7,5 @@ 'use strict';

var transform = _require.transform;
var has = _require.has;
var isSchema = _require.isSchema;
var getter = require('property-expr').getter;

@@ -15,3 +15,5 @@ module.exports = Conditional;

var Conditional = (function () {
function Conditional(key, type, options) {
function Conditional(refs, options) {
var _this = this;
_classCallCheck(this, Conditional);

@@ -22,20 +24,30 @@

var otherwise = options.otherwise;
var prefix = options.contextPrefix || '$';
this.prefix = prefix;
this.key = key;
this.isContext = key.indexOf(prefix) === 0;
this.refs = [].concat(refs);
if (typeof options === 'function') this.fn = options;else {
if (!has(options, 'is')) throw new TypeError('`is:` is required for `when()` conditions');
(function () {
if (!has(options, 'is')) throw new TypeError('`is:` is required for `when()` conditions');
if (!options.then && !options.otherwise) throw new TypeError('either `then:` or `otherwise:` is required for `when()` conditions');
if (!options.then && !options.otherwise) throw new TypeError('either `then:` or `otherwise:` is required for `when()` conditions');
is = typeof is === 'function' ? is : (function (is, value) {
return is === value;
}).bind(null, is);
var isFn = typeof is === 'function' ? is : function () {
for (var _len = arguments.length, values = Array(_len), _key = 0; _key < _len; _key++) {
values[_key] = arguments[_key];
}
this.fn = function (value, ctx) {
return is(value) ? ctx.concat(then) : ctx.concat(otherwise);
};
return values.every(function (value) {
return value === is;
});
};
_this.fn = function () {
for (var _len2 = arguments.length, values = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
values[_key2] = arguments[_key2];
}
var ctx = values.pop();
return isFn.apply(undefined, values) ? ctx.concat(then) : ctx.concat(otherwise);
};
})();
}

@@ -45,11 +57,11 @@ }

Conditional.prototype.getValue = function getValue(parent, context) {
var path = this.isContext ? this.key.slice(this.prefix.length) : this.key;
var values = this.refs.map(function (r) {
return r.getValue(parent, context);
});
if (this.isContext && !context || !this.isContext && !context && !parent) throw new Error('missing the context necessary to cast this value');
return getter(path)(this.isContext ? context : parent || context);
return values;
};
Conditional.prototype.resolve = function resolve(ctx, value) {
var schema = this.fn.call(ctx, value, ctx);
Conditional.prototype.resolve = function resolve(ctx, values) {
var schema = this.fn.apply(ctx, values.concat(ctx));

@@ -56,0 +68,0 @@ if (schema !== undefined && !isSchema(schema)) throw new TypeError('conditions must return a schema object');

@@ -7,20 +7,40 @@ 'use strict';

var Promise = require('promise/lib/es6-extensions'),
ValidationError = require('./validation-error');
var Promise = require('promise/lib/es6-extensions');
var ValidationError = require('./validation-error');
var Ref = require('./reference');
var _require = require('./_');
var transform = _require.transform;
var formatError = ValidationError.formatError;
function createErrorFactory(orginalMessage, orginalPath, value, orginalParams, originalType, label) {
function resolveParams(oldParams, newParams, resolve) {
var start = _extends({}, oldParams, newParams);
return transform(start, function (obj, value, key) {
obj[key] = resolve(value);
});
}
function createErrorFactory(_ref) {
var value = _ref.value;
var label = _ref.label;
var resolve = _ref.resolve;
var opts = _objectWithoutProperties(_ref, ['value', 'label', 'resolve']);
return function createError() {
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref$path = _ref.path;
var path = _ref$path === undefined ? orginalPath : _ref$path;
var _ref$message = _ref.message;
var message = _ref$message === undefined ? orginalMessage : _ref$message;
var _ref$type = _ref.type;
var type = _ref$type === undefined ? originalType : _ref$type;
var params = _ref.params;
var _ref2$path = _ref2.path;
var path = _ref2$path === undefined ? opts.path : _ref2$path;
var _ref2$message = _ref2.message;
var message = _ref2$message === undefined ? opts.message : _ref2$message;
var _ref2$type = _ref2.type;
var type = _ref2$type === undefined ? opts.name : _ref2$type;
var params = _ref2.params;
return new ValidationError(formatError(message, _extends({ path: path, value: value, label: label }, orginalParams, params)), value, path, type);
params = resolveParams(opts.params, params, resolve);
return new ValidationError(formatError(message, _extends({ path: path, value: value, label: label }, params)), value, path, type);
};

@@ -36,13 +56,21 @@ }

function validate(_ref2) {
var value = _ref2.value;
var path = _ref2.path;
var label = _ref2.label;
var parent = _ref2.state.parent;
function validate(_ref3) {
var value = _ref3.value;
var path = _ref3.path;
var label = _ref3.label;
var parent = _ref3.state.parent;
var rest = _objectWithoutProperties(_ref2, ['value', 'path', 'label', 'state']);
var rest = _objectWithoutProperties(_ref3, ['value', 'path', 'label', 'state']);
var createError = createErrorFactory(message, path, value, params, name, label);
var ctx = _extends({ path: path, parent: parent, createError: createError, type: name }, rest);
var resolve = function resolve(value) {
return Ref.isRef(value) ? value.getValue(parent, rest.options.context) : value;
};
var createError = createErrorFactory({
message: message, path: path, value: value, params: params,
label: label, resolve: resolve, name: name
});
var ctx = _extends({ path: path, parent: parent, type: name, createError: createError, resolve: resolve }, rest);
return new Promise(function (resolve, reject) {

@@ -49,0 +77,0 @@ !useCallback ? resolve(test.call(ctx, value)) : test.call(ctx, value, function (err, valid) {

@@ -1,19 +0,51 @@

"use strict";
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
exports.__esModule = true;
var Reference = (function () {
function Reference(string) {
_classCallCheck(this, Reference);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
this._deps = [];
var getter = require('property-expr').getter;
var validateName = function validateName(d) {
if (typeof d !== 'string') throw new TypeError('ref\'s must be strings, got: ' + d);
};
var Ref = (function () {
Ref.isRef = function isRef(value) {
return !!(value && (value.__isYupRef || value instanceof Ref));
};
function Ref(key, mapFn) {
var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
_classCallCheck(this, Ref);
validateName(key);
var prefix = options.contextPrefix || '$';
this.key = key;
this.prefix = prefix;
this.isContext = key.indexOf(prefix) === 0;
this.path = this.isContext ? this.key.slice(this.prefix.length) : this.key;
this.map = mapFn || function (value) {
return value;
};
}
Reference.prototype["default"] = function _default() {};
Ref.prototype.getValue = function getValue(parent, context) {
var isContext = this.isContext;
Reference.prototype.cast = function cast(value, parent, options) {
return parent["default"](undefined).cast(value, options);
if (isContext && !context || !isContext && !context && !parent) throw new Error('missing the context necessary to cast this value');
var value = getter(this.path)(isContext ? context : parent || context);
return this.map(value);
};
return Reference;
})();
return Ref;
})();
exports['default'] = Ref;
Ref.prototype.__isYupRef = true;
module.exports = exports['default'];

@@ -1,9 +0,11 @@

"use strict";
'use strict';
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var hasOwnProperty = Object.prototype.hasOwnProperty;
var _require = require('./_');
var _has = _require.has;
module.exports = (function () {

@@ -14,2 +16,3 @@ function BadSet() {

this._map = Object.create(null);
this._refs = Object.create(null);
}

@@ -29,3 +32,3 @@

BadSet.prototype["delete"] = function _delete(item) {
BadSet.prototype['delete'] = function _delete(item) {
delete this._map[stringify(item)];

@@ -35,7 +38,7 @@ };

BadSet.prototype.has = function has(item) {
return hasOwnProperty.call(this._map, stringify(item));
return _has(this._map, stringify(item));
};
_createClass(BadSet, [{
key: "length",
key: 'length',
get: function get() {

@@ -42,0 +45,0 @@ return Object.keys(this._map).length;

{
"name": "yup",
"version": "0.14.2",
"version": "0.15.0",
"description": "Dead simple Object schema validation",

@@ -39,3 +39,2 @@ "main": "lib/index.js",

"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.2.0",
"karma-sourcemap-loader": "^0.3.5",

@@ -42,0 +41,0 @@ "karma-webpack": "^1.7.0",

@@ -25,2 +25,3 @@

- [`ValidationError(String|Array<String> errors, Any value, String path)`](#validationerrorstringarraystring-errors-any-value-string-path)
- [`ref(String path, Object options)`](#refstring-path-object-options)
- [mixed](#mixed)

@@ -43,3 +44,3 @@ - [`mixed.clone()`](#mixedclone)

- [`mixed.notOneOf(Array<Any> arrayOfValues, [String message])`](#mixednotoneofarrayany-arrayofvalues-string-message)
- [`mixed.when(String key, Object options | Function func)`](#mixedwhenstring-key-object-options--function-func)
- [`mixed.when(String|Array<String> keys, Object options | Function func)`](#mixedwhenstringarraystring-keys-object-options--function-func)
- [`mixed.test(String name, String message, Function fn, [Bool callbackStyleAsync])`](#mixedteststring-name-string-message-function-fn-bool-callbackstyleasync)

@@ -50,4 +51,4 @@ - [`mixed.test(Object options)`](#mixedtestobject-options)

- [`string.required([String message])`](#stringrequiredstring-message)
- [`string.min(Number limit, [String message])`](#stringminnumber-limit-string-message)
- [`string.max(Number limit, [String message])`](#stringmaxnumber-limit-string-message)
- [`string.min(Number|Ref limit, [String message])`](#stringminnumberref-limit-string-message)
- [`string.max(Number|Ref limit, [String message])`](#stringmaxnumberref-limit-string-message)
- [`string.matches(Regex regex, [String message])`](#stringmatchesregex-regex-string-message)

@@ -60,4 +61,4 @@ - [`string.email([String message])`](#stringemailstring-message)

- [number](#number)
- [`number.min(Number limit, [String message])`](#numberminnumber-limit-string-message)
- [`number.max(Number limit, [String message])`](#numbermaxnumber-limit-string-message)
- [`number.min(Number|Ref limit, [String message])`](#numberminnumberref-limit-string-message)
- [`number.max(Number|Ref limit, [String message])`](#numbermaxnumberref-limit-string-message)
- [`number.positive([String message])`](#numberpositivestring-message)

@@ -69,9 +70,9 @@ - [`number.negative([String message])`](#numbernegativestring-message)

- [date](#date)
- [`date.min(Date|String limit, [String message])`](#datemindatestring-limit-string-message)
- [`date.max(Date|String limit, [String message])`](#datemaxdatestring-limit-string-message)
- [`date.min(Date|String|Ref limit, [String message])`](#datemindatestringref-limit-string-message)
- [`date.max(Date|String|Ref limit, [String message])`](#datemaxdatestringref-limit-string-message)
- [array](#array)
- [`array.of(Schema type)`](#arrayofschema-type)
- [`array.required([String message])`](#arrayrequiredstring-message)
- [`array.min(Number limit, [String message])`](#arrayminnumber-limit-string-message)
- [`array.max(Number limit, [String message])`](#arraymaxnumber-limit-string-message)
- [`array.min(Number|Ref limit, [String message])`](#arrayminnumberref-limit-string-message)
- [`array.max(Number|Ref limit, [String message])`](#arraymaxnumberref-limit-string-message)
- [`array.compact(Function rejector)`](#arraycompactfunction-rejector)

@@ -193,3 +194,22 @@ - [object](#object)

#### `ref(String path, Object options)`
Creates a reference to another sibling or sibling descendant field. Ref's are resolved
at _run time_ and supported where specified. Ref's are evaluated in in the proper order so that
the ref value is resolved before the field using the ref (be careful of circular dependencies!).
```js
var schema = object({
baz: ref('foo.bar'),
foo: object({
bar: string()
})
x: ref('$x')
})
inst.cast({ foo: { bar: 'boom' } }, { context: { x: 5 } })
// { baz: 'boom', x: 5, { foo: { bar: 'boom' } }, }
```
### mixed

@@ -374,3 +394,3 @@

#### `mixed.when(String key, Object options | Function func)`
#### `mixed.when(String|Array<String> keys, Object options | Function func)`

@@ -384,7 +404,4 @@ Adjust the schema based on a sibling or sibling children fields. You can provide an object

Alternatively you can provide a function the returns a schema (called with the value of the key
and the current schema). `when` conditions are additive.
Like joi you can also prefix properties with `$` to specify a property that is dependent
on `context` passed in by `validate()` or `isValid`.
on `context` passed in by `validate()` or `isValid`. `when` conditions are additive.

@@ -408,3 +425,39 @@ ```javascript

You can also specify more than one dependent key, in which case each value will be spread as an argument.
```javascript
var inst = yup.object({
isSpecial: yup.bool()
isBig: yup.bool(),
count: yup.number()
.when(['isBig', 'isSpecial'], {
is: true, // alternatively: (isBig, isSpecial) => isBig && isSpecial
then: yup.number().min(5),
otherwise: yup.number().min(0)
})
})
inst.validate({
isBig: true,
isSpecial: true,
count: 10
})
```
Alternatively you can provide a function the returns a schema
(called with the value of the key and the current schema).
```js
var inst = yup.object({
isBig: yup.boolean(),
count: yup.number()
.when('isBig', (isBig, schema) => {
return isBig ? schema.min(5) : schema.min(0)
})
})
inst.validate({ isBig: false, count: 4 })
```
#### `mixed.test(String name, String message, Function fn, [Bool callbackStyleAsync])`

@@ -551,7 +604,7 @@

#### `string.min(Number limit, [String message])`
#### `string.min(Number|Ref limit, [String message])`
Set an minimum length limit for the string value. The `${min}` interpolation can be used in the `message` argument
#### `string.max(Number limit, [String message])`
#### `string.max(Number|Ref limit, [String message])`

@@ -601,3 +654,3 @@ Set an maximum length limit for the string value. The `${max}` interpolation can be used in the `message` argument

#### `number.min(Number limit, [String message])`
#### `number.min(Number|Ref limit, [String message])`

@@ -607,3 +660,3 @@ Set the minimum value allowed. The `${min}` interpolation can be used in the

#### `number.max(Number limit, [String message])`
#### `number.max(Number|Ref limit, [String message])`

@@ -651,7 +704,7 @@ Set the maximum value allowed. The `${max}` interpolation can be used in the

#### `date.min(Date|String limit, [String message])`
#### `date.min(Date|String|Ref limit, [String message])`
Set the minimum date allowed.
#### `date.max(Date|String limit, [String message])`
#### `date.max(Date|String|Ref limit, [String message])`

@@ -684,7 +737,7 @@ Set the maximum date allowed.

#### `array.min(Number limit, [String message])`
#### `array.min(Number|Ref limit, [String message])`
Set an minimum length limit for the array. The `${min}` interpolation can be used in the `message` argument.
#### `array.max(Number limit, [String message])`
#### `array.max(Number|Ref limit, [String message])`

@@ -691,0 +744,0 @@ Set an maximum length limit for the array. The `${max}` interpolation can be used in the `message` argument.

@@ -112,3 +112,5 @@ 'use strict';

params: { min },
test: value => isAbsent(value) || value.length >= min
test(value) {
return isAbsent(value) || value.length >= this.resolve(min)
}
})

@@ -124,3 +126,5 @@ },

params: { max },
test: value => isAbsent(value) || value.length <= max
test(value) {
return isAbsent(value) || value.length <= this.resolve(max)
}
})

@@ -127,0 +131,0 @@ },

@@ -45,3 +45,5 @@ 'use strict';

params: { min: min },
test: value => isAbsent(value) || (value >= limit)
test(value) {
return isAbsent(value) || value >= this.resolve(limit)
}
})

@@ -61,3 +63,5 @@ },

params: { max: max },
test: value => isAbsent(value) || (value <= limit)
test(value) {
return isAbsent(value) || value <= this.resolve(limit)
}
})

@@ -64,0 +68,0 @@ }

'use strict';
var mixed = require('./mixed')
, bool = require('./boolean');
, bool = require('./boolean')
, Ref = require('./util/reference');

@@ -20,2 +21,3 @@ var isSchema = schema => schema && !!schema.__isYupSchema__;

ValidationError: require('./util/validation-error'),
ref: (key, options) => new Ref(key, options),

@@ -22,0 +24,0 @@ isSchema,

@@ -5,3 +5,2 @@ 'use strict';

, Condition = require('./util/condition')
, ValidationError = require('./util/validation-error')
, locale = require('./locale.js').mixed

@@ -12,3 +11,4 @@ , _ = require('./util/_')

, createValidation = require('./util/createValidation')
, BadSet = require('./util/set');
, BadSet = require('./util/set')
, Ref = require('./util/reference');

@@ -30,2 +30,3 @@ let notEmpty = value => !isAbsent(value);

this._deps = []
this._conditions = []
this._options = { abortEarly: true, recursive: true }

@@ -106,5 +107,5 @@ this._exclusive = Object.create(null)

cast(_value, _opts) {
var schema = this._resolve((_opts || {}).context)
return schema._cast(_value, _opts)
cast(value, opts = {}) {
var schema = this._resolve(opts.context, opts.parent)
return schema._cast(value, opts)
},

@@ -123,5 +124,5 @@

_resolve(context, parent){
if (this._deps.length) {
return this._deps.reduce((schema, match) =>
_resolve(context, parent) {
if (this._conditions.length) {
return this._conditions.reduce((schema, match) =>
match.resolve(schema, match.getValue(parent, context)), this)

@@ -194,3 +195,3 @@ }

default(def) {
if( arguments.length === 0){
if (arguments.length === 0) {
var dflt = _.has(this, '_default') ? this._default : this._defaultDefault

@@ -286,8 +287,13 @@ return typeof dflt === 'function'

when(key, options){
when(keys, options) {
var next = this.clone()
, dep = new Condition(key, next._type, options);
, deps = [].concat(keys).map(key => new Ref(key));
next._deps.push(dep)
deps.forEach(dep => {
if (!dep.isContext)
next._deps.push(dep.key)
})
next._conditions.push(new Condition(deps, options))
return next

@@ -305,3 +311,5 @@ },

return this.createError({
params: { type: this.schema._type }
params: {
type: this.schema._type
}
})

@@ -330,4 +338,8 @@ return true

let valids = this.schema._whitelist
if (valids.length && !(valids.has(value) || isAbsent(value)))
return this.createError({ params: { values: valids.values().join(', ') }})
if (valids.length && !(value === undefined || valids.has(value)))
return this.createError({
params: {
values: valids.values().join(', ')
}
})
return true

@@ -354,3 +366,7 @@ }

if (invalids.length && invalids.has(value))
return this.createError({ params: { values: invalids.values().join(', ') }})
return this.createError({
params: {
values: invalids.values().join(', ')
}
})
return true

@@ -357,0 +373,0 @@ }

@@ -42,3 +42,5 @@ 'use strict';

message: msg || locale.min,
test: value => isAbsent(value) || value >= min
test(value) {
return isAbsent(value) || value >= this.resolve(min)
}
})

@@ -53,3 +55,5 @@ },

message: msg || locale.max,
test: value => isAbsent(value) || value <= max
test(value) {
return isAbsent(value) || value <= this.resolve(max)
}
})

@@ -56,0 +60,0 @@ },

@@ -7,2 +7,3 @@ 'use strict';

, split = require('property-expr').split
, Ref = require('./util/reference')
, c = require('case')

@@ -15,3 +16,3 @@ , {

, collectErrors
, has } = require('./util/_');
, isSchema, has } = require('./util/_');

@@ -28,7 +29,5 @@ let isRecursive = schema => (schema._subType || schema) === '$this'

let childSchema = (field, parent) => {
return isRecursive(field)
? field.of
? field.of(parent)
: parent
: field
if (!isRecursive(field)) return field
return field.of ? field.of(parent) : parent
}

@@ -84,3 +83,3 @@

_cast(_value, _opts) {
_cast(_value, _opts = {}) {
var schema = this

@@ -99,11 +98,28 @@ , value = MixedSchema.prototype._cast.call(schema, _value)

schema.withMutation(() => {
let innerOptions = { ..._opts, context: {} };
let innerOptions = { ..._opts, parent: {} };
value = transform(props, function(obj, prop) {
var exists = has(value, prop);
let field = fields[prop]
let exists = has(value, prop);
if (exists && fields[prop]) {
var fieldSchema = childSchema(fields[prop], schema.default(undefined))
if (Ref.isRef(field)) {
let refValue = field.getValue(obj, innerOptions.context)
if (refValue !== undefined)
obj[prop] = refValue
}
else if (exists && field) {
// ugly optimization avoiding a clone. clears default for recursive
// cast and resets it below;
let hasDflt = has(schema, '_default')
, dflt = schema._default;
let fieldSchema = childSchema(field, schema.default(undefined))
obj[prop] = fieldSchema.cast(value[prop], innerOptions)
if (hasDflt) schema.default(dflt)
else delete schema._default
}

@@ -113,4 +129,4 @@ else if (exists && !strip)

else if(fields[prop]) {
var fieldDefault = fields[prop].default ? fields[prop].default() : undefined
else if (field) {
var fieldDefault = field.default ? field.default() : undefined

@@ -120,5 +136,3 @@ if (fieldDefault !== undefined)

}
}, innerOptions.context)
delete schema._default
}, innerOptions.parent)
})

@@ -253,17 +267,21 @@

for (var key in fields) if (has(fields, key)) {
if (!~nodes.indexOf(key)) nodes.push(key)
let value = fields[key];
fields[key]._deps &&
fields[key]._deps.forEach(dep => { //eslint-disable-line no-loop-func
if (dep.isContext)
return
if (!~nodes.indexOf(key))
nodes.push(key)
var node = split(dep.key)[0]
let addNode = depPath => { //eslint-disable-line no-loop-func
var node = split(depPath)[0]
if (!~nodes.indexOf(node))
nodes.push(node)
if (!~nodes.indexOf(node))
nodes.push(node)
if (!~excludes.indexOf(`${key}-${node}`))
edges.push([key, node])
})
if (!~excludes.indexOf(`${key}-${node}`))
edges.push([key, node])
}
if (Ref.isRef(value) && !value.isContext)
addNode(value.path)
else if (isSchema(value))
value._deps.forEach(addNode)
}

@@ -270,0 +288,0 @@

@@ -36,3 +36,3 @@ 'use strict';

required(msg){
required(msg) {
var next = MixedSchema.prototype.required.call(this, msg || mixed.required )

@@ -47,3 +47,3 @@

min(min, msg){
min(min, msg) {
return this.test({

@@ -54,7 +54,9 @@ name: 'min',

params: { min },
test: value => isAbsent(value) || value.length >= min
test(value) {
return isAbsent(value) || value.length >= this.resolve(min)
}
})
},
max(max, msg){
max(max, msg) {
return this.test({

@@ -65,7 +67,9 @@ name: 'max',

params: { max },
test: value => isAbsent(value) || value.length <= max
test(value) {
return isAbsent(value) || value.length <= this.resolve(max)
}
})
},
matches(regex, msg){
matches(regex, msg) {
return this.test({

@@ -78,7 +82,7 @@ message: msg || locale.matches,

email(msg){
email(msg) {
return this.matches(rEmail, msg || locale.email);
},
url(msg){
url(msg) {
return this.matches(rUrl, msg || locale.url);

@@ -88,3 +92,3 @@ },

//-- transforms --
trim(msg){
trim(msg) {
msg = msg || locale.trim

@@ -97,3 +101,3 @@

lowercase(msg){
lowercase(msg) {
return this

@@ -100,0 +104,0 @@ .transform(value => !isAbsent(value) ? value.toLowerCase() : value)

'use strict';
var { has, isSchema } = require('./_')
, getter = require('property-expr').getter
var { transform, has, isSchema } = require('./_')

@@ -9,38 +8,36 @@ module.exports = Conditional

constructor(key, type, options){
let { is, then, otherwise } = options
, prefix = options.contextPrefix || '$';
constructor(refs, options) {
let { is, then, otherwise } = options;
this.prefix = prefix;
this.key = key
this.isContext = key.indexOf(prefix) === 0
this.refs = [].concat(refs)
if ( typeof options === 'function')
if (typeof options === 'function')
this.fn = options
else
{
if( !has(options, 'is') )
if (!has(options, 'is'))
throw new TypeError('`is:` is required for `when()` conditions')
if( !options.then && !options.otherwise )
if (!options.then && !options.otherwise)
throw new TypeError('either `then:` or `otherwise:` is required for `when()` conditions')
is = typeof is === 'function'
? is : ((is, value) => is === value).bind(null, is)
this.fn = (value, ctx) => is(value) ? ctx.concat(then) : ctx.concat(otherwise)
let isFn = typeof is === 'function'
? is : ((...values) => values.every(value => value === is))
this.fn = function (...values) {
let ctx = values.pop();
return isFn(...values) ? ctx.concat(then) : ctx.concat(otherwise)
}
}
}
getValue(parent, context){
var path = this.isContext ? this.key.slice(this.prefix.length) : this.key
getValue(parent, context) {
let values = this.refs.map(r => r.getValue(parent, context))
if ( (this.isContext && !context) || (!this.isContext && !context && !parent))
throw new Error('missing the context necessary to cast this value')
return getter(path)(this.isContext ? context : (parent || context) )
return values
}
resolve(ctx, value) {
let schema = this.fn.call(ctx, value, ctx)
resolve(ctx, values) {
let schema = this.fn.apply(ctx, values.concat(ctx))

@@ -47,0 +44,0 @@ if (schema !== undefined && !isSchema(schema))

'use strict';
var Promise = require('promise/lib/es6-extensions')
, ValidationError = require('./validation-error');
, ValidationError = require('./validation-error')
, Ref = require('./reference')
, { transform } = require('./_');
let formatError = ValidationError.formatError
function createErrorFactory(orginalMessage, orginalPath, value, orginalParams, originalType, label) {
return function createError({ path = orginalPath, message = orginalMessage, type = originalType, params } = {}) {
function resolveParams(oldParams, newParams, resolve) {
let start = { ...oldParams, ...newParams }
return transform(start, (obj, value, key) => {
obj[key] = resolve(value)
})
}
function createErrorFactory({ value, label, resolve, ...opts}) {
return function createError({ path = opts.path, message = opts.message, type = opts.name, params } = {}) {
params = resolveParams(opts.params, params, resolve)
return new ValidationError(
formatError(message, { path, value, label, ...orginalParams, ...params }), value, path, type)
formatError(message, { path, value, label, ...params })
, value
, path
, type)
}

@@ -18,5 +32,13 @@ }

function validate({ value, path, label, state: { parent }, ...rest }) {
var createError = createErrorFactory(message, path, value, params, name, label)
var ctx = { path, parent, createError, type: name, ...rest }
var resolve = (value) => Ref.isRef(value)
? value.getValue(parent, rest.options.context)
: value
var createError = createErrorFactory({
message, path, value, params
, label, resolve, name
})
var ctx = { path, parent, type: name, createError, resolve, ...rest }
return new Promise((resolve, reject) => {

@@ -23,0 +45,0 @@ !useCallback

@@ -0,13 +1,36 @@

var getter = require('property-expr').getter
let validateName = d => {
if (typeof d !== 'string')
throw new TypeError('ref\'s must be strings, got: ' + d)
}
class Reference {
constructor(string) {
this._deps = []
export default class Ref {
static isRef(value) {
return !!(value && (value.__isYupRef || value instanceof Ref))
}
default() {}
cast(value, parent, options){
return parent.default(undefined).cast(value, options)
constructor(key, mapFn, options = {}) {
validateName(key)
let prefix = options.contextPrefix || '$';
this.key = key;
this.prefix = prefix;
this.isContext = key.indexOf(prefix) === 0
this.path = this.isContext ? this.key.slice(this.prefix.length) : this.key
this.map = mapFn || (value => value);
}
}
getValue(parent, context) {
let isContext = this.isContext
if ((isContext && !context) || (!isContext && !context && !parent))
throw new Error('missing the context necessary to cast this value')
let value = getter(this.path)(isContext ? context : (parent || context))
return this.map(value)
}
}
Ref.prototype.__isYupRef = true

@@ -1,2 +0,2 @@

var hasOwnProperty = Object.prototype.hasOwnProperty
var { has } = require('./_')

@@ -7,2 +7,3 @@ module.exports = class BadSet {

this._map = Object.create(null)
this._refs = Object.create(null)
}

@@ -27,3 +28,3 @@

has(item){
return hasOwnProperty.call(this._map, stringify(item))
return has(this._map, stringify(item))
}

@@ -30,0 +31,0 @@ }

@@ -74,3 +74,3 @@ 'use strict';

it('should ignore absent values', function(){
return Promise.all([
return Promise.all([
mixed()

@@ -81,11 +81,17 @@ .oneOf(['hello'])

mixed()
.nullable()
.oneOf(['hello'])
.required()
.isValid(null)
.should.eventually.equal(false),
string()
mixed()
.oneOf(['hello'])
.required()
.isValid(undefined)
.should.eventually.equal(false),
mixed()
.nullable()
.oneOf(['hello'])
.required()
.isValid(null)
.should.eventually.equal(true)
.should.eventually.equal(false)
])

@@ -415,2 +421,25 @@ })

it('should handle multiple conditionals', function() {
let called = false
var inst = mixed()
.when(['prop', 'other'], function(prop, other) {
other.should.equal(true)
prop.should.equal(1)
called = true
})
inst.cast({}, { context: { prop: 1, other: true }})
called.should.equal(true)
inst = mixed().when(['prop', 'other'], {
is: 5,
then: mixed().required()
})
return inst
.isValid(undefined, { context: { prop: 5, other: 5 }})
.should.eventually.equal(false)
})
it('should require context when needed', function(){

@@ -448,15 +477,15 @@ var inst = mixed()

it('should use label in error message', function () {
var label = 'Label'
var inst = object({
prop: string().required().label(label)
})
it('should use label in error message', function () {
var label = 'Label'
var inst = object({
prop: string().required().label(label)
})
return Promise.all([
inst.validate({}).should.be.rejected.then(function (err) {
err.message.should.equal(`${label} is a required field`)
})
])
return Promise.all([
inst.validate({}).should.be.rejected.then(function (err) {
err.message.should.equal(`${label} is a required field`)
})
])
})
})

@@ -6,9 +6,6 @@ 'use strict';

, Promise = require('promise/src/es6-extensions')
, mixed = require('../src/mixed')
, string = require('../src/string')
, date = require('../src/date')
, number = require('../src/number')
, bool = require('../src/boolean')
, array = require('../src/array')
, object = require('../src/object');
, {
mixed, string, date, number
, bool, array, object, ref
} = require('../src');

@@ -252,2 +249,23 @@ chai.use(chaiAsPromised);

it('should allow refs', function() {
var schema = object({
quz: ref('baz'),
baz: ref('foo.bar'),
foo: object({
bar: string()
}),
x: ref('$x')
})
schema.cast({ foo: { bar: 'boom' } }, { context: { x: 5 } })
.should.eql({
foo: {
bar: 'boom'
},
baz: 'boom',
quz: 'boom',
x: 5
})
})
it('should allow nesting with "$this"', function(){

@@ -254,0 +272,0 @@ var inst = object().shape({

@@ -7,3 +7,3 @@ 'use strict';

, chaiAsPromised = require('chai-as-promised')
, string = require('../src/string');
, { string, number, object, ref } = require('../src');

@@ -93,2 +93,6 @@ chai.use(chaiAsPromised);

var v = string().min(5);
var obj = object({
len: number(),
name: string().min(ref('len'))
})

@@ -101,3 +105,5 @@ return Promise.all([

v.isValid(null).should.eventually.equal(false), // null -> ''
v.nullable().isValid(null).should.eventually.equal(true) // null -> null
v.nullable().isValid(null).should.eventually.equal(true), // null -> null
obj.isValid({ len: 10, name: 'john' }).should.eventually.equal(false)
])

@@ -109,3 +115,6 @@

var v = string().max(5);
var obj = object({
len: number(),
name: string().max(ref('len'))
})
return Promise.all([

@@ -121,3 +130,5 @@ v.isValid('adgf').should.eventually.equal(true),

v.nullable().isValid(null).should.eventually.equal(true)
v.nullable().isValid(null).should.eventually.equal(true),
obj.isValid({ len: 3, name: 'john' }).should.eventually.equal(false)
])

@@ -124,0 +135,0 @@ })

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc