ajv-errors
Advanced tools
Comparing version 0.1.2 to 0.2.0
'use strict'; | ||
module.exports = function (ajv) { | ||
if (!ajv._opts.allErrors) throw new Error('Ajv option allErrors must be true'); | ||
if (!ajv._opts.allErrors) throw new Error('ajv-errors: Ajv option allErrors must be true'); | ||
if (!ajv._opts.jsonPointers) { | ||
console.warn('ajv-errors: Ajv option jsonPointers changed to true'); | ||
ajv._opts.jsonPointers = true; | ||
} | ||
@@ -12,3 +16,2 @@ ajv.addKeyword('errorMessage', { | ||
config: { | ||
CHILD_ERRORS: ['properties', 'items'], | ||
ALLOW_OBJECT: ['required', 'dependencies'] | ||
@@ -15,0 +18,0 @@ }, |
@@ -17,18 +17,10 @@ 'use strict'; | ||
$err = '_em_err' + $lvl, | ||
$child = '_em_child' + $lvl, | ||
$matches = '_em_matches' + $lvl, | ||
$isArray = '_em_isArray' + $lvl, | ||
$errors = '_em_errors' + $lvl, | ||
$nextChar = '_em_nextChar' + $lvl, | ||
$errSchemaPathString = it.util.toQuotedString(it.errSchemaPath); | ||
out += ' var ' + ($dataPath) + ' = (dataPath || \'\') + ' + (it.errorPath) + '; '; | ||
out += ' var ' + ($dataPath) + ' = (dataPath || \'\') + ' + (it.errorPath) + '; var ' + ($i) + ', ' + ($err) + ', ' + ($errors) + '; '; | ||
if (typeof $schema == 'string') { | ||
out += ' var ' + ($i) + ' = 0; var ' + ($err) + '; '; | ||
if (!it.opts.jsonPointers) { | ||
out += 'var ' + ($nextChar) + ';'; | ||
} | ||
out += ' var ' + ($errors) + ' = []; while (' + ($i) + ' < errors) { ' + ($err) + ' = vErrors[' + ($i) + ']; if ( ' + ($err) + '.keyword != \'' + ($keyword) + '\' && (' + ($err) + '.dataPath == ' + ($dataPath) + ' || (' + ($err) + '.dataPath.indexOf(' + ($dataPath) + ') == 0 && '; | ||
if (it.opts.jsonPointers) { | ||
out += ' ' + ($err) + '.dataPath[' + ($dataPath) + '.length] == \'/\' '; | ||
} else { | ||
out += ' (' + ($nextChar) + ' = ' + ($err) + '.dataPath[' + ($dataPath) + '.length]) == \'.\' || ' + ($nextChar) + ' == \'[\' '; | ||
} | ||
out += ')) && ' + ($err) + '.schemaPath.indexOf(' + ($errSchemaPathString) + ') == 0 && ' + ($err) + '.schemaPath[' + (it.errSchemaPath.length) + '] == \'/\') { ' + ($errors) + '.push(' + ($err) + '); vErrors.splice(' + ($i) + ', 1); errors--; } else { ' + ($i) + '++; } } if (' + ($errors) + '.length) { var err = { keyword: \'' + ($keyword) + '\' , dataPath: ' + ($dataPath) + ' , schemaPath: ' + ($errSchemaPathString) + ' + \'/' + ($keyword) + '\' , params: { errors: ' + ($errors) + ' } , message: ' + (it.util.toQuotedString($schema)) + ' '; | ||
out += ' ' + ($i) + ' = 0; ' + ($errors) + ' = []; while (' + ($i) + ' < errors) { ' + ($err) + ' = vErrors[' + ($i) + ']; if ( ' + ($err) + '.keyword != \'' + ($keyword) + '\' && (' + ($err) + '.dataPath == ' + ($dataPath) + ' || (' + ($err) + '.dataPath.indexOf(' + ($dataPath) + ') == 0 && ' + ($err) + '.dataPath[' + ($dataPath) + '.length] == \'/\')) && ' + ($err) + '.schemaPath.indexOf(' + ($errSchemaPathString) + ') == 0 && ' + ($err) + '.schemaPath[' + (it.errSchemaPath.length) + '] == \'/\') { ' + ($errors) + '.push(' + ($err) + '); vErrors.splice(' + ($i) + ', 1); errors--; } else { ' + ($i) + '++; } } if (' + ($errors) + '.length) { var err = { keyword: \'' + ($keyword) + '\' , dataPath: ' + ($dataPath) + ' , schemaPath: ' + ($errSchemaPathString) + ' + \'/' + ($keyword) + '\' , params: { errors: ' + ($errors) + ' } , message: ' + (it.util.toQuotedString($schema)) + ' '; | ||
if (it.opts.verbose) { | ||
@@ -41,13 +33,27 @@ out += ' , schema: ' + (it.util.toQuotedString($schema)) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; | ||
$keywordErrors = {}, | ||
$childErrors = {}; | ||
for (var $key in $schema) { | ||
var $child = $config.CHILD_ERRORS.indexOf($key) >= 0; | ||
($child ? $childErrors : $keywordErrors)[$key] = []; | ||
$childErrors = { | ||
properties: {}, | ||
items: {} | ||
}, | ||
$hasProperties, $hasItems; | ||
for (var $k in $schema) { | ||
switch ($k) { | ||
case 'properties': | ||
for (var $prop in $schema.properties) { | ||
$hasProperties = true; | ||
$childErrors.properties[$prop] = []; | ||
} | ||
break; | ||
case 'items': | ||
for (var $item = 0; $item < $schema.items.length; $item++) { | ||
$hasItems = true; | ||
$childErrors.items[$item] = []; | ||
} | ||
break; | ||
default: | ||
$keywordErrors[$k] = []; | ||
} | ||
} | ||
if (Object.keys($keywordErrors).length) { | ||
out += ' var ' + ($i) + ' = 0; var ' + ($err) + '; '; | ||
if (!it.opts.jsonPointers) { | ||
out += 'var ' + ($nextChar) + ';'; | ||
} | ||
out += ' var ' + ($errors) + ' = ' + (JSON.stringify($keywordErrors)) + '; while (' + ($i) + ' < errors) { ' + ($err) + ' = vErrors[' + ($i) + ']; if ( ' + ($err) + '.keyword in ' + ($errors) + ' && ' + ($err) + '.dataPath == ' + ($dataPath) + ' && ' + ($err) + '.schemaPath.indexOf(' + ($errSchemaPathString) + ') == 0 && /^\\/[^\\/]*$/.test(' + ($err) + '.schemaPath.slice(' + ($errSchemaPathString) + '.length))) { ' + ($errors) + '[' + ($err) + '.keyword].push(' + ($err) + '); vErrors.splice(' + ($i) + ', 1); errors--; } else { ' + ($i) + '++; } } for (var ' + ($key) + ' in ' + ($errors) + ') { if (' + ($errors) + '[' + ($key) + '].length) { var err = { keyword: \'' + ($keyword) + '\' , dataPath: ' + ($dataPath) + ' , schemaPath: ' + ($errSchemaPathString) + ' + \'/' + ($keyword) + '\' , params: { errors: ' + ($errors) + '[' + ($key) + '] } , message: validate.schema' + ($schemaPath) + '[' + ($key) + '] '; | ||
out += ' ' + ($i) + ' = 0; ' + ($errors) + ' = ' + (JSON.stringify($keywordErrors)) + '; while (' + ($i) + ' < errors) { ' + ($err) + ' = vErrors[' + ($i) + ']; if ( ' + ($err) + '.keyword in ' + ($errors) + ' && ' + ($err) + '.dataPath == ' + ($dataPath) + ' && ' + ($err) + '.schemaPath.indexOf(' + ($errSchemaPathString) + ') == 0 && /^\\/[^\\/]*$/.test(' + ($err) + '.schemaPath.slice(' + (it.errSchemaPath.length) + '))) { ' + ($errors) + '[' + ($err) + '.keyword].push(' + ($err) + '); vErrors.splice(' + ($i) + ', 1); errors--; } else { ' + ($i) + '++; } } for (var ' + ($key) + ' in ' + ($errors) + ') { if (' + ($errors) + '[' + ($key) + '].length) { var err = { keyword: \'' + ($keyword) + '\' , dataPath: ' + ($dataPath) + ' , schemaPath: ' + ($errSchemaPathString) + ' + \'/' + ($keyword) + '\' , params: { errors: ' + ($errors) + '[' + ($key) + '] } , message: validate.schema' + ($schemaPath) + '[' + ($key) + '] '; | ||
if (it.opts.verbose) { | ||
@@ -58,2 +64,33 @@ out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; | ||
} | ||
if ($hasProperties || $hasItems) { | ||
out += ' var ' + ($isArray) + ' = Array.isArray(' + ($data) + '); if ('; | ||
if ($hasProperties && $hasItems) { | ||
out += ' typeof ' + ($data) + ' == \'object\' '; | ||
} else if ($hasProperties) { | ||
out += ' typeof ' + ($data) + ' == \'object\' && !' + ($isArray) + ' '; | ||
} else { | ||
out += ' ' + ($isArray) + ' '; | ||
} | ||
out += ') { ' + ($i) + ' = 0; ' + ($errors) + ' = '; | ||
if ($hasProperties && $hasItems) { | ||
out += ' ' + ($isArray) + ' ? ' + (JSON.stringify($childErrors.items)) + ' : ' + (JSON.stringify($childErrors.properties)) + ' '; | ||
} else if ($hasProperties) { | ||
out += ' ' + (JSON.stringify($childErrors.properties)) + ' '; | ||
} else { | ||
out += ' ' + (JSON.stringify($childErrors.items)) + ' '; | ||
} | ||
out += '; var ' + ($child) + ', ' + ($matches) + '; while (' + ($i) + ' < errors) { ' + ($err) + ' = vErrors[' + ($i) + ']; if ( ' + ($err) + '.keyword != \'' + ($keyword) + '\' && ' + ($err) + '.dataPath.indexOf(' + ($dataPath) + ') == 0 && (' + ($matches) + ' = ' + ($err) + '.dataPath.slice(' + ($dataPath) + '.length).match(/^\\/([^\\/]*)(?:\\/|$)/), ' + ($child) + ' = ' + ($matches) + ' && ' + ($matches) + '[1].replace(/~1/g, \'/\').replace(/~0/g, \'~\') ) !== undefined && ' + ($child) + ' in ' + ($errors) + ') { ' + ($errors) + '[' + ($child) + '].push(' + ($err) + '); vErrors.splice(' + ($i) + ', 1); errors--; } else { ' + ($i) + '++; } } for (var ' + ($key) + ' in ' + ($errors) + ') { if (' + ($errors) + '[' + ($key) + '].length) { var err = { keyword: \'' + ($keyword) + '\' , dataPath: ' + ($dataPath) + ' + \'/\' + ' + ($key) + '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\') , schemaPath: ' + ($errSchemaPathString) + ' + \'/' + ($keyword) + '\' , params: { errors: ' + ($errors) + '[' + ($key) + '] } , message: validate.schema' + ($schemaPath) + ' '; | ||
if ($hasProperties && $hasItems) { | ||
out += ' [' + ($isArray) + ' ? \'items\' : \'properties\'] '; | ||
} else if ($hasProperties) { | ||
out += ' .properties '; | ||
} else { | ||
out += ' .items '; | ||
} | ||
out += ' [' + ($key) + '] '; | ||
if (it.opts.verbose) { | ||
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; | ||
} | ||
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } } '; | ||
} | ||
} | ||
@@ -60,0 +97,0 @@ out += ' }'; |
{ | ||
"name": "ajv-errors", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "Custom error messages in JSON-Schema for Ajv validator", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -23,7 +23,8 @@ # ajv-errors | ||
var Ajv = require('ajv'); | ||
var ajv = new Ajv({allErrors: true}); // option allErrors is required | ||
var ajv = new Ajv({allErrors: true, jsonPointers: true}); | ||
// options allErrors and jsonPointers are required | ||
require('ajv-errors')(ajv); | ||
``` | ||
#### Replace all errors in the current schema and subschemas with a single message: | ||
### Replace all errors in the current schema and subschemas with a single message: | ||
@@ -64,3 +65,3 @@ ```javascript | ||
#### Replace errors for certain keywords in the current schema only: | ||
### Replace errors for certain keywords in the current schema only: | ||
@@ -94,3 +95,3 @@ ```javascript | ||
keyword: type, | ||
dataPath: '.foo', | ||
dataPath: '/foo', | ||
// ... | ||
@@ -114,4 +115,60 @@ message: 'should be integer' | ||
### Replace errors for properties / items (and deeper): | ||
```javascript | ||
var schema = { | ||
type: 'object', | ||
required: ['foo', 'bar'], | ||
allOf: [{ | ||
properties: { | ||
foo: { type: 'integer', minimum: 2 }, | ||
bar: { type: 'string', minLength: 2 } | ||
}, | ||
additionalProperties: false | ||
}], | ||
errorMessage: { | ||
properties: { | ||
foo: 'data.foo should be integer >= 2', | ||
bar: 'data.bar should be string with length >= 2' | ||
} | ||
} | ||
}; | ||
var validate = ajv.compile(schema); | ||
console.log(validate({foo: 1, bar: 'a'})); // false | ||
console.log(validate.errors); // processed errors | ||
``` | ||
Processed errors: | ||
```javascript | ||
[ | ||
{ | ||
keyword: 'errorMessage', | ||
message: 'data.foo should be integer >= 2', | ||
dataPath: '/foo', | ||
// ... | ||
params: { | ||
errors: [ | ||
{ keyword: 'minimum' /* , ... */ } | ||
] | ||
}, | ||
}, | ||
{ | ||
keyword: 'errorMessage', | ||
message: 'data.bar should be string with length >= 2', | ||
dataPath: '/bar', | ||
// ... | ||
params: { | ||
errors: [ | ||
{ keyword: 'minLength' /* , ... */ } | ||
] | ||
}, | ||
} | ||
] | ||
``` | ||
## License | ||
[MIT](https://github.com/epoberezkin/ajv-errors/blob/master/LICENSE) |
Sorry, the diff of this file is not supported yet
21317
146
171