Joi.js - 如何要求至少一个布尔字段为真?

Joi.js - how to require at least one boolean field to be true?

提问人:Kimball Robinson 提问时间:10/26/2023 最后编辑:Kimball Robinson 更新时间:11/1/2023 访问量:27

问:

我有一个 Joi 架构,我想要一个条件验证。对于对象,我有字段和 。必须至少有一个存在 和 ,但两者都不需要单独存在。exampleabtrue

这是我希望完成的伪代码,但我无法弄清楚。

const example = Joi.object({
   a: Joi.boolean().optional().when('b', { is: /* null, missing, or false */, then: Joi.valid(true).required()}
   b: Joi.boolean().optional().when('a', { is: /* null, missing, or false */, then: Joi.valid(true).required()}
})

这是一个遗留的 API - 我正在添加验证,并且没有灵活性来制定更简单、更灵活的规则,这些规则适用于 Joi 使(对我来说)变得容易的东西。

我可以选择使用 jsonschema - 但我目前不愿意这样做,因为我已经使用 Joi 构建了其他验证,这会花费我相当多的时间。我想我可以在那里使用部分模式。耸肩。

测试:

schema.validate({ example: { a: false, b: false}}) // must fail
schema.validate({ example: { b: false}}) // must fail
schema.validate({ example: { a: false}}) // must fail
schema.validate({ example: { }}) // must fail
schema.validate({ example: { a: null, b: null }}) // must fail

schema.validate({ example: { a: true, b: null }}) // must PASS
schema.validate({ example: { a: null, b: true }}) // must PASS
schema.validate({ example: { a: true }}) // must PASS
schema.validate({ example: { b: true }}) // must PASS
JavaScript 节点.js JOI

评论


答:

0赞 Kimball Robinson 10/26/2023 #1

挣扎了好一会儿,我想出了这个:

    b: Joi.boolean().optional(),
    a: Joi.boolean().when('b', { is: Joi.equal(null, false), then: Joi.valid(true).required() })
      .messages({
        'any.required': 'one or both of example.a or example.b must equal === true',
        'any.only': 'one or both of example.a or example.b must equal === true',
      })

它通过了我所有的测试。

[编辑]

我把它拉出来了一个功能......

const oneMustBePresentAndTrue = (firstProperty, secondProperty) => {
  const container = {}
  container[firstProperty] = Joi.boolean().optional()
  const errorMessage = `one or both of {{#label}} or {..number.key}.${firstProperty} must equal === true`
  container[secondProperty] = Joi.boolean().when(firstProperty, {
    is: Joi.equal(null, false),
    then: Joi.valid(true).required()
  }).messages({
    'any.required': errorMessage,
    'any.only': errorMessage
  })
  return container
}