What version of Ajv are you using? Does the issue happen if you use the latest version?
6.1.0
Ajv options object
{
allErrors: true,
verbose: true
}
JSON Schema
{
"type": "object",
"properties": {
"title": {
"description": "",
"type": "string"
},
"description": {
"type": "string",
},
"period": {
"type": "daterange"
},
"geo": {
"type": "geocircle"
},
"message": {
"title": "Шаблон сообщения",
"type": "string"
},
"precision": {
"type": "integer"
},
"repeatEmitting": {
"type": "boolean"
}
}
}
daterange:
{
"type": "array",
"items": {
"type": "date",
"minItems": 2,
"maxItems": 2
},
"additionalItems": false
}
geocircle:
{
"type": "object",
"properties": {
"center": {
"type": "object",
"properties": {
"lat": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"lng": {
"type": "number",
"minimum": -180,
"maximum": 180
}
},
"required": ["lat", "lng"]
},
"radius": {
"type": "number",
"minimum": 0
}
},
"required": ["center", "radius"]
}
Sample data
{}
Your code
https://runkit.com/vankop/5a7c86502ba35200123686ad
import Ajv from 'ajv';
import {
dateRangeSchema,
geoCircleSchema
} from 'emp-admin-entity-administration-config-schema';
export const ajv = new Ajv({
allErrors: true,
verbose: true
});
ajv.addFormat('date', {
type: 'integer',
validate: () => false
});
ajv.addFormat('daterange', (dateRange) => {
const validate = ajv.compile(dateRangeSchema);
return validate(dateRange);
});
ajv.addFormat('geocircle', (geoCircle) => {
const validate = ajv.compile(geoCircleSchema);
return validate(geoCircle);
});
const validate = ajv.compile({
"type": "object",
"properties": {
"title": {
"description": "",
"type": "string"
},
"description": {
"type": "string",
},
"period": {
"type": "daterange"
},
"geo": {
"type": "geocircle"
},
"message": {
"title": "Шаблон сообщения",
"type": "string"
},
"precision": {
"type": "integer"
},
"repeatEmitting": {
"type": "boolean"
}
}
});
const valid = validate({});
Validation result, data AFTER validation, error messages
Error:
schema is invalid: data.properties['period'].type should be equal to one of the allowed values, data.properties['period'].type should be array, data.properties['period'].type should match some schema in anyOf, data.properties['geo'].type should be equal to one of the allowed values, data.properties['geo'].type should be array, data.properties['geo'].type should match some schema in anyOf
What results did you expect?
Valid schema
The addFormat function is for adding custom formats not custom types.
Also it seems that what you're trying to achieve doesn't need the whole format validation functions as you can just add $ref to combine these schema's.
WARNING: psuedo code inbound; something along the lines of this should work:
import Ajv from 'ajv';
import {
dateRangeSchema,
geoCircleSchema
} from 'emp-admin-entity-administration-config-schema';
export const ajv = new Ajv({
allErrors: true,
verbose: true
});
ajv.addFormat('date', { /* This would also need to be changed */
type: 'integer',
validate: () => false
});
ajv.addSchema(dateRangeSchema, 'DateRange');
ajv.addSchema(geoCircleSchema, 'GeoCircle');
const validate = ajv.compile({
"type": "object",
"properties": {
"title": {
"description": "",
"type": "string"
},
"description": {
"type": "string",
},
"period": {
"$ref": "DateRange"
},
"geo": {
"$ref": "GeoCircle"
},
"message": {
"title": "Шаблон сообщения",
"type": "string"
},
"precision": {
"type": "integer"
},
"repeatEmitting": {
"type": "boolean"
}
}
});
This still leaves in the date one, not sure what kind of dates you're currently expecting (UNIX timestamps maybe? seeing how you had integer as it's type). Might want to look into using formatted datestrings, these are default formats that JSON Schema has in it's draft. The expected date format here looks like: 2002-07-01T13:50:05Z
This would look like something along the lines of:
{
"type": "array",
"items": {
"type": "string",
"format": "date-time"
},
"minItems": 2,
"maxItems": 2,
"additionalItems": false
}
@M-TGH so if I will specify keyword format instead of type it should work properly?
@vankop Technically yes, however since format keywords only are applied to strings formally (or numbers if specifically assigned to) it won't.
I'd suggest adding the schemas to your ajv instance with addSchema. Then referencing to the key you gave your schema's in your main schema, like this:
const ajv = new Ajv();
ajv.addSchema(dateRangeSchema, 'DateRange'); // You can either specify these keys here or add "$id" keywords to your schema's to reference to
ajv.addSchema(geoCircleSchema, 'GeoCircle');
const validate = ajv.compile({
"type": "object",
"properties": {
"period": {
"$ref": "DateRange", //Reference to the subschema you want to add-in here
},
"geo": {
"$ref": "GeoCircle",
},
});
This compiles to the types from your subschemas being applied in the places where the references are set. E.g. the compiled schema would look like:
{
"type": "object",
"properties": {
"period": {
"type": "array",
"items": {
"type": "date" //Type "date" still is invalid, see my suggestion with using "string" and the date-time format
},
"minItems": 2,
"maxItems": 2,
"additionalItems": false
},
"geo": {
// Your geocircle one here
},
}
Got it thanks!
Most helpful comment
The addFormat function is for adding custom formats not custom types.
Also it seems that what you're trying to achieve doesn't need the whole format validation functions as you can just add $ref to combine these schema's.
WARNING: psuedo code inbound; something along the lines of this should work:
This still leaves in the date one, not sure what kind of dates you're currently expecting (UNIX timestamps maybe? seeing how you had integer as it's type). Might want to look into using formatted datestrings, these are default formats that JSON Schema has in it's draft. The expected date format here looks like: 2002-07-01T13:50:05Z
This would look like something along the lines of: