Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const { dequal: deepEqual } = require('dequal')

const jsonSchemaRefSymbol = Symbol.for('json-schema-ref')

// the keywords whose value is data, not a schema: a $ref or an $id inside them is a property
// name of the instance, not a reference
const dataKeywords = new Set(['default', 'const', 'enum', 'examples'])

class RefResolver {
#schemas
#derefSchemas
Expand Down Expand Up @@ -50,6 +54,7 @@ class RefResolver {
}

for (const key in schema) {
if (dataKeywords.has(key)) continue
if (typeof schema[key] === 'object' && schema[key] !== null) {
this.addSchema(schema[key], rootSchemaId, false)
}
Expand Down Expand Up @@ -202,6 +207,7 @@ class RefResolver {
}

for (const key in derefSchema) {
if (dataKeywords.has(key)) continue
const value = derefSchema[key]
if (typeof value === 'object' && value !== null) {
derefSchema[key] = this.#addDerefSchema(value, rootSchemaId, false, refs)
Expand Down
27 changes: 27 additions & 0 deletions test/data-keywords.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict'

const assert = require('node:assert/strict')
const { test } = require('node:test')
const { RefResolver } = require('../index.js')

// a $ref inside default, const, enum or examples is a property of the instance, not a reference,
// and was collected as one: the dependencies could not be resolved and the deref walked into data
test('does not read a $ref inside a data keyword as a reference', () => {
const refResolver = new RefResolver()
const schema = {
$id: 'schemaId',
type: 'object',
properties: {
a: { type: 'object', default: { $ref: 'nowhere#/x', $id: 'nowhere' } },
b: { const: { $ref: 'nowhere' } },
c: { enum: [{ $ref: 'nowhere' }] },
d: { type: 'string', examples: [{ $ref: 'nowhere' }] }
}
}
refResolver.addSchema(schema)

assert.deepStrictEqual(refResolver.getSchemaRefs('schemaId'), [])
assert.deepStrictEqual(refResolver.getSchemaDependencies('schemaId'), {})
assert.deepStrictEqual(refResolver.getDerefSchema('schemaId'), schema)
assert.equal(refResolver.hasSchema('nowhere'), false)
})