This repository has been archived on 2020-11-15. You can view files and clone it, but cannot push or open issues or pull requests.
schemajs/lib/schema.js

121 lines
3.2 KiB
JavaScript
Raw Normal View History

var _ = require('underscore');
var rules = require('./rules.js');
2011-09-23 21:58:47 +00:00
var Schema = function(schema) {
this.schema = schema;
2011-09-23 21:58:47 +00:00
};
2013-09-11 19:20:04 +00:00
var checkArray = function(schema, key, errors, values) {
2014-08-24 05:41:21 +00:00
var valid = true;
values.forEach(function(value, index) {
try {
if(schema.schema.schema) {
// if array has another schema, then we want objects!
value = rules.create(key, {type:'object'}).apply(value);
var results = (new Schema(schema.schema.schema)).validate(value);
if(!results.valid)
{
errors[key] = errors[key] || [];
errors[key][index] = results.errors;
2014-08-24 05:41:21 +00:00
} else {
values[index] = results.data;
}
}
else
2014-08-24 05:41:21 +00:00
values[index] = rules.create(key + "[" + index + "]", schema.schema).apply(value);
} catch (error) {
2014-08-24 05:41:21 +00:00
valid = false;
if (!_.isArray(errors[key])) errors[key] = [];
errors[key][index] = error;
}
});
2014-08-24 05:41:21 +00:00
return valid;
};
/*jshint loopfunc:true*/
2015-02-25 19:26:20 +00:00
Schema.prototype.validate = function(data, opts) {
var params = _.keys(this.schema);
var errors = {};
var values = {};
var value;
var get = typeof(data) == "function" ? data : function(p) {
return data[p];
};
2011-09-23 21:58:47 +00:00
for (var i = 0; i < params.length; i++) {
var schema = this.schema[params[i]];
2011-09-23 21:58:47 +00:00
try {
// if undefined, don't store it.
value = rules.create(params[i], schema).apply(get(params[i]));
// does this rule contain embedded schemas
if (typeof(schema.schema) == "object" &&
!_.isArray(schema.schema) &&
_.keys(schema.schema).length &&
2014-08-24 05:41:21 +00:00
!_.isUndefined(value)) {
if(schema.allownull && _.isNull(value)) {
values[params[i]] = null;
} else {
if (schema.type == "object") {
2014-08-24 05:41:21 +00:00
var results = (new Schema(schema.schema)).validate(value);
if(!results.valid) {
errors[params[i]] = results.errors;
2014-08-24 05:41:21 +00:00
} else {
values[params[i]] = results.data;
}
} else if (schema.type == "array") {
2014-08-24 05:41:21 +00:00
if( checkArray(schema, params[i], errors, value, get)){
values[params[i]] = value;
}
}
}
2014-08-24 06:31:33 +00:00
} else if (!_.isUndefined(value)) {
2014-08-24 05:41:21 +00:00
values[params[i]] = value;
}
} catch (error) {
errors[params[i]] = error;
}
}
2011-09-23 21:58:47 +00:00
2015-05-07 09:01:14 +00:00
if(opts && opts.strict) {
2015-02-25 19:26:20 +00:00
var origKeys = Object.keys(data);
2015-02-25 19:44:04 +00:00
2015-02-25 19:26:20 +00:00
var diff = origKeys.filter(function(i) {
2015-02-25 19:44:04 +00:00
return params.indexOf(i) < 0;
2015-02-25 19:26:20 +00:00
});
diff.forEach(function(field) {
errors[field] = "Additional key not defined in schema";
});
}
return {
data: values,
errors: errors,
valid: _.keys(errors).length === 0
};
2011-09-23 21:58:47 +00:00
};
exports.types = rules.types;
exports.test = function(value, schema) {
return (new Schema({
input: schema
})).validate({
input: value
});
};
exports.properties = rules.properties;
exports.filters = rules.filters;
exports.create = function(schema) {
return new Schema(schema);
};
exports.middleware = function(schema) {
return function(req, res, next) {
2015-11-19 02:41:03 +00:00
req.form = new Schema(schema).validate((req.method || req.route.method || '').toLowerCase() == "post" ? req.body : req.query);
next();
};
};