Joi arr 条件长度

问题描述

用户将作为一组对象发送联系信息,如下所示,电话号码是可选的,电子邮件是必需的:

{
  "contact": [{
    "type": "phone","value": "555-555-5555"
  },{
    "type": "email","value": "test@test.com"
  }]
}

我想确保数组中有一个电子邮件对象。我尝试了这样的 Joi 验证:

contact: Joi.array().items(Joi.object().keys({
      type: Joi.string().valid('phone','email'),value: Joi.string()
        .when('contact.type',{ is: 'phone',then: Joi.string() })
        .when('contact.type',{ is: 'email',then: Joi.string().email().required() })
    }))
      .when('contact.type',then: Joi.array().min(2).required() }),

但我收到以下错误

Error: Item cannot come after itself: contact

它似乎不喜欢我以这种方式给它一个长度,但我想不出任何其他方法来做到这一点。任何帮助,将不胜感激。谢谢。

解决方法

这个结合了 .when.has.unique 的架构应该可以工作:

Joi.object({
  contact: Joi.array().items(
    Joi.object().keys({
      type: Joi.string().valid('phone','email').required(),value: Joi.string().when('type',{ is: 'email',then: Joi.required() })
    }).required(),)
  .has(Joi.object({ type: 'email',value: Joi.exist() }))
  .unique('type').min(1).max(2)
})

让我们看看规则:

  1. 必须存在类型为“email”的对象;

这就是我添加的原因

.has(Joi.object({ type: 'email',value: Joi.exist() }))

这意味着数组必须至少具有这些元素之一。

  1. 我们不想重复,对吧?
.unique('type').min(1).max(2)

数组将有 1 个或 2 个元素,具有不同的类型。

  1. 当类型为“email”时,该值应该是必需的,否则是可选的。这就是我们在这里所说的:
value: Joi.string().when('type',then: Joi.required() })
,

感谢@soltex 的回答。

首先,我不确定我们是否应该排除重复项。有些人有多个电话号码。

其次,您的回答不太奏效。这是我根据您写的内容更新的答案:

contact: Joi.array().items(Joi.object().keys({
      type: Joi.string().valid('phone',value: Joi.string().required(),}))
    .has(Joi.object({ type: 'email',value: Joi.string().email() }))

一旦我包含了 .has 方法,就没有理由包含 .when 方法。我还希望电子邮件是有效的电子邮件,而不仅仅是它存在。我将值更改为 required 因为如果用户发送类型电话我仍然希望他们包含该值。

再次感谢您的指导。