使用 Joi,如何将 .or 用于递归对象

Using Joi, how to use .or for recursive objects

我正在使用节点模块 Joi 进行一些验证,但在使用 .or() 方法时遇到问题。

在他们的文档中,他们将用法指定为:

var schema = Joi.object().keys({
    a: Joi.any(),
    b: Joi.any()
}).or('a', 'b');

但是我正在尝试验证一个对象,我想使用 .or() 来检查嵌套在不同属性下的属性,明白了吗?类似于:

var schema = Joi.object().keys({
  body:{
    device:{
      smthelse: Joi.any(),
      ua: Joi.string()
    }
  },
  headers:{
    'user-agent': Joi.string()      
}).or('body.device.ua', 'headers.user-agent');

但我似乎无法让它发挥作用。有谁知道我是否遗漏了什么?是嵌套对象的用户 .or() 的方式吗?

谢谢!

嵌套对象也需要是 Joi 模式;

var schema = Joi.object().keys({
  body: Joi.object().keys({
    device: Joi.object().keys({
      smthelse: Joi.any(),
      ua: Joi.string()
    }
  }),
  headers:  Joi.object().keys({
    'user-agent': Joi.string()      
  })
}).or('body.device.ua', 'headers.user-agent');

感谢 Bulkan 的回答,但实际上并没有用。我在 hapijs github 的问题部分发布了同样的问题并得到了解决方案,这是它(由 DavidTPate 发布):

The way you are doing it doesn't appear possible to me since it doesn't look like object.or() at that top level supports referencing nested items. You could do it with alternatives though.

You should be able to do

var bodySchema = Joi.object().keys({
  body: Joi.object().keys({
    device: Joi.object().keys({
      ua: Joi.string().required()
    }).required();
  }).required();
}).required();
var headerSchema = Joi.object().keys({
  headers: Joi.object().keys({
    'user-agent': Joi.string().required()
  }).required()
}).required();
var schema = Joi.alternatives().try(bodySchema, headerSchema); 

这里是 link 了解更多信息:https://github.com/hapijs/joi/issues/643