Skip to content

Commit

Permalink
add type to error
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Oct 18, 2015
1 parent 055707d commit 5d65038
Show file tree
Hide file tree
Showing 19 changed files with 1,595 additions and 2 deletions.
140 changes: 140 additions & 0 deletions lib/array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var MixedSchema = require('./mixed');
var Promise = require('promise/lib/es6-extensions');

var _require = require('./locale.js');

var mixed = _require.mixed;
var locale = _require.array;

var _require2 = require('./util/_');

var inherits = _require2.inherits;
var collectErrors = _require2.collectErrors;

var scopeError = function scopeError(value) {
return function (err) {
err.value = value;
throw err;
};
};

module.exports = ArraySchema;

function ArraySchema() {
if (!(this instanceof ArraySchema)) return new ArraySchema();

MixedSchema.call(this, { type: 'array' });

this.transforms.push(function (values) {
if (typeof values === 'string') try {
values = JSON.parse(values);
} catch (err) {
values = null;
}

if (Array.isArray(values)) return this._subType ? values.map(this._subType.cast, this._subType) : values;

return this.isType(values) ? values : null;
});
}

inherits(ArraySchema, MixedSchema, {

_typeCheck: function _typeCheck(v) {
return Array.isArray(v);
},

_validate: function _validate(_value, _opts, _state) {
var errors = [],
context,
subType,
schema,
endEarly,
recursive;

_state = _state || {};
context = _state.parent || (_opts || {}).context;
schema = this._resolve(context);
subType = schema._subType;
endEarly = schema._option('abortEarly', _opts);
recursive = schema._option('recursive', _opts);

return MixedSchema.prototype._validate.call(this, _value, _opts, _state)['catch'](endEarly ? null : function (err) {
errors = err;
return err.value;
}).then(function (value) {
if (!recursive || !subType || !schema._typeCheck(value)) {
if (errors.length) throw errors[0];
return value;
}

var result = value.map(function (item, key) {
var path = (_state.path || '') + '[' + key + ']',
state = _extends({}, _state, { path: path, key: key, parent: value });

return subType._validate(item, _opts, state);
});

result = endEarly ? Promise.all(result)['catch'](scopeError(value)) : collectErrors(result, value, _state.path, errors);

return result.then(function () {
return value;
});
});
},

of: function of(schema) {
var next = this.clone();
next._subType = schema;
return next;
},

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

return next.min(1, msg || mixed.required);
},

min: function min(_min, message) {
message = message || locale.min;

return this.test({
message: message,
name: 'min',
exclusive: true,
params: { min: _min },
test: function test(value) {
return value && value.length >= _min;
}
});
},

max: function max(_max, message) {
message = message || locale.max;
return this.test({
message: message,
name: 'max',
exclusive: true,
params: { max: _max },
test: function test(value) {
return value && value.length <= _max;
}
});
},

compact: function compact(rejector) {
var reject = !rejector ? function (v) {
return !!v;
} : function (v, i, a) {
return !rejector(v, i, a);
};

return this.transform(function (values) {
return values != null ? values.filter(reject) : values;
});
}
});
23 changes: 23 additions & 0 deletions lib/boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';
var MixedSchema = require('./mixed'),
inherits = require('./util/_').inherits;

module.exports = BooleanSchema;

function BooleanSchema() {
if (!(this instanceof BooleanSchema)) return new BooleanSchema();

MixedSchema.call(this, { type: 'boolean' });

this.transforms.push(function (value) {
if (this.isType(value)) return value;
return /true|1/i.test(value);
});
}

inherits(BooleanSchema, MixedSchema, {

_typeCheck: function _typeCheck(v) {
return typeof v === 'boolean';
}
});
66 changes: 66 additions & 0 deletions lib/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use strict';
var MixedSchema = require('./mixed');
var isoParse = require('./util/isodate');
var locale = require('./locale.js').date;

var _require = require('./util/_');

var isDate = _require.isDate;
var inherits = _require.inherits;

var invalidDate = new Date('');

module.exports = DateSchema;

function DateSchema() {
if (!(this instanceof DateSchema)) return new DateSchema();

MixedSchema.call(this, { type: 'date' });

this.transforms.push(function (value) {
if (this.isType(value)) return isDate(value) ? new Date(value) : value;

value = isoParse(value);
return value ? new Date(value) : invalidDate;
});
}

inherits(DateSchema, MixedSchema, {

_typeCheck: function _typeCheck(v) {
return isDate(v) && !isNaN(v.getTime());
},

min: function min(_min, msg) {
var limit = this.cast(_min);

if (!this._typeCheck(limit)) throw new TypeError('`min` must be a Date or a value that can be `cast()` to a Date');

return this.test({
name: 'min',
exclusive: true,
message: msg || locale.min,
params: { min: _min },
test: function test(value) {
return value && value >= limit;
}
});
},

max: function max(_max, msg) {
var limit = this.cast(_max);

if (!this._typeCheck(limit)) throw new TypeError('`max` must be a Date or a value that can be `cast()` to a Date');

return this.test({
name: 'max',
exclusive: true,
message: msg || locale.max,
params: { max: _max },
test: function test(value) {
return !value || value <= limit;
}
});
}

});
33 changes: 33 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';
var mixed = require('./mixed'),
bool = require('./boolean');

var isSchema = function isSchema(schema) {
return schema && !!schema.__isYupSchema__;
};

module.exports = {
mixed: mixed,
string: require('./string'),
number: require('./number'),
boolean: bool,
bool: bool,
date: require('./date'),
object: require('./object'),
array: require('./array'),

reach: require('./util/reach'),

ValidationError: require('./util/validation-error'),

isSchema: isSchema,

addMethod: function addMethod(schemaType, name, fn) {
if (!schemaType || !isSchema(schemaType.prototype)) throw new TypeError('You must provide a yup schema constructor function');

if (typeof name !== 'string') throw new TypeError('A Method name must be provided');
if (typeof fn !== 'function') throw new TypeError('Method function must be provided');

schemaType.prototype[name] = fn;
}
};
48 changes: 48 additions & 0 deletions lib/locale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

module.exports = {
mixed: {
'default': '${path} is invalid',
notType: '${path} (value: `${value}`) must be a `${type}` type',
required: '${path} is a required field',
oneOf: '${path} must be one the following values: ${values}',
notOneOf: '${path} must not be one the following values: ${values}'
},

string: {
required: '${path} is a required field',
min: '${path} must be at least ${min} characters',
max: '${path} must be less than ${max} characters',
matches: '${path} must match the following: "${regex}"',
email: '${path} must be a valid email',
url: '${path} must be a valid URL',
trim: '${path} must be a trimmed string',
lowercase: '${path} must be a lowercase string',
uppercase: '${path} must be a uppercase string'
},

number: {
min: '${path} must be at least ${min}',
max: '${path} must be less than or equal to ${max}',
positive: '${path} must be a positive number',
negative: '${path} must be a negative number',
integer: '${path} must be an integer'
},

date: {
min: '${path} field must be later than ${min}',
max: '${path} field must be at earlier than ${max}'
},

boolean: {},

object: {
noUnknown: '${path} field cannot have keys not specified in the objcet shape'
},

array: {
required: '${path} is a required field',
min: '${path} field must have at least ${min} items',
max: '${path} field must have less than ${max} items'
}
};
Loading

0 comments on commit 5d65038

Please sign in to comment.