feat: support validating [meta-]schemas against themselves, closes #259
parent
804764dbec
commit
c103dc04b9
17
lib/ajv.js
17
lib/ajv.js
|
@ -106,8 +106,7 @@ function Ajv(opts) {
|
|||
* @return {Function} validating function
|
||||
*/
|
||||
function compile(schema, _meta) {
|
||||
var schemaObj = _addSchema(schema);
|
||||
schemaObj.meta = _meta;
|
||||
var schemaObj = _addSchema(schema, undefined, _meta);
|
||||
return schemaObj.validate || _compile(schemaObj);
|
||||
}
|
||||
|
||||
|
@ -127,8 +126,7 @@ function Ajv(opts) {
|
|||
// can key/id have # inside?
|
||||
key = resolve.normalizeId(key || schema.id);
|
||||
checkUnique(key);
|
||||
var schemaObj = self._schemas[key] = _addSchema(schema, _skipValidation, true);
|
||||
schemaObj.meta = _meta;
|
||||
self._schemas[key] = _addSchema(schema, _skipValidation, _meta, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -248,7 +246,7 @@ function Ajv(opts) {
|
|||
}
|
||||
|
||||
|
||||
function _addSchema(schema, skipValidation, shouldAddSchema) {
|
||||
function _addSchema(schema, skipValidation, meta, shouldAddSchema) {
|
||||
if (typeof schema != 'object') throw new Error('schema should be object');
|
||||
var jsonStr = stableStringify(schema);
|
||||
var cached = self._cache.get(jsonStr);
|
||||
|
@ -259,7 +257,9 @@ function Ajv(opts) {
|
|||
var id = resolve.normalizeId(schema.id);
|
||||
if (id && shouldAddSchema) checkUnique(id);
|
||||
|
||||
if (self._opts.validateSchema !== false && !skipValidation)
|
||||
var willValidate = self._opts.validateSchema !== false && !skipValidation;
|
||||
var recursiveMeta;
|
||||
if (willValidate && !(recursiveMeta = schema.id && schema.id == schema.$schema))
|
||||
validateSchema(schema, true);
|
||||
|
||||
var localRefs = resolve.ids.call(self, schema);
|
||||
|
@ -268,12 +268,15 @@ function Ajv(opts) {
|
|||
id: id,
|
||||
schema: schema,
|
||||
localRefs: localRefs,
|
||||
jsonStr: jsonStr
|
||||
jsonStr: jsonStr,
|
||||
meta: meta
|
||||
});
|
||||
|
||||
if (id[0] != '#' && shouldAddSchema) self._refs[id] = schemaObj;
|
||||
self._cache.put(jsonStr, schemaObj);
|
||||
|
||||
if (willValidate && recursiveMeta) validateSchema(schema, true);
|
||||
|
||||
return schemaObj;
|
||||
}
|
||||
|
||||
|
|
|
@ -457,3 +457,12 @@ describe('issue #240, mutually recursive fragment refs reference a common schema
|
|||
validate({ data: { type: 'Foo', id: '123' } }) .should.equal(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('issue #259, support validating [meta-]schemas against themselves', function() {
|
||||
it('should add schema before validation if "id" is the same as "$schema"', function() {
|
||||
var ajv = new Ajv;
|
||||
var hyperSchema = require('./remotes/hyper-schema.json');
|
||||
ajv.addMetaSchema(hyperSchema);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/hyper-schema#",
|
||||
"id": "http://json-schema.org/draft-04/hyper-schema#",
|
||||
"title": "JSON Hyper-Schema",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "http://json-schema.org/draft-04/schema#"
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"definitions": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"patternProperties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"allOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"anyOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"oneOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"not": {
|
||||
"$ref": "#"
|
||||
},
|
||||
|
||||
"links": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/linkDescription"
|
||||
}
|
||||
},
|
||||
"fragmentResolution": {
|
||||
"type": "string"
|
||||
},
|
||||
"media": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "A media type, as described in RFC 2046",
|
||||
"type": "string"
|
||||
},
|
||||
"binaryEncoding": {
|
||||
"description": "A content encoding scheme, as described in RFC 2045",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pathStart": {
|
||||
"description": "Instances' URIs must start with this value for this schema to apply to them",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"schemaArray": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
}
|
||||
},
|
||||
"linkDescription": {
|
||||
"title": "Link Description Object",
|
||||
"type": "object",
|
||||
"required": [ "href", "rel" ],
|
||||
"properties": {
|
||||
"href": {
|
||||
"description": "a URI template, as defined by RFC 6570, with the addition of the $, ( and ) characters for pre-processing",
|
||||
"type": "string"
|
||||
},
|
||||
"rel": {
|
||||
"description": "relation to the target resource of the link",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "a title for the link",
|
||||
"type": "string"
|
||||
},
|
||||
"targetSchema": {
|
||||
"description": "JSON Schema describing the link target",
|
||||
"$ref": "#"
|
||||
},
|
||||
"mediaType": {
|
||||
"description": "media type (as defined by RFC 2046) describing the link target",
|
||||
"type": "string"
|
||||
},
|
||||
"method": {
|
||||
"description": "method for requesting the target of the link (e.g. for HTTP this might be \"GET\" or \"DELETE\")",
|
||||
"type": "string"
|
||||
},
|
||||
"encType": {
|
||||
"description": "The media type in which to submit data along with the request",
|
||||
"type": "string",
|
||||
"default": "application/json"
|
||||
},
|
||||
"schema": {
|
||||
"description": "Schema describing the data to submit along with the request",
|
||||
"$ref": "#"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "{+id}"
|
||||
},
|
||||
{
|
||||
"rel": "full",
|
||||
"href": "{+($ref)}"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue