Джой: Требовать, чтобы ровно два из трех полей были непустыми

Вот простая версия моей схемы.

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string(),
    c: Joi.string()
});

Я хочу, чтобы a, b, c были ровно 2 из 3 непустыми. То есть:

  • если a, b не пусты, c не должно быть установлено
  • то же самое с круговой перестановкой a,b,c
  • конечно, если 2 или более пустых, тоже выдать ошибку

Пробовал использовать .or(), но явно не помогает. Заглянул в .alternatives(), но не заработал.


joi
person jeanpaul62    schedule 17.01.2018    source источник


Ответы (1)


Трудно найти элегантный способ справиться с этим, не натыкаясь на проблемы циклической зависимости. Мне удалось заставить что-то работать, используя .alternatives() и .try() .

Решение в необработанном виде будет таким:

Joi.alternatives().try(
    Joi.object().keys({
        a: Joi.string().required(),
        b: Joi.string().required(),
        c: Joi.string().required().valid('')
    }),
    Joi.object().keys({
        a: Joi.string().required().valid(''),
        b: Joi.string().required(),
        c: Joi.string().required()
    }),
    Joi.object().keys({
        a: Joi.string().required(),
        b: Joi.string().required().valid(''),
        c: Joi.string().required()
    })
);

Это, конечно, не очень красиво и может сильно раздуться, если будут введены дополнительные зависимости.

В попытке уменьшить количество повторений также будет работать следующее:

var base = {
    a: Joi.string().required(),
    b: Joi.string().required(),
    c: Joi.string().required()
};

Joi.alternatives().try(
    Joi.object().keys(Object.assign({}, base,
    {
        a: base.a.valid('')
    })),
    Joi.object().keys(Object.assign({}, base,
    {
        b: base.b.valid('')
    })),
    Joi.object().keys(Object.assign({}, base,
    {
        c: base.c.valid('')
    }))
);
person Ankh    schedule 19.01.2018