diff --git a/lib/keyword.js b/lib/keyword.js index 53d95c69d..5ea565c38 100644 --- a/lib/keyword.js +++ b/lib/keyword.js @@ -43,8 +43,6 @@ var definitionSchema = { } }; -var validateDefinition; - /** * Define custom keyword * @this Ajv @@ -56,7 +54,6 @@ function addKeyword(keyword, definition) { /* jshint validthis: true */ /* eslint no-shadow: 0 */ var RULES = this.RULES; - if (RULES.keywords[keyword]) throw new Error('Keyword ' + keyword + ' is already defined'); @@ -64,10 +61,11 @@ function addKeyword(keyword, definition) { throw new Error('Keyword ' + keyword + ' is not a valid identifier'); if (definition) { - validateDefinition = validateDefinition || this.compile(definitionSchema); + this.validateKeyword = this.validateKeyword + || this.compile(definitionSchema, true); - if (!validateDefinition(definition)) - throw new Error('custom keyword definition is invalid: ' + this.errorsText(validateDefinition.errors)); + if (!this.validateKeyword(definition)) + throw new Error('custom keyword definition is invalid: ' + this.errorsText(this.validateKeyword.errors)); var dataType = definition.type; if (Array.isArray(dataType)) { diff --git a/spec/issues/955_removeAdditional_custom_keywords.spec.js b/spec/issues/955_removeAdditional_custom_keywords.spec.js new file mode 100644 index 000000000..4ef949d60 --- /dev/null +++ b/spec/issues/955_removeAdditional_custom_keywords.spec.js @@ -0,0 +1,48 @@ +'use strict'; + +var Ajv = require('../ajv'); +require('../chai').should(); + + +describe('issue #955: option removeAdditional breaks custom keywords', function() { + it('should support custom keywords with option removeAdditional', function() { + var ajv = new Ajv({removeAdditional: 'all'}); + + ajv.addKeyword('minTrimmedLength', { + type: 'string', + compile: function(schema) { + return function(str) { + return str.trim().length >= schema; + }; + }, + metaSchema: {type: 'integer'} + }); + + var schema = { + type: 'object', + properties: { + foo: { + type: 'string', + minTrimmedLength: 3 + } + }, + required: ['foo'] + }; + + var validate = ajv.compile(schema); + + var data = { + foo: ' bar ', + baz: '' + }; + validate(data) .should.equal(true); + data .should.not.have.property('baz'); + + data = { + foo: ' ba ', + baz: '' + }; + validate(data) .should.equal(false); + data .should.not.have.property('baz'); + }); +});