switch keyword

master
Evgeny Poberezkin 2015-12-12 13:41:51 +00:00
parent 7c7abbbc74
commit 318af74629
28 changed files with 239 additions and 151 deletions

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'allOf' }}
{{# def.setupNextLevel }}
@ -11,15 +12,12 @@
{{= it.validate($it) }}
{{? $breakOnError }}
if (valid{{=$it.level}}) {
{{ $closingBraces += '}'; }}
{{?}}
{{# def.ifResultValid }}
{{?}}
{{~}}
{{? $breakOnError }}
{{= $closingBraces.slice(0,-1) }}
{{= $closingBraces.slice(1) }}
{{?}}
{{# def.cleanUp }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'anyOf' }}
{{# def.setupNextLevel }}
@ -34,11 +35,7 @@
if (!{{=$valid}}) {
{{# def.addError:'anyOf' }}
} else {
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}
{{# def.cleanUp }}

View File

@ -98,129 +98,3 @@
{{## def.cleanUpVarErrors: {{ out = it.util.cleanUpVarErrors(out); }} #}}
{{## def._error:_rule:
{
keyword: '{{=_rule}}'
, dataPath: (dataPath || '') + {{= it.errorPath }}
, schemaPath: "{{=$schemaPath}}"
, params: {{# def._errorParams[_rule] }}
{{? it.opts.messages !== false }}
, message: {{# def._errorMessages[_rule] }}
{{?}}
{{? it.opts.verbose }}
, schema: {{# def._errorSchemas[_rule] }}
, parentSchema: validate.schema{{=it.schemaPath}}
, data: {{=$data}}
{{?}}
}
#}}
{{## def.addError:_rule:
var err = {{# def._error:_rule }};
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
errors++;
#}}
{{## def.error:_rule:
{{? !it.compositeRule && $breakOnError }}
validate.errors = [{{# def._error:_rule }}];
return false;
{{??}}
{{# def.addError:_rule }}
{{?}}
#}}
{{## def.checkError:_rule:
if (!{{=$valid}}) {
{{# def.error:_rule }}
}
#}}
{{## def._errorMessages = {
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
enum: "'should be equal to one of values'",
format: "'should match format {{=it.util.escapeQuotes($schema)}}'",
maximum: "'should be {{=$op}} {{=$schema}}'",
minimum: "'should be {{=$op}} {{=$schema}}'",
maxItems: "'should NOT have more than {{=$schema}} items'",
minItems: "'should NOT have less than {{=$schema}} items'",
maxLength: "'should NOT be longer than {{=$schema}} characters'",
minLength: "'should NOT be shorter than {{=$schema}} characters'",
maxProperties: "'should NOT have more than {{=$schema}} properties'",
minProperties: "'should NOT have less than {{=$schema}} properties'",
multipleOf: "'should be multiple of {{=$schema}}'",
not: "'should NOT be valid'",
oneOf: "'should match exactly one schema in oneOf'",
pattern: "'should match pattern \"{{=it.util.escapeQuotes($schema)}}\"'",
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
type: "'should be {{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
patternGroups: "'should NOT have {{=$moreOrLess}} than {{=$limit}} properties matching pattern \"{{=it.util.escapeQuotes($pgProperty)}}\"'"
} #}}
{{## def._errorSchemas = {
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
enum: "validate.schema{{=$schemaPath}}",
format: "{{=it.util.toQuotedString($schema)}}",
maximum: "{{=$schema}}",
minimum: "{{=$schema}}",
maxItems: "{{=$schema}}",
minItems: "{{=$schema}}",
maxLength: "{{=$schema}}",
minLength: "{{=$schema}}",
maxProperties: "{{=$schema}}",
minProperties: "{{=$schema}}",
multipleOf: "{{=$schema}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "{{=it.util.toQuotedString($schema)}}",
required: "validate.schema{{=$schemaPath}}",
type: "{{? $isArray }}['{{= $typeSchema.join(\"','\") }}']{{??}}'{{=$typeSchema}}'{{?}}",
uniqueItems: "{{=$schema}}",
custom: "validate.schema{{=$schemaPath}}",
patternGroups: "validate.schema{{=$schemaPath}}"
} #}}
{{## def._errorParams = {
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
additionalItems: "{ limit: {{=$schema.length}} }",
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{? $deps.length==1 }}{{= it.util.escapeQuotes($deps[0]) }}{{??}}{{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}}' }",
format: "{ format: '{{=it.util.escapeQuotes($schema)}}' }",
maximum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
minimum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
maxItems: "{ limit: {{=$schema}} }",
minItems: "{ limit: {{=$schema}} }",
maxLength: "{ limit: {{=$schema}} }",
minLength: "{ limit: {{=$schema}} }",
maxProperties: "{ limit: {{=$schema}} }",
minProperties: "{ limit: {{=$schema}} }",
multipleOf: "{ multipleOf: {{=$schema}} }",
not: "{}",
oneOf: "{}",
pattern: "{ pattern: '{{=it.util.escapeQuotes($schema)}}' }",
required: "{ missingProperty: '{{=$missingProperty}}' }",
type: "{ type: '{{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
uniqueItems: "{ i: i, j: j }",
custom: "{ keyword: '{{=$rule.keyword}}' }",
patternGroups: "{ reason: '{{=$reason}}', limit: {{=$limit}}, pattern: '{{=it.util.escapeQuotes($pgProperty)}}' }"
} #}}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.missing }}
{{# def.setup:'dependencies' }}
{{# def.setupNextLevel }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'enum' }}
{{ var $i = 'i' + $lvl; }}

136
lib/dot/errors.def Normal file
View File

@ -0,0 +1,136 @@
{{## def._error:_rule:
{
keyword: '{{=_rule}}'
, dataPath: (dataPath || '') + {{= it.errorPath }}
, schemaPath: "{{=$schemaPath}}"
, params: {{# def._errorParams[_rule] }}
{{? it.opts.messages !== false }}
, message: {{# def._errorMessages[_rule] }}
{{?}}
{{? it.opts.verbose }}
, schema: {{# def._errorSchemas[_rule] }}
, parentSchema: validate.schema{{=it.schemaPath}}
, data: {{=$data}}
{{?}}
}
#}}
{{## def.addError:_rule:
var err = {{# def._error:_rule }};
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
errors++;
#}}
{{## def.error:_rule:
{{? !it.compositeRule && $breakOnError }}
validate.errors = [{{# def._error:_rule }}];
return false;
{{??}}
{{# def.addError:_rule }}
{{?}}
#}}
{{## def.checkError:_rule:
if (!{{=$valid}}) {
{{# def.error:_rule }}
}
#}}
{{## def.resetErrors:
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
#}}
{{## def._errorMessages = {
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
enum: "'should be equal to one of values'",
format: "'should match format {{=it.util.escapeQuotes($schema)}}'",
maximum: "'should be {{=$op}} {{=$schema}}'",
minimum: "'should be {{=$op}} {{=$schema}}'",
maxItems: "'should NOT have more than {{=$schema}} items'",
minItems: "'should NOT have less than {{=$schema}} items'",
maxLength: "'should NOT be longer than {{=$schema}} characters'",
minLength: "'should NOT be shorter than {{=$schema}} characters'",
maxProperties: "'should NOT have more than {{=$schema}} properties'",
minProperties: "'should NOT have less than {{=$schema}} properties'",
multipleOf: "'should be multiple of {{=$schema}}'",
not: "'should NOT be valid'",
oneOf: "'should match exactly one schema in oneOf'",
pattern: "'should match pattern \"{{=it.util.escapeQuotes($schema)}}\"'",
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
type: "'should be {{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
patternGroups: "'should NOT have {{=$moreOrLess}} than {{=$limit}} properties matching pattern \"{{=it.util.escapeQuotes($pgProperty)}}\"'",
switch: "'should pass \"switch\" keyword validation'"
} #}}
{{## def._errorSchemas = {
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
enum: "validate.schema{{=$schemaPath}}",
format: "{{=it.util.toQuotedString($schema)}}",
maximum: "{{=$schema}}",
minimum: "{{=$schema}}",
maxItems: "{{=$schema}}",
minItems: "{{=$schema}}",
maxLength: "{{=$schema}}",
minLength: "{{=$schema}}",
maxProperties: "{{=$schema}}",
minProperties: "{{=$schema}}",
multipleOf: "{{=$schema}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "{{=it.util.toQuotedString($schema)}}",
required: "validate.schema{{=$schemaPath}}",
type: "{{? $isArray }}['{{= $typeSchema.join(\"','\") }}']{{??}}'{{=$typeSchema}}'{{?}}",
uniqueItems: "{{=$schema}}",
custom: "validate.schema{{=$schemaPath}}",
patternGroups: "validate.schema{{=$schemaPath}}",
switch: "validate.schema{{=$schemaPath}}"
} #}}
{{## def._errorParams = {
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
additionalItems: "{ limit: {{=$schema.length}} }",
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{? $deps.length==1 }}{{= it.util.escapeQuotes($deps[0]) }}{{??}}{{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}}' }",
format: "{ format: '{{=it.util.escapeQuotes($schema)}}' }",
maximum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
minimum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
maxItems: "{ limit: {{=$schema}} }",
minItems: "{ limit: {{=$schema}} }",
maxLength: "{ limit: {{=$schema}} }",
minLength: "{ limit: {{=$schema}} }",
maxProperties: "{ limit: {{=$schema}} }",
minProperties: "{ limit: {{=$schema}} }",
multipleOf: "{ multipleOf: {{=$schema}} }",
not: "{}",
oneOf: "{}",
pattern: "{ pattern: '{{=it.util.escapeQuotes($schema)}}' }",
required: "{ missingProperty: '{{=$missingProperty}}' }",
type: "{ type: '{{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
uniqueItems: "{ i: i, j: j }",
custom: "{ keyword: '{{=$rule.keyword}}' }",
patternGroups: "{ reason: '{{=$reason}}', limit: {{=$limit}}, pattern: '{{=it.util.escapeQuotes($pgProperty)}}' }",
switch: "{ caseIndex: {{=$caseIndex}} }"
} #}}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'format' }}
{{

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'items' }}
{{# def.setupNextLevel }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'maxItems' }}
if ({{=$data}}.length > {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'maxLength' }}
if ({{# def.strLength }} > {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'maxProperties' }}
if (Object.keys({{=$data}}).length > {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'maximum' }}
{{

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'minItems' }}
if ({{=$data}}.length < {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'minLength' }}
if ({{# def.strLength }} < {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'minProperties' }}
if (Object.keys({{=$data}}).length < {{=$schema}}) {

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'minimum' }}
{{

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'multipleOf' }}
var division{{=$lvl}} = {{=$data}} / {{=$schema}};

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'not' }}
{{# def.setupNextLevel }}
@ -19,12 +20,7 @@
if (valid{{=$it.level}}) {
{{# def.error:'not' }}
} else {
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}
{{??}}
{{# def.addError:'not' }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'oneOf' }}
{{# def.setupNextLevel }}
@ -37,10 +38,5 @@ var {{=$valid}} = false;
if (!{{=$valid}}) {
{{# def.error:'oneOf' }}
} else {
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'pattern' }}
{{ new RegExp($schema); /* test if regexp is valid to fail at compile time rather than in eval */}}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'properties' }}
{{# def.setupNextLevel }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'$ref' }}
{{## def.validateRef:_v:

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.missing }}
{{# def.setup:'required' }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'uniqueItems' }}

71
lib/dot/v5/switch.jst Normal file
View File

@ -0,0 +1,71 @@
{{# def.definitions }}
{{# def.setup:'allOf' }}
{{# def.setupNextLevel }}
{{## def.validateIf:
{{# def.setCompositeRule }}
{{ $breakOnError = true; }}
{{# def._validateSwitchRule:if }} }
{{ $breakOnError = !it.opts.allErrors; }}
{{# def.resetCompositeRule }}
{{=$ifPassed}} = valid{{=$it.level}};
#}}
{{## def.validateThen:
{{? typeof sch.then == 'boolean' }}
{{? sch.then === false }}
{{# def.error:'switch' }}
{{?}}
var valid{{=$it.level}} = {{= sch.then }};
{{??}}
{{# def._validateSwitchRule:then }}
{{?}}
{{# def.ifResultValid }}
#}}
{{## def._validateSwitchRule:_clause:
{{
$it.schema = $sch._clause;
$it.schemaPath = $schemaPath + '[' + $i + ']._clause';
}}
{{= it.validate($it) }}
#}}
{{## def.switchCase:
{{? $sch.if && {{# def.nonEmptySchema:$sch.if }} }}
var {{=$errs}} = errors;
{{# def.validateIf }}
if ({{=$ifPassed}}) {
{{# def.validateThen }}
} else {
{{# def.resetErrors }}
{{ $closingBraces += '}'; }}
{{??}}
{{# def.validateThen }}
{{?}}
#}}
{{
var $ifPassed = 'ifPassed' + it.level
, $shouldContinue;
}}
var {{=$ifPassed}};
{{~ $schema:$sch:$caseIndex }}
{{? caseIndex || !$shouldContinue }}
if (!{{=$ifPassed}}) {
{{# def.switchCase }}
}
{{??}}
{{# def.switchCase }}
{{?}}
{{ $shouldContinue = $sch.continue }}
{{~}}
{{? $breakOnError }}
{{= $closingBraces.slice(1) }}
{{?}}
{{# def.cleanUp }}

View File

@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{ /**
* schema compilation (render) time:

View File

@ -13,7 +13,8 @@ function enableV5(ajv) {
ajv.addKeyword('formatMinimum', { type: 'string', inline: formatLimit('minimum'), errors: false });
ajv.addKeyword('exclusiveFormatMaximum');
ajv.addKeyword('exclusiveFormatMinimum');
ajv.addKeyword('patternGroups');
ajv.addKeyword('patternGroups'); // implemented in properties.jst
ajv.addKeyword('switch', { inline: require('./dotjs/switch'), statements: true, errors: true })
}
function constantMacro(schema) {

View File

@ -7,10 +7,10 @@ var glob = require('glob')
, beautify = require('js-beautify').js_beautify;
var defs = {};
['definitions', 'custom', 'missing'].forEach(function (name) {
['definitions', 'errors', 'custom', 'missing'].forEach(function (name) {
defs[name] = fs.readFileSync(path.join(__dirname, '../lib/dot/' + name + '.def'));
});
var files = glob.sync('../lib/dot/*.jst', { cwd: __dirname });
var files = glob.sync('../lib/dot/**/*.jst', { cwd: __dirname });
var dotjsPath = path.join(__dirname, '../lib/dotjs');
try { fs.mkdirSync(dotjsPath); } catch(e) {}