[英]Validate Joi - all array elements have the same nested value
我想使用 Joi 來驗證傳入的 JSON 請求對象,以便每個數組元素在路徑.runs[].results.type
處具有相同的值。 如果有一個元素突出,則驗證應該失敗。 類似於.runs[]
內的array.unique
上的.results.type
.runs[]
。
將以下 JSON 想象為有效輸入:
{
runs: [
{ results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } },
{ results: { type: 'A', side: 'right' }, meta: { createdBy: 1 } }
]
}
這應該會引發驗證錯誤:
{
runs: [
{ results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } },
{ results: { type: 'B', side: 'right' }, meta: { createdBy: 1 } }
]
}
我嘗試編寫一個 Joi 模式,如:
...
runs: Joi.array()
.min(1)
.items(
Joi.object()
.unknown()
.keys({
results: Joi.object()
.keys({
type: Joi.string()
.allow('A', 'B', 'C', 'D')
.valid(Joi.ref('....', { in: true, adjust: runs => runs.map(run => run.results.type) }))
.required(),
side: Joi.string().allow('left', 'right')
})
})
)
...
但這不起作用(我認為它以循環引用結束)。 此外,即使它成功運行,我也不確定它是否會在提供兩種差異類型A
和B
情況下破壞驗證。
我想我找到了一種不使用自定義函數的優雅解決方案,盡管這將是解決這個問題的一個很好的方法!
Joi.object().keys({
runs: Joi.array().items(
Joi.object().keys({
results: Joi.object().keys({
type: Joi.string().valid(
Joi.ref('....0.results.type')
).required()
})
})
).has(
Joi.object().keys({
results: Joi.object().keys({
type: Joi.valid('A', 'B', 'C', 'D').required()
})
}))
})
它基於首先確定所有runs[]
元素具有相同的.results.type
值,然后斷言runs
數組.has()
至少一個元素具有來自{'A', 'B', 'C', 'D'}
.results.type
{'A', 'B', 'C', 'D'}
。
我學到的有趣的事情是,在 Joi 中,數組元素在.ref()
中用點索引,例如$runs.0.results
。
您需要使用.some()
o .every()
函數,如果至少有某個元素完成某個條件,或者每個元素都完成一個條件,則該函數返回:
1)使用.some()
:
const object1 = { runs: [ { results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } }, { results: { type: 'A', side: 'right' }, meta: { createdBy: 1 } } ]}; const object2 = { runs: [ { results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } }, { results: { type: 'B', side: 'right' }, meta: { createdBy: 1 } } ]}; let result1 = object1.runs.some(e => e.results.type !== 'A'); console.log(result1); // false let result2 = object2.runs.some(e => e.results.type !== 'A'); console.log(result2); // true
2)使用.every()
:
const object1 = { runs: [ { results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } }, { results: { type: 'A', side: 'right' }, meta: { createdBy: 1 } } ]}; const object2 = { runs: [ { results: { type: 'A', side: 'left' }, meta: { createdBy: 3 } }, { results: { type: 'B', side: 'right' }, meta: { createdBy: 1 } } ]}; let result1 = object1.runs.every(e => e.results.type === 'A'); console.log(result1); // true let result2 = object2.runs.every(e => e.results.type === 'A'); console.log(result2); // false
runs[0].results.type
並用它替換 'A' 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.