@@ -6,6 +6,20 @@ import type $RefParser from "./index";
6
6
import type { ParserOptions } from "./index" ;
7
7
import type { JSONSchema } from "./index" ;
8
8
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
+ }
9
23
/**
10
24
* Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
11
25
* only has *internal* references, not any *external* references.
@@ -21,7 +35,7 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
21
35
// console.log('Bundling $ref pointers in %s', parser.$refs._root$Ref.path);
22
36
23
37
// Build an inventory of all $ref pointers in the JSON Schema
24
- const inventory : any = [ ] ;
38
+ const inventory : InventoryEntry [ ] = [ ] ;
25
39
crawl < S , O > ( parser , "schema" , parser . $refs . _root$Ref . path + "#" , "#" , 0 , inventory , parser . $refs , options ) ;
26
40
27
41
// Remap all $ref pointers
@@ -41,16 +55,16 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
41
55
* @param options
42
56
*/
43
57
function crawl < S extends object = JSONSchema , O extends ParserOptions < S > = ParserOptions < S > > (
44
- parent : any ,
58
+ parent : object | $RefParser < S , O > ,
45
59
key : string | null ,
46
60
path : string ,
47
61
pathFromRoot : string ,
48
62
indirections : number ,
49
- inventory : unknown [ ] ,
63
+ inventory : InventoryEntry [ ] ,
50
64
$refs : $Refs < S , O > ,
51
65
options : O ,
52
66
) {
53
- const obj = key === null ? parent : parent [ key ] ;
67
+ const obj = key === null ? parent : parent [ key as keyof typeof parent ] ;
54
68
55
69
if ( obj && typeof obj === "object" && ! ArrayBuffer . isView ( obj ) ) {
56
70
if ( $Ref . isAllowed$Ref ( obj ) ) {
@@ -71,7 +85,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
71
85
// This produces the shortest possible bundled references
72
86
return a . length - b . length ;
73
87
}
74
- } ) ;
88
+ } ) as ( keyof typeof obj ) [ ] ;
75
89
76
90
// eslint-disable-next-line no-shadow
77
91
for ( const key of keys ) {
@@ -104,11 +118,11 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
104
118
*/
105
119
function inventory$Ref < S extends object = JSONSchema , O extends ParserOptions < S > = ParserOptions < S > > (
106
120
$refParent : any ,
107
- $refKey : any ,
121
+ $refKey : string | null ,
108
122
path : string ,
109
- pathFromRoot : any ,
110
- indirections : any ,
111
- inventory : any ,
123
+ pathFromRoot : string ,
124
+ indirections : number ,
125
+ inventory : InventoryEntry [ ] ,
112
126
$refs : $Refs < S , O > ,
113
127
options : O ,
114
128
) {
@@ -118,7 +132,8 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
118
132
if ( pointer === null ) {
119
133
return ;
120
134
}
121
- const depth = Pointer . parse ( pathFromRoot ) . length ;
135
+ const parsed = Pointer . parse ( pathFromRoot ) ;
136
+ const depth = parsed . length ;
122
137
const file = url . stripHash ( pointer . path ) ;
123
138
const hash = url . getHash ( pointer . path ) ;
124
139
const external = file !== $refs . _root$Ref . path ;
@@ -178,9 +193,9 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
178
193
*
179
194
* @param inventory
180
195
*/
181
- function remap ( inventory : any ) {
196
+ function remap ( inventory : InventoryEntry [ ] ) {
182
197
// 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 ) => {
184
199
if ( a . file !== b . file ) {
185
200
// Group all the $refs that point to the same file
186
201
return a . file < b . file ? - 1 : + 1 ;
@@ -243,23 +258,41 @@ function remap(inventory: any) {
243
258
entry . $ref . $ref = entry . pathFromRoot ;
244
259
}
245
260
}
246
-
247
- // console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
248
261
}
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
+ // }
249
282
}
250
283
251
284
/**
252
285
* TODO
253
286
*/
254
- function findInInventory ( inventory : any , $refParent : any , $refKey : any ) {
287
+ function findInInventory ( inventory : InventoryEntry [ ] , $refParent : any , $refKey : any ) {
255
288
for ( const existingEntry of inventory ) {
256
289
if ( existingEntry && existingEntry . parent === $refParent && existingEntry . key === $refKey ) {
257
290
return existingEntry ;
258
291
}
259
292
}
260
293
}
261
294
262
- function removeFromInventory ( inventory : any , entry : any ) {
295
+ function removeFromInventory ( inventory : InventoryEntry [ ] , entry : any ) {
263
296
const index = inventory . indexOf ( entry ) ;
264
297
inventory . splice ( index , 1 ) ;
265
298
}
0 commit comments