Reputation: 57271
I am using Node's AJV (which enforces JSON Schema).
I want to validate array1 properties.bars
. Easy enough.
Then I want to ensure that an item in array2 properties.keep
is in array1 properties.bars
.
How do I do this?
I've got:
const config = require('../../../config')
const VALID_BARS = Object.keys(config.LHS_RHS_LOOKUP)
const schemaItems = {
id: 'schemaItems',
type: 'string',
anyOf: [
{ enum: VALID_BARS },
{ pattern: '^[^\\s]+ [^\\s]+$' }
]
}
const schemaOptions = {
type: 'object',
properties: {
bars: {
type: 'array',
default: [VALID_BARS[0]],
items: schemaItems,
minItems: 1,
uniqueItems: true
},
keep: {
type: 'array',
default: [],
items: schemaItems, // << THIS NEEDS TO CHANGE
minItems: 0,
uniqueItems: true
},
protect: {
default: true,
type: 'boolean'
}
}
}
module.exports = schemaOptions
Upvotes: 2
Views: 1758
Reputation: 993
You would want to use a $data pointer to the first array. Right now it's just a proposal. It allows you to assign a value to a keyword using the data value of another property.
So in this case the items property of your second array will have an enum property that will use the $data value of the first array.
In order to do this I had to remove the 'anyOf' in your original schema so that the first array wouldn't end up referring to itself. I also combined the schemaItems into the main schema via a $ref and definition.
Here's a PLNKR of it in action.
The test code would look something like:
let schema = {
definitions: {
schemaItems: {
id: 'schemaItems',
type: 'string',
pattern: '^[^\\s]+ [^\\s]+$'
}
},
type: 'object',
properties: {
bars: {
type: 'array',
items: {
$ref: "#/definitions/schemaItems"
},
minItems: 1,
uniqueItems: true
},
keep: {
type: 'array',
items: {
type: 'string',
enum: {
"$data": "/bars"
}
},
minItems: 0,
uniqueItems: true
},
protect: {
default: true,
type: 'boolean'
}
}
};
And a valid data sample would be:
let data = {
bars: [
"d d",
"b b"
],
keep: [
"d d"
],
protect: true
};
Upvotes: 3