11import $Ref from "./ref.js" ;
22import Pointer from "./pointer.js" ;
33import * as url from "./util/url.js" ;
4+ import { getSchemaBasePath } from "./util/schema-resources.js" ;
45import type $Refs from "./refs.js" ;
56import type $RefParser from "./index.js" ;
67import type { ParserOptions } from "./index.js" ;
@@ -37,7 +38,18 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
3738
3839 // Build an inventory of all $ref pointers in the JSON Schema
3940 const inventory : InventoryEntry [ ] = [ ] ;
40- crawl < S , O > ( parser , "schema" , parser . $refs . _root$Ref . path + "#" , "#" , 0 , inventory , parser . $refs , options ) ;
41+ crawl < S , O > (
42+ parser ,
43+ "schema" ,
44+ parser . $refs . _root$Ref . path + "#" ,
45+ parser . $refs . _root$Ref . path ! ,
46+ parser . $refs . _root$Ref . dynamicIdScope ,
47+ "#" ,
48+ 0 ,
49+ inventory ,
50+ parser . $refs ,
51+ options ,
52+ ) ;
4153
4254 // Get the root schema's $id (if any) for qualifying refs inside sub-schemas with their own $id
4355 const rootId =
@@ -71,6 +83,8 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
7183 parent : object | $RefParser < S , O > ,
7284 key : string | null ,
7385 path : string ,
86+ scopeBase : string ,
87+ dynamicIdScope : boolean ,
7488 pathFromRoot : string ,
7589 indirections : number ,
7690 inventory : InventoryEntry [ ] ,
@@ -82,8 +96,9 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
8296 const isExcludedPath = bundleOptions . excludedPathMatcher || ( ( ) => false ) ;
8397
8498 if ( obj && typeof obj === "object" && ! ArrayBuffer . isView ( obj ) && ! isExcludedPath ( pathFromRoot ) ) {
99+ const currentScopeBase = dynamicIdScope ? getSchemaBasePath ( scopeBase , obj ) : scopeBase ;
85100 if ( $Ref . isAllowed$Ref ( obj ) ) {
86- inventory$Ref ( parent , key , path , pathFromRoot , indirections , inventory , $refs , options ) ;
101+ inventory$Ref ( parent , key , path , currentScopeBase , dynamicIdScope , pathFromRoot , indirections , inventory , $refs , options ) ;
87102 } else {
88103 // Crawl the object in a specific order that's optimized for bundling.
89104 // This is important because it determines how `pathFromRoot` gets built,
@@ -108,9 +123,21 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
108123 const value = obj [ key ] ;
109124
110125 if ( $Ref . isAllowed$Ref ( value ) ) {
111- inventory$Ref ( obj , key , path , keyPathFromRoot , indirections , inventory , $refs , options ) ;
126+ const valueScopeBase = dynamicIdScope ? getSchemaBasePath ( currentScopeBase , value ) : currentScopeBase ;
127+ inventory$Ref (
128+ obj ,
129+ key ,
130+ keyPath ,
131+ valueScopeBase ,
132+ dynamicIdScope ,
133+ keyPathFromRoot ,
134+ indirections ,
135+ inventory ,
136+ $refs ,
137+ options ,
138+ ) ;
112139 } else {
113- crawl ( obj , key , keyPath , keyPathFromRoot , indirections , inventory , $refs , options ) ;
140+ crawl ( obj , key , keyPath , currentScopeBase , dynamicIdScope , keyPathFromRoot , indirections , inventory , $refs , options ) ;
114141 }
115142
116143 // We need to ensure that we have an object to work with here because we may be crawling
@@ -142,14 +169,16 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
142169 $refParent : any ,
143170 $refKey : string | null ,
144171 path : string ,
172+ scopeBase : string ,
173+ dynamicIdScope : boolean ,
145174 pathFromRoot : string ,
146175 indirections : number ,
147176 inventory : InventoryEntry [ ] ,
148177 $refs : $Refs < S , O > ,
149178 options : O ,
150179) {
151180 const $ref = $refKey === null ? $refParent : $refParent [ $refKey ] ;
152- const $refPath = url . resolve ( path , $ref . $ref ) ;
181+ const $refPath = url . resolve ( dynamicIdScope ? scopeBase : path , $ref . $ref ) ;
153182 const pointer = $refs . _resolve ( $refPath , pathFromRoot , options ) ;
154183 if ( pointer === null ) {
155184 return ;
@@ -158,7 +187,7 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
158187 const depth = parsed . length ;
159188 const file = url . stripHash ( pointer . path ) ;
160189 const hash = url . getHash ( pointer . path ) ;
161- const external = file !== $refs . _root$Ref . path ;
190+ const external = file !== $refs . _root$Ref . path && ! $refs . _aliases [ file ] ;
162191 const extended = $Ref . isExtended$Ref ( $ref ) ;
163192 indirections += pointer . indirections ;
164193
@@ -189,7 +218,18 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
189218
190219 // Recursively crawl the resolved value
191220 if ( ! existingEntry || external ) {
192- crawl ( pointer . value , null , pointer . path , pathFromRoot , indirections + 1 , inventory , $refs , options ) ;
221+ crawl (
222+ pointer . value ,
223+ null ,
224+ pointer . path ,
225+ pointer . $ref . path ! ,
226+ pointer . $ref . dynamicIdScope ,
227+ pathFromRoot ,
228+ indirections + 1 ,
229+ inventory ,
230+ $refs ,
231+ options ,
232+ ) ;
193233 }
194234}
195235
0 commit comments