Skip to content

Commit aef1674

Browse files
refactor: compare schemas with same schema id
1 parent de7f3e2 commit aef1674

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@fastify/deepmerge": "^1.0.0",
5353
"ajv": "^8.10.0",
5454
"ajv-formats": "^2.1.1",
55+
"fast-deep-equal": "^3.1.3",
5556
"fast-uri": "^2.1.0",
5657
"rfdc": "^1.2.0"
5758
},

ref-resolver.js

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,67 @@
11
'use strict'
22

3+
const deepEqual = require('fast-deep-equal')
4+
35
class RefResolver {
46
constructor () {
5-
this.refs = {}
7+
this.schemas = {}
68
}
79

810
addSchema (schema, schemaKey) {
9-
if (schema === null) return
10-
1111
if (schema.$id !== undefined && schema.$id.charAt(0) !== '#') {
1212
schemaKey = schema.$id
1313
}
14-
15-
this.refs[schemaKey] = { schema, anchors: {} }
16-
this.resolveSchema(schema, schemaKey, '')
14+
this.insertSchemaBySchemaId(schema, schemaKey)
15+
this.insertSchemaSubschemas(schema, schemaKey)
1716
}
1817

1918
getSchema (schemaReference) {
2019
const [schemaKey, jsonPointer] = schemaReference.split('#')
21-
const schema = this.refs[schemaKey]
22-
20+
const schema = this.schemas[schemaKey]
2321
if (schema === undefined) {
2422
return undefined
2523
}
24+
if (schema.anchors[jsonPointer] !== undefined) {
25+
return schema.anchors[jsonPointer]
26+
}
27+
return getDataByJSONPointer(schema.schema, jsonPointer)
28+
}
29+
30+
insertSchemaBySchemaId (schema, schemaId) {
31+
if (
32+
this.schemas[schemaId] !== undefined &&
33+
!deepEqual(schema, this.schemas[schemaId].schema)
34+
) {
35+
throw new Error(`There is already another schema with id ${schemaId}`)
36+
}
37+
this.schemas[schemaId] = { schema, anchors: {} }
38+
}
2639

27-
return schema.anchors[jsonPointer] || getDataByJSONPointer(schema.schema, jsonPointer)
40+
insertSchemaByAnchor (schema, schemaId, anchor) {
41+
const { anchors } = this.schemas[schemaId]
42+
if (
43+
anchors[anchor] !== undefined &&
44+
!deepEqual(schema, anchors[anchor])
45+
) {
46+
throw new Error(`There is already another schema with id ${schemaId}#${anchor}`)
47+
}
48+
anchors[anchor] = schema
2849
}
2950

30-
resolveSchema (schema, schemaKey, jsonPointer) {
51+
insertSchemaSubschemas (schema, rootSchemaId) {
3152
const schemaId = schema.$id
3253
if (schemaId !== undefined && typeof schemaId === 'string') {
3354
if (schemaId.charAt(0) === '#') {
34-
this.refs[schemaKey].anchors[schemaId.slice(1)] = schema
55+
const anchor = schemaId.slice(1)
56+
this.insertSchemaByAnchor(schema, rootSchemaId, anchor)
3557
} else {
36-
this.refs[schemaId] = { schema, anchors: {} }
58+
this.insertSchemaBySchemaId(schema, schemaId)
3759
}
3860
}
3961

4062
for (const key in schema) {
4163
if (typeof schema[key] === 'object' && schema[key] !== null) {
42-
this.resolveSchema(schema[key], schemaKey, jsonPointer + '/' + key)
64+
this.insertSchemaSubschemas(schema[key], rootSchemaId)
4365
}
4466
}
4567
}
@@ -48,15 +70,9 @@ class RefResolver {
4870
function getDataByJSONPointer (data, jsonPointer) {
4971
const parts = jsonPointer.split('/')
5072
let current = data
51-
for (let i = 0; i < parts.length; i++) {
52-
const part = parts[i]
53-
if (part === '') {
54-
continue
55-
}
56-
if (part.charAt(0) === '#') {
57-
continue
58-
}
59-
if (current[part] === undefined) {
73+
for (const part of parts) {
74+
if (part === '') continue
75+
if (typeof current !== 'object' || current === null) {
6076
return undefined
6177
}
6278
current = current[part]

0 commit comments

Comments
 (0)