ajv-keywords
ajv-keywords copied to clipboard
deepProperties support for relative and absolute pointers
Hello,
From the readme for deepProperties: This keyword allows to validate deep properties (identified by JSON pointers).
I have a need to validate 'cousin' properties inside an array. I've tried this:
let schema = {
deepProperties : { "/parent/child1/grandchild1" : {
deepProperties : { "2/child2/grandchild2" : { const : true }}
}}
};
let data = {
parent : {
child1 : {
grandchild1: true
},
child2 : {
grandchild2: false
}
}
};
And got: keyword schema is invalid: data should match format "json-pointer", data property name '2/child2/grandchild2' is invalid.
Tracing a bit - it looks like the validation code from ajv/lib doesn't support relative pointers. I can build another custom keyword to wrap deepProperties I think, but wanted to report this either for fixing or for clarifying.
Thanks!
Koby
I don't understand why you need to validate one deep property from another.
It's possible to allow root-based absolute and relative JSON pointers, but that would mean full rewrite of this keywords and changes in deepRequired - should be a major version change.
I thought about this some more, and I think you're right - I may not need it. I'm doing government forms and have ridiculously complex rules, and am looking to write a generic form and rule generator.
Suppose I have data that looks like this:
{
vehicles: [
{
id: 1,
make: 'honda',
model: 'accord',
//... year, vin, etc
driver: {
firstname: 'john',
lastname: 'doe',
//...
},
passengers: [
{
firstname: 'jane',
lastname: 'doe',
//...
},
//... More passengers
],
damage: {
//...
}
},
{
id: 2,
//... year, vin, etc
driver: {
firstname: 'none',
//...
}, passengers: [],
damage: {
//...
}
},
],
incident: {
date: 'thedate',
time: '...',
parked: true,
}
}
The rule might be "if incident.parked is true, then at least one vehicle's driver must have firstname='none' and also have at least one element in its damage section"
For the last part(about the driver firstname and the damage section - I was thinking of using deep properties like so:
{
properties: {
vehicles: { allOf : {
deepProperties: {"/driver/firstname" : {const: 'unknown'}}, },
deepProperties: {"1/damage" : // Needs at least one element...
}
}...
}
The last snippet is equivalent to:
{
properties: {
vehicles: {
deepProperties: {
"/driver/firstname" : {const: 'unknown'},
"1/damage" : // I assume it should not be relative in this case as well
}
}
}
}