#node.js #joi
#node.js #joi
Вопрос:
Я пытался работать с Joi (старая версия 14.3.1) для создания схемы, и, к сожалению, я застрял. Я пробовал несколько способов определения схем, но результаты всегда приходят с ошибкой в определении схемы.
Вот мое определение схемы:
const allowedUser = {
admin: 'ADMIN',
normal: 'NORMAL'
};
const schema = validator
.object()
.keys({
user: validator.any().valid(Object.values(allowedUser)).required(),
context: validator.object().default({})
})
.when('user', {
is: allowedUser.admin,
then: validator.when(validator.object({ context: validator.exist() }), {
then: validator.object().keys({
session: validator.string().required()
})
})
})
.when('user', {
is: allowedUser.normal,
then: validator.when(validator.object({ context: validator.exist() }), {
then: validator.object().keys({
id: validator.string().required()
})
})
});
Другое определение схемы, которое я пробовал:
const schema = validator.object().keys({
user: validator.any().valid(Object.values(allowedUser)).required(),
context: validator
.object()
.when('user', {
is: allowedUser.admin,
then: validator.when('context', {
is: validator.exist(),
then: validator.object().keys({
session: validator.string().required()
})
})
})
.when('user', {
is: allowedUser.normal,
then: validator.when('context', {
is: validator.exist(),
then: validator.object().keys({
id: validator.string().required()
})
})
})
.default({})
});
Итак, условия для схемы следующие:
- В случае
user
типаADMIN
: еслиcontext
свойство определено, оно должно содержать свойствоsession
. еслиcontext
свойство не определено, оно должно установить значение по умолчанию равным{}
- В случае
user
типаNORMAL
: еслиcontext
свойство определено, оно должно содержать свойствоid
. еслиcontext
свойство не определено, оно должно установить значение по умолчанию равным{}
- Неявный случай, если
context
свойство содержит неизвестное свойство, оно также должно завершиться неудачей
Когда я запускаю код, я всегда получаю ошибку в определении схемы, которая выглядит следующим образом:
AssertionError [ERR_ASSERTION]: Cannot merge type object with another type: alternatives
Мой минимальный пример кода выглядит следующим образом:
const validator = require('joi');
const allowedUser = {
admin: 'ADMIN',
normal: 'NORMAL'
};
const bodyWhenUndefined = {
user: 'ADMIN',
message: 'Hi'
};
const bodyWhenValidDefined = {
user: 'ADMIN',
message: 'Hi'
};
const bodyWhenDefinedEmpty = {
user: 'ADMIN',
message: 'Hi 2',
context: {}
};
const bodyWhenDefinedWrong = {
user: 'admin',
message: 'Hi 3',
context: {abc: 'wrong property'}
};
const schema = validator
.object()
.keys({
user: validator.any().valid(Object.values(allowedUser)).required(),
context: validator.object().default({})
})
.when('user', {
is: allowedUser.admin,
then: validator.when(validator.object({ context: validator.exist() }), {
then: validator.object().keys({
session: validator.string().required()
})
})
})
.when('user', {
is: allowedUser.normal,
then: validator.when(validator.object({ context: validator.exist() }), {
then: validator.object().keys({
id: validator.string().required()
})
})
});
const resultSuccess = validator.validate(bodyWhenValidDefined, schema);
console.log("This is with success in validation",resultSuccess.value);
const result = validator.validate(bodyWhenUndefined, schema);
console.log("This is with default context property",result.value);
const resultWithEmptyError = validator.validate(bodyWhenDefinedEmpty, schema);
console.log("This should come with error with required property session",resultWithEmptyError.error);
const resultWithWrongProp = validator.validate(bodyWhenDefinedWrong, schema);
console.log("This should come with error with required property session",resultWithWrongProp.error);
Я создал рабочую скрипку REPL здесь, была бы признательна помощь, чтобы рассказать мне, где я делаю неправильно.
Ответ №1:
Итак, благодаря REPL, найденному здесь. Я получил представление о том, как вложенная схема может быть определена на основе значения родственного свойства. Вы можете просто предоставить then
условие объекту и определить требуемые свойства. вот рабочая схема:
const schema = validator.object().keys({
user: validator.any().valid(Object.values(allowedUser)).required(),
message: validator.string(),
context: validator
.object()
.when('user', {
is: allowedUser.admin,
then: {
session: validator.required()
}
})
.when('user', {
is: allowedUser.normal,
then: {
id: validator.required()
}
})
.default({})
});