@@ -9,6 +9,7 @@ const { randomUUID } = require('crypto')
99
1010const validate = require ( './schema-validator' )
1111const Serializer = require ( './serializer' )
12+ const RefResolver = require ( './ref-resolver' )
1213const buildAjv = require ( './ajv' )
1314
1415let largeArraySize = 2e4
@@ -57,20 +58,12 @@ function resolveRef (location, ref) {
5758 const schemaId = ref . slice ( 0 , hashIndex ) || location . schemaId
5859 const jsonPointer = ref . slice ( hashIndex ) || '#'
5960
60- const schemaRef = schemaId + jsonPointer
61+ const schema = refResolver . getSchema ( schemaId , jsonPointer )
6162
62- let ajvSchema
63- try {
64- ajvSchema = ajvInstance . getSchema ( schemaRef )
65- } catch ( error ) {
63+ if ( schema === undefined ) {
6664 throw new Error ( `Cannot find reference "${ ref } "` )
6765 }
6866
69- if ( ajvSchema === undefined ) {
70- throw new Error ( `Cannot find reference "${ ref } "` )
71- }
72-
73- const schema = ajvSchema . schema
7467 if ( schema . $ref !== undefined ) {
7568 return resolveRef ( { schema, schemaId, jsonPointer } , schema . $ref )
7669 }
@@ -83,6 +76,7 @@ const objectReferenceSerializersMap = new Map()
8376
8477let rootSchemaId = null
8578let ajvInstance = null
79+ let refResolver = null
8680let contextFunctions = null
8781
8882function build ( schema , options ) {
@@ -95,11 +89,13 @@ function build (schema, options) {
9589 options = options || { }
9690
9791 ajvInstance = buildAjv ( options . ajv )
92+ refResolver = new RefResolver ( )
9893 rootSchemaId = schema . $id || randomUUID ( )
9994
10095 isValidSchema ( schema )
10196 extendDateTimeType ( schema )
10297 ajvInstance . addSchema ( schema , rootSchemaId )
98+ refResolver . addSchema ( schema , rootSchemaId )
10399
104100 if ( options . schema ) {
105101 const externalSchemas = clone ( options . schema )
@@ -114,7 +110,14 @@ function build (schema, options) {
114110 schemaKey = key + externalSchema . $id // relative URI
115111 }
116112
117- if ( ajvInstance . getSchema ( schemaKey ) === undefined ) {
113+ if ( refResolver . getSchema ( schemaKey ) === undefined ) {
114+ refResolver . addSchema ( externalSchema , key )
115+ }
116+
117+ if (
118+ ajvInstance . refs [ schemaKey ] === undefined &&
119+ ajvInstance . schemas [ schemaKey ] === undefined
120+ ) {
118121 ajvInstance . addSchema ( externalSchema , schemaKey )
119122 }
120123 }
@@ -178,6 +181,7 @@ function build (schema, options) {
178181 const stringifyFunc = contextFunc ( ajvInstance , serializer )
179182
180183 ajvInstance = null
184+ refResolver = null
181185 rootSchemaId = null
182186 contextFunctions = null
183187 arrayItemsReferenceSerializersMap . clear ( )
@@ -494,6 +498,7 @@ function mergeAllOfSchema (location, schema, mergedSchema) {
494498
495499 mergedSchema . $id = `merged_${ randomUUID ( ) } `
496500 ajvInstance . addSchema ( mergedSchema )
501+ refResolver . addSchema ( mergedSchema )
497502 location . schemaId = mergedSchema . $id
498503 location . jsonPointer = '#'
499504}
0 commit comments