简体   繁体   中英

Require 2 properties if one is present unless they are nested under a specific property

I have this joi schema which requires that if you pass in id , you must also pass in 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

I want to make it so that if you pass in id , you must also pass in type , unless it is nested under and .

For example this should fail because it does not have id AND type

{
  id: 'foo',
}

But this should pass because it does have id AND type at the root level AND only id when nested under and .

{
  id: 'foo',
  type: 'bar',
  and: [{ id: 'foobar' }, { createdBy: 'me' }]
}

The or / and "children" are a different schema.

You could define a base schema for the common elements

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')

Then create the "head" schema with the additions, and allowing it to still reference #base

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

The .keys() extension is a bit clunky as null/undefined/{} have special meaning in Joi to change validation behaviour, so I had to pick a key to redefine to make it "extend".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM