Joi 在架构定义中嵌套“when”条件失败,出现“ERR_ASSERTION”错误
Joi nested `when` conditions failed in schema definition with `ERR_ASSERTION ` error
我一直在尝试使用 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({})
});
所以schema的条件如下:
- 在
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 fiddle here 如果您能告诉我哪里做错了,我们将不胜感激。
多亏了找到的 REPL here。我了解了如何根据同级 属性 值定义嵌套模式。您可以简单地为对象提供 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({})
});
我一直在尝试使用 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({})
});
所以schema的条件如下:
- 在
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 fiddle here 如果您能告诉我哪里做错了,我们将不胜感激。
多亏了找到的 REPL here。我了解了如何根据同级 属性 值定义嵌套模式。您可以简单地为对象提供 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({})
});