Сообщение об ошибке альтернативной схемы валидатора Joi - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь создать схему Joi, используя Joi.alternatives.try () . Это схема, которую я пробовал.

Joi.alternatives().try(Joi.object({
    type: Joi.number().required().label('Error1!!')
}), Joi.object({
    reason: Joi.string().required().label('Error2!!')
})).label('Error!!')

Это объект, который я использовал.

{ reason: 2 }

Я ожидал ошибку как Error2!! или что-то, содержащее эту строку Error2!!. Но я получаю ошибку как

Validation Error: "Error!!" does not match any of the allowed types

Эта ошибка исходит от родительского узла.

Как я могу сделать ошибку, указав c для объекта? То есть ошибка, исходящая из узла альтернативного объекта, а не из родительского объекта.

Вы можете использовать эту платформу для проверки схемы в сети.

Обновление: Вот пример схемы, которую я использовал.

employee_retired = Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    personaldetails: Joi.alternatives().conditional('type', {
        is: 2, then: Joi.array().items(Joi.object({
            address: Joi.string().required()
                .min(1)
                .max(100),
            salary: Joi.string().required()
                .min(0)
                .max(500),
            contactnumbers: Joi.array().items(Joi.object({
                mobile: Joi.string().required()
                    .min(0)
                    .max(15),
                home: Joi.string()
                    .required()
                    .min(1)
                    .max(15),
            })).max(50).required(),
        }).required()).max(50).required(),
        otherwise: Joi.forbidden(),
    }),
    monthlysavings: Joi.alternatives().conditional('type', {
            is: 3,
            then: Joi.number()
                .required()
                .min(0)
                .max(50000),
            otherwise: Joi.forbidden(),
        }),
    isapproved: Joi.boolean().required(),
});

empolyee_working = Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    contactnumbers: Joi.array().items(Joi.object({
        mobile: Joi.string().required()
            .min(0)
            .max(15),
        home: Joi.string()
            .required()
            .min(1)
            .max(15),
    })).max(50).required(),
    monthlysavings: Joi.alternatives().conditional('type', {
        is: 3,
        then: Joi.number().required()
            .min(1)
            .max(50000),
        otherwise: Joi.forbidden(),
    }),
    isapproved: Joi.boolean().required(),
})

const employee = Joi.alternatives().try(employee_retired, empolyee_working);

1 Ответ

2 голосов
/ 28 апреля 2020

Вы можете использовать object.or для этого поведения:

Joi.object({
    type: Joi.number().label('Error1!!'),
    reason: Joi.string().label('Error2!!')
}).or('type', 'reason').label('Error!!')

Тесты:

{}
// Validation Error: "Error!!" must contain at least one of [Error1!!, Error2!!]
{ reason: 2 }
// Validation Error: "Error2!!" must be a string
{ type: "a" } // note that due to default `convert` behavior, `{ type: "2" }` would pass
// Validation Error: "Error1!!" must be a number
{ a: "b" }
// Validation Error: "a" is not allowed. "Error!!" must contain at least one of [Error1!!, Error2!!]

ОБНОВЛЕНИЕ (после комментария)

На самом деле это немного более многословно, но следует той же логике c:

  • оба пенсионеры и работающие сотрудники имеют одинаковую структуру
  • только personaldetails и contactnumbers варьируются

Таким образом, что-то в следующих строках должно предоставить вам точное сообщение об ошибке проверки (хотя я не проверял все случаи). Я просто «объединил» обе декларации сотрудника, и два разных случая personaldetails и contactnumbers больше не объявляются required, но указаны в окончательном or.

Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    personaldetails: Joi.alternatives().conditional('type', {
        is: 2, then: Joi.array().items(Joi.object({
            address: Joi.string().required()
                .min(1)
                .max(100),
            salary: Joi.string().required()
                .min(0)
                .max(500),
            contactnumbers: Joi.array().items(Joi.object({
                mobile: Joi.string().required()
                    .min(0)
                    .max(15),
                home: Joi.string()
                    .required()
                    .min(1)
                    .max(15),
            })).max(50).required(),
        // N.B.: no more .required() on the next line, .or() will handle it conditionally
        }).required()).max(50),
        otherwise: Joi.forbidden(),
    }),
    contactnumbers: Joi.array().items(Joi.object({
        mobile: Joi.string().required()
            .min(0)
            .max(15),
        home: Joi.string()
            .required()
            .min(1)
            .max(15),
    // N.B.: no more .required() on the next line, .or() will handle it conditionally
    })).max(50),
    monthlysavings: Joi.alternatives().conditional('type', {
            is: 3,
            then: Joi.number()
                .required()
                .min(0)
                .max(50000),
            otherwise: Joi.forbidden(),
        }),
    isapproved: Joi.boolean().required(),
}).or('personaldetails', 'contactnumbers').label('OR failure')
...