缺失引用错误:无法从该ID解析引用
我在尝试使用Ajv库来验证我的数据。我在JSON Schema中指定了多种类型:SetUserAccountDataPayload、UpdateUserAccountDataPayload、RemoveUserAccountDataPayload,以此类推。
我想实现的是能够像下面这样访问这些类型定义:
schema.definitions.SetUserAccountDataPayload
不过,我遇到了一个错误:
Uncaught MissingRefError: can't resolve reference #/definitions/UserAccountData from id #
import Ajv from 'ajv';
import schema from 'app/features/cross-platform-bridge/types/cross-platform-bridge.types.json';
const ajv = new Ajv();
const validate1 = ajv.compile<SetUserAccountDataPayload>(schema.definitions.SetUserAccountDataPayload);
const validate2 = ajv.compile<UpdateUserAccountDataPayload>(schema.definitions.UpdateUserAccountDataPayload);
const validate3 = ajv.compile<RemoveUserAccountDataPayload>(schema.definitions.RemoveUserAccountDataPayload);
架构:
{
"$ref": "#/definitions/SchemaRoot",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AtLeastOne<UserAccountData>": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"userId"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"sessionStatus"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"kycState"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"firstTimeDeposited"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"lastDepositedAt"
],
"type": "object"
}
]
},
"RemoveUserAccountDataPayload": {
"additionalProperties": false,
"properties": {
"data": {
"type": "null"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"data",
"type",
"version"
],
"type": "object"
},
"SchemaRoot": {
"additionalProperties": false,
"properties": {
"removeUserAccountDataPayload": {
"$ref": "#/definitions/RemoveUserAccountDataPayload"
},
"setUserAccountDataPayload": {
"$ref": "#/definitions/SetUserAccountDataPayload"
},
"updateUserAccountDataPayload": {
"$ref": "#/definitions/UpdateUserAccountDataPayload"
}
},
"required": [
"setUserAccountDataPayload",
"updateUserAccountDataPayload",
"removeUserAccountDataPayload"
],
"type": "object"
},
"SessionStatus": {
"enum": [
"FAILED",
"RESTRICTED",
"SUCCESSFUL",
"null"
],
"type": "string"
},
"SetUserAccountDataPayload": {
"additionalProperties": false,
"properties": {
"data": {
"$ref": "#/definitions/UserAccountData"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"data",
"type",
"version"
],
"type": "object"
},
"UpdateUserAccountDataPayload": {
"additionalProperties": false,
"properties": {
"data": {
"$ref": "#/definitions/AtLeastOne%3CUserAccountData%3E"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"data",
"type",
"version"
],
"type": "object"
},
"UserAccountData": {
"additionalProperties": false,
"properties": {
"firstTimeDeposited": {
"type": "boolean"
},
"kycState": {
"$ref": "#/definitions/VerificationStatus"
},
"lastDepositedAt": {
"type": "string"
},
"sessionStatus": {
"$ref": "#/definitions/SessionStatus"
},
"userId": {
"type": "string"
}
},
"required": [
"userId",
"sessionStatus",
"kycState",
"firstTimeDeposited",
"lastDepositedAt"
],
"type": "object"
},
"VerificationStatus": {
"enum": [
"EXPIRED",
"PENDING",
"TEMPORARY",
"UNVERIFIED",
"VERIFIED"
],
"type": "string"
}
}
}
有什么线索吗?我还没法让它工作。
解决方案
本回答将聚焦于 schema.definitions.SetUserAccountDataPayload,但对于你的每个示例,原理都是一样的。
schema.definitions.SetUserAccountDataPayload 就是这个对象:
{
"additionalProperties": false,
"properties": {
"data": {
"$ref": "#/definitions/UserAccountData"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
}
},
"required": [
"data",
"type",
"version"
],
"type": "object"
}
所以当你调用 ajv.compile(schema.definitions.SetUserAccountDataPayload) 时,等同于执行以下操作:
ajv.compile({
additionalProperties: false,
properties: {
data: {
$ref: '#/definitions/UserAccountData',
},
type: {
type: 'string',
},
version: {
type: 'string',
},
},
required: ['data', 'type', 'version'],
type: 'object',
});
但是 #/definitions/UserAccountData 在该对象中无法解析——里面甚至没有一个 definitions 属性。
相反,你可以把整个 schema 编译,然后使用 getSchema 提取你想要的特定子模式的验证器:
const ajv = new Ajv();
ajv.compile(schema); // or do this during construction: `new Ajv({ schemas: [schema] })`
const validate = ajv.getSchema<SetUserAccountDataPayload>(
'#/definitions/SetUserAccountDataPayload',
);
或者,你也可以把 cross-platform-bridge.types.json 拆分成多个模式。有关更多信息,请参阅Ajv的“组合模式”指南:Ajv的“组合模式”指南。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。