@@ -6,6 +6,20 @@ import type $RefParser from "./index";
66import type { ParserOptions } from "./index" ;
77import type { JSONSchema } from "./index" ;
88
9+ export interface InventoryEntry {
10+ $ref : any ;
11+ parent : any ;
12+ key : any ;
13+ pathFromRoot : any ;
14+ depth : any ;
15+ file : any ;
16+ hash : any ;
17+ value : any ;
18+ circular : any ;
19+ extended : any ;
20+ external : any ;
21+ indirections : any ;
22+ }
923/**
1024 * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
1125 * only has *internal* references, not any *external* references.
@@ -21,7 +35,7 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
2135 // console.log('Bundling $ref pointers in %s', parser.$refs._root$Ref.path);
2236
2337 // Build an inventory of all $ref pointers in the JSON Schema
24- const inventory : any = [ ] ;
38+ const inventory : InventoryEntry [ ] = [ ] ;
2539 crawl < S , O > ( parser , "schema" , parser . $refs . _root$Ref . path + "#" , "#" , 0 , inventory , parser . $refs , options ) ;
2640
2741 // Remap all $ref pointers
@@ -41,16 +55,16 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
4155 * @param options
4256 */
4357function crawl < S extends object = JSONSchema , O extends ParserOptions < S > = ParserOptions < S > > (
44- parent : any ,
58+ parent : object | $RefParser < S , O > ,
4559 key : string | null ,
4660 path : string ,
4761 pathFromRoot : string ,
4862 indirections : number ,
49- inventory : unknown [ ] ,
63+ inventory : InventoryEntry [ ] ,
5064 $refs : $Refs < S , O > ,
5165 options : O ,
5266) {
53- const obj = key === null ? parent : parent [ key ] ;
67+ const obj = key === null ? parent : parent [ key as keyof typeof parent ] ;
5468
5569 if ( obj && typeof obj === "object" && ! ArrayBuffer . isView ( obj ) ) {
5670 if ( $Ref . isAllowed$Ref ( obj ) ) {
@@ -71,7 +85,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
7185 // This produces the shortest possible bundled references
7286 return a . length - b . length ;
7387 }
74- } ) ;
88+ } ) as ( keyof typeof obj ) [ ] ;
7589
7690 // eslint-disable-next-line no-shadow
7791 for ( const key of keys ) {
@@ -104,11 +118,11 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
104118 */
105119function inventory$Ref < S extends object = JSONSchema , O extends ParserOptions < S > = ParserOptions < S > > (
106120 $refParent : any ,
107- $refKey : any ,
121+ $refKey : string | null ,
108122 path : string ,
109- pathFromRoot : any ,
110- indirections : any ,
111- inventory : any ,
123+ pathFromRoot : string ,
124+ indirections : number ,
125+ inventory : InventoryEntry [ ] ,
112126 $refs : $Refs < S , O > ,
113127 options : O ,
114128) {
@@ -118,7 +132,8 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
118132 if ( pointer === null ) {
119133 return ;
120134 }
121- const depth = Pointer . parse ( pathFromRoot ) . length ;
135+ const parsed = Pointer . parse ( pathFromRoot ) ;
136+ const depth = parsed . length ;
122137 const file = url . stripHash ( pointer . path ) ;
123138 const hash = url . getHash ( pointer . path ) ;
124139 const external = file !== $refs . _root$Ref . path ;
@@ -178,9 +193,9 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
178193 *
179194 * @param inventory
180195 */
181- function remap ( inventory : any ) {
196+ function remap ( inventory : InventoryEntry [ ] ) {
182197 // Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them
183- inventory . sort ( ( a : any , b : any ) => {
198+ inventory . sort ( ( a : InventoryEntry , b : InventoryEntry ) => {
184199 if ( a . file !== b . file ) {
185200 // Group all the $refs that point to the same file
186201 return a . file < b . file ? - 1 : + 1 ;
@@ -243,23 +258,41 @@ function remap(inventory: any) {
243258 entry . $ref . $ref = entry . pathFromRoot ;
244259 }
245260 }
246-
247- // console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
248261 }
262+
263+ // we want to ensure that any $refs that point to another $ref are remapped to point to the final value
264+ // let hadChange = true;
265+ // while (hadChange) {
266+ // hadChange = false;
267+ // for (const entry of inventory) {
268+ // if (entry.$ref && typeof entry.$ref === "object" && "$ref" in entry.$ref) {
269+ // const resolved = inventory.find((e: InventoryEntry) => e.pathFromRoot === entry.$ref.$ref);
270+ // if (resolved) {
271+ // const resolvedPointsToAnotherRef =
272+ // resolved.$ref && typeof resolved.$ref === "object" && "$ref" in resolved.$ref;
273+ // if (resolvedPointsToAnotherRef && entry.$ref.$ref !== resolved.$ref.$ref) {
274+ // // console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot);
275+ // entry.$ref.$ref = resolved.$ref.$ref;
276+ // hadChange = true;
277+ // }
278+ // }
279+ // }
280+ // }
281+ // }
249282}
250283
251284/**
252285 * TODO
253286 */
254- function findInInventory ( inventory : any , $refParent : any , $refKey : any ) {
287+ function findInInventory ( inventory : InventoryEntry [ ] , $refParent : any , $refKey : any ) {
255288 for ( const existingEntry of inventory ) {
256289 if ( existingEntry && existingEntry . parent === $refParent && existingEntry . key === $refKey ) {
257290 return existingEntry ;
258291 }
259292 }
260293}
261294
262- function removeFromInventory ( inventory : any , entry : any ) {
295+ function removeFromInventory ( inventory : InventoryEntry [ ] , entry : any ) {
263296 const index = inventory . indexOf ( entry ) ;
264297 inventory . splice ( index , 1 ) ;
265298}
0 commit comments