如何验证值之间的关系

How to validate relationship between values

提问人:Avram 提问时间:11/2/2023 最后编辑:Mark RotteveelAvram 更新时间:11/21/2023 访问量:21

问:

我有一个案例,用户输入应该有几种不同的方式能够通过验证:

// greatly simplified
Joi.object({
  v4Type: Joi.string().valid('DHCP', 'Static'),
  v6Type: Joi.string().valid('DHCP', 'Static'),
  v4Addr: Joi.string().ip({version: 'ipv4'}),
  v6Addr: Joi.string().ip({version: 'ipv6'}),
})

用户需要至少配置一个地址系列,但我们不关心是哪一个。唯一需要拒绝的通过上述架构的配置是:

{ v4Type: Static, v6Type: Static } // both addrs are missing

他们需要至少有一个地址。它可以用于任何一个系列,它可以是静态的,也可以是动态的 - 但如果它是静态的,则必须提供。在伪代码中:

function isValid(...) {
  if ([v4Type, v6Type].include('DHCP')) return true;
  if (v4Addr || v6Addr) return true;
  return false;
}

我在这里和其他地方跟踪了十几个线程,但还没有找到一个可以让我在决定通过/失败之前同时考虑多个键的值。我也找不到一种方法,根据一个键的值对其他键施加一对“or'd”约束。我已经研究了和链接的选项,但都有相同的问题。switch:when()when()

这里有两个伪代码 Joi schemata 可以工作,但我不知道如何表达真实:

Joi.object({
  a1: Joi.string().valid('ok', 'need more').
      when({ is: 'need more', then: Joi.object({a2: DHCP}).or(b1: Joi.required()),
  a2: Joi.string().valid('ok', 'need more').
      when({ is: 'need more', then: Joi.object({a1: DHCP}).or(b2: Joi.required()),
  b1: Joi.string(),
  b2: Joi.string(),
})

Joi.object({
  a1: Joi.string().valid('ok', 'need more'),
  a2: Joi.string().valid('ok', 'need more'),
  b1: Joi.string(),
  b2: Joi.string(),
}).when({ is: a1 == 'need more' && a2 == 'need more', then: Joi.keys('b1').or('b2')})
乔伊

评论


答:

0赞 Kamran 11/21/2023 #1

v4Type 或 v6Type 中的任何一个都是必需的,如果 v4Type 或 v6Type 是“DHCP”,则 v4Addr 和 v6Addr 是可选的,如果是“静态”,则各自将是必需的。

Joi.object({
    v4Type: Joi.string().allow('DHCP','Static'),
    v6Type: Joi.string().allow('DHCP','Static'),
    v4Addr: Joi.string().regex(/^(\d{1,3}\.){3}\d{1,3}$/).when('v4Type', { is: 'Static', then: Joi.string().required(), otherwise: Joi.string().optional() }),
    v6Addr: Joi.string().regex(/^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i).when('v6Type', { is: 'Static', then: Joi.string().required(), otherwise: Joi.string().optional() }),
}).or("v4Type", "v6Type")

评论

0赞 Avram 11/22/2023
非常感谢您提供解决方案。我不确定这是否符合我们的要求:当两种类型都是 时,只需要一个地址 - 而不是两个。我们不会强迫用户在两个家庭中都有一个地址,只有一个。看起来您正在通过键入类型来实现这一目标 - 您是否建议通过省略其类型来表示一个系列中没有地址?我们希望默认类型是 DHCP,这样就会强制使用我们不需要的地址。我还注意到你从我的使用切换到 - 这有什么特别的原因吗?Staticorip()regex