refactor validate generator

master
Evgeny Poberezkin 2015-05-31 12:21:41 +01:00
parent 0021032091
commit d784d95959
5 changed files with 82 additions and 20 deletions

View File

@ -7,20 +7,21 @@ var doT = require('dot')
, resolve = require('./resolve');
var RULES = require('./rules')
, validateTemplateStr = fs.readFileSync(__dirname + '/validate.dot.js')
, validateTemplate = doT.compile(validateTemplateStr);
, validateGenerator = require('./validate');
// , validateTemplateStr = fs.readFileSync(__dirname + '/validate.dot.js')
// , validateTemplate = doT.compile(validateTemplateStr);
module.exports = compile;
function compile(schema) {
var self = this;
var validateCode = validateTemplate({
var validateCode = validateGenerator({
isRoot: true,
schema: schema,
schemaPath: '',
RULES: RULES,
validate: validateTemplate,
validate: validateGenerator,
copy: copy,
toHash: toHash,
resolveRef: resolveRef,
@ -63,19 +64,11 @@ function copy(o, to) {
}
function getDataType(data) {
if (data === null) return 'null';
if (Array.isArray(data)) return 'array';
return typeof data;
}
function checkDataType(dataType) {
switch (dataType) {
case 'null': return 'data === null';
case 'array': return 'Array.isArray(data)';
case 'object': return '(data && typeof data == "object" && !Array.isArray(data))';
// case 'object': return 'Object.prototype.toString.call(data).slice(8,-1) == "Object"';
case 'integer': return '(typeof data == "number" && !(data % 1))'
default: return 'typeof data == "' + dataType + '"';
}

View File

@ -17,11 +17,8 @@ function (data, dataPath) {
var $propertyKeys = Object.keys(it.schema || {})
, $pProperties = it.parentSchema.patternProperties || {}
, $pPropertyKeys = $pProperties && Object.keys($pProperties)
, $aProperties = it.parentSchema.additionalProperties;
}}
{{
var $noAdditional = $aProperties === false
, $aProperties = it.parentSchema.additionalProperties
, $noAdditional = $aProperties === false
, $additionalIsSchema = typeof $aProperties == 'object'
&& Object.keys($aProperties).length
, $checkAdditional = $noAdditional || $additionalIsSchema;

View File

@ -6,7 +6,7 @@
*
* runtime:
* "validate" is a variable name to which this function will be assigned
* copy, getDataType etc. are defined in the parent scope in index.js
* validateRef etc. are defined in the parent scope in index.js
*/ }}
function (data{{? !it.isRoot }}, dataPath{{?}}) {
@ -66,4 +66,4 @@ function (data{{? !it.isRoot }}, dataPath{{?}}) {
}
return $use;
}
}}
}}

72
lib/compile/validate.js Normal file
View File

@ -0,0 +1,72 @@
/**
* schema compilation (render) time:
* it = { schema, RULES, _validate, opts }
* it.validate - this template function,
* it is used recursively to generate code for subschemas
*
* runtime:
* "validate" is a variable name to which this function will be assigned
* validateRef etc. are defined in the parent scope in index.js
*/
module.exports = function (it) {
if (it.isRoot) {
it.isRoot = false;
var out = '\nfunction (data) { \n "use strict"; \n';
out += 'var dataPath = ""; \n';
out += 'var errs = validate.errors.length = 0; \n';
} else {
var out = '\nfunction (data, dataPath) { \n "use strict"; \n';
out += 'var errs = validate.errors.length; \n';
}
it.RULES.forEach(function (rulesGroup) {
if (shouldUseGroup(rulesGroup)) {
if (rulesGroup.type) out += 'if (' + (it.checkDataType(rulesGroup.type)) + ') { \n';
rulesGroup.rules.forEach(function (rule) {
if (shouldUseRule(rule)) {
if (rule.inline) out += rule.code(it) + ' \n';
else {
var $it = it.copy(it);
$it.schema = it.schema[rule.keyword];
$it.schemaPath = it.schemaPath + '.' + rule.keyword;
$it.parentSchema = it.schema;
$it.parentSchemaPath = it.schemaPath;
if (!it.opts.allErrors) out += 'var valid = ';
out += '(' + rule.code($it) + ')(data, dataPath); \n';
}
if (!it.opts.allErrors) out += ' if (!valid) return false; \n';
}
});
if (rulesGroup.type) out += ' } \n';
}
});
out += it.opts.allErrors
? 'return errs == validate.errors.length; \n'
: 'return true; \n';
return out + '} \n';
function shouldUseGroup(rulesGroup) {
return rulesGroup.rules.some(function(rule) {
return shouldUseRule(rule);
});
}
function shouldUseRule(rule) {
var use = it.schema.hasOwnProperty(rule.keyword);
if (!use && rule.keyword == 'properties') {
var pProperties = it.schema.patternProperties
, aProperties = it.schema.additionalProperties;
use = (pProperties && Object.keys(pProperties).length) ||
(aProperties === false || typeof aProperties == 'object');
}
return use;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "ajv",
"version": "0.1.4",
"version": "0.1.5",
"description": "Another JSON schema Validator",
"main": "lib/ajv.js",
"scripts": {