z-schema
z-schema copied to clipboard
cannot reference self when absolute `id` defined
when a $ref
is set to something starting with a '#', the schema validates as expected, unless the id
property is set to an absolute uri
var ZSchema = require('z-schema');
var data = {
color: "blue"
};
var schema = {
"$schema": "http://json-schema.org/draft-04/hyper-schema",
"id": "color-1.0",
"strictProperties": true,
"additionalProperties": false,
"definitions": {
"color": {
"type": "string",
"enum": [
"blue",
"yellow"
]
}
},
"type": [
"object"
],
"required": [
"color"
],
"properties": {
"color": {
"$ref": "#/definitions/color"
}
}
};
var validator = new ZSchema({});
var valid = validator.validate(data, schema);
var errors;
console.log("1st run:", valid);
if (!valid) {
errors = validator.getLastErrors();
console.log({errors});
}
schema.id = "http://schemas.example.com/color-1.0";
validator = new ZSchema({});
valid = validator.validate(data, schema);
console.log("2nd run:", valid);
if (!valid) {
errors = validator.getLastErrors();
console.log({errors});
}
output
1st run: true
2nd run: false
{ errors:
[ { code: 'UNRESOLVABLE_REFERENCE',
params: [Object],
message: 'Reference could not be resolved: http://schemas.example.com/#/definitions/color',
path: '#/properties/color',
schemaId: 'http://schemas.example.com/color-1.0' } ] }
same result when remote reference set
validator = new ZSchema({});
validator.setRemoteReference(schema.id, schema);
valid = validator.validate(data, schema);
console.log("2nd run:", valid);
if (!valid) {
errors = validator.getLastErrors();
console.log({errors});
}
I've narrowed it down to the SchemaCompilation mergeReference
function, it sets the reference to http://schemas.example.com/#definitions/color
instead of http://schemas.example.com/color-1.0#/definitions/color
. I can fix it by adding a trailing #
(or /
) to the id
, i.e. http://schemas.example.com/color-1.0#
. Is that the expected behavior? I don't understand the purpose of the trailing #
(or /
) in either the $schema
or id
fields