【问题标题】:Require 2 properties if one is present unless they are nested under a specific property如果存在一个属性,则需要 2 个属性,除非它们嵌套在特定属性下
【发布时间】:2022-10-01 10:54:02
【问题描述】:

我有这个 joi 模式,它要求如果你传入id,你还必须传入type

joi
    .object()
    .required()
    .keys({
        id: joi.string(),
        type: joi.string(),

        expirationTime: dateSchema,
        createdBy: joi.string().uuid(),
        createdAt: dateSchema,

        // Allow \"or\" to recursively reference this entire schema.
        // https://hapi.dev/module/joi/api/?v=17.1.1#linkref
        or: joi.array().items(joi.link(\'/\')).min(2),

        // Allow \"and\" to recursively reference this entire schema.
        // https://hapi.dev/module/joi/api/?v=17.1.1#linkref
        and: joi.array().items(joi.link(\'/\')).min(2)
    });
    .with(\'id\', \'type\'); // If searching for id you must also search by type

我想这样如果你传入id,你也必须传入type,除非它嵌套在and下。

例如这应该失败,因为它没有id AND type

{
  id: \'foo\',
}

但这应该会通过,因为它在根级别确实有idtype,并且只有id 嵌套在and 下。

{
  id: \'foo\',
  type: \'bar\',
  and: [{ id: \'foobar\' }, { createdBy: \'me\' }]
}
  • or/and \"children\" 看起来像一个不同的模式,有一些共享的组件。他们是否打算支持或/和递归?
  • 是的,它旨在支持和/或递归。唯一的区别是当嵌套在andor 下时,id 也不需要type

标签: node.js joi


【解决方案1】:

or/and“孩子”是不同的模式。

您可以为公共元素定义 base 架构

const base = Joi.object()
    .keys({
        id: Joi.string(),
        type: Joi.string(),
        expirationTime: dateSchema,
        createdBy: Joi.string().uuid(),
        createdAt: dateSchema,
        or: Joi.array().items(Joi.link('#base')).min(2),
        and: Joi.array().items(Joi.link('#base')).min(2),
    })
    .id('base')

然后创建带有添加的“head”模式,并允许它仍然引用#base

const head = base
    .keys({
         id: Joi.string()
    })
    .required()
    .with('id', 'type')
    .id('head')
    .shared(base)

.keys() 扩展有点笨拙,因为 null/undefined/{} 在 Joi 中具有特殊含义以更改验证行为,因此我必须选择一个键来重新定义以使其“扩展”。

【讨论】:

    猜你喜欢
    • 2022-07-27
    • 1970-01-01
    • 2018-06-09
    • 2015-08-10
    • 2012-03-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多