#javascript #typescript #ajv
#javascript #typescript #ajv
Вопрос:
Я искал примеры использования if-then-else
в схемах AJV, но не нашел конкретного случая, когда тип свойства и требуемый список изменяются на основе значения другого свойства.
Случай:
Мне нужно обновить, userSchema
чтобы свойство if role
= superuser
, то customer_id
было одновременно обнуляемым и необязательным.
const userSchema: Schema<UserItem> = {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
required: ['id', 'email', 'customer_id'],
additionalProperties: false,
properties: {
id: {
type: 'string',
format: 'uuid'
},
email: {
type: 'string',
format: 'email'
},
customer_id: {
type: 'string',
format: 'uuid'
},
role: {
anyOf: [
{ type: 'null' },
{ enum: Object.values(UserRole) }
]
}
}
}
Я пытался…
const userSchemaNullableCustomerId: Schema<UserItem> = {
...userSchema,
if: {
properties: {
role: { const: UserRole.Superuser }
}
},
then: {
properties: {
customer_id: {
anyOf: [
{ type: 'null' },
{ type: 'string', format: 'uuid' }
]
}
},
not: {
required: ['customer_id']
}
}
}
но он все еще жалуется на это data.customer_id should be string
. Как это можно решить?
Следующее должно быть правдой:
// Valid
{
"id": "id",
"email": "foo@bar.com",
"role": "superuser",
"customer_id": null
},
{
"id": "id",
"email": "foo@bar.com",
"role": "superuser"
},
{
"id": "id",
"email": "foo@bar.com",
"role": "null",
"customer_id": 'some-uuid...'
},
{
"id": "id",
"email": "foo@bar.com",
"role": "user",
"customer_id": 'some-uuid...'
}
// Invalid
{
"id": "id",
"email": "foo@bar.com",
"role": "user",
"customer_id": null
},
{
"id": "id",
"email": "foo@bar.com",
"role": "user"
},
{
"id": "id",
"email": "foo@bar.com",
"role": "superuser",
"customer_id": 'nonUuidString'
}
Ответ №1:
После долгих экспериментов я обнаружил, что хитрость заключается в том, что customer_id
свойство должно быть инициализировано как пустое, а role
свойство требует проверки зависимости.
...
properties: {
id: {
type: 'string',
format: 'uuid'
},
email: {
type: 'string',
format: 'email'
}
customer_id: {},
role: {
anyOf: [
{ type: 'null' },
{ enum: Object.values(UserRole) }
]
}
},
if: {
dependencies: { role: ['role'] },
properties: { role: { const: UserRole.Superuser } }
},
then: {
properties: { customer_id: { anyOf: [{ type: 'null' }, { type: 'string', format: 'uuid' }] } }
},
else: {
properties: { customer_id: { type: 'string', format: 'uuid' } }
}