1
- import { pathToPointer , stringify } from '@stoplight/json' ;
1
+ import { pathToPointer } from '@stoplight/json' ;
2
2
3
3
import { ResolvingError } from '../errors' ;
4
4
import type { SchemaFragment } from '../types' ;
@@ -8,8 +8,18 @@ const resolveAllOf = require('@stoplight/json-schema-merge-allof');
8
8
9
9
const store = new WeakMap < WalkerRefResolver , WeakMap < SchemaFragment , string [ ] > > ( ) ;
10
10
11
- function _mergeAllOf ( fragment : SchemaFragment , path : string [ ] , resolveRef : WalkerRefResolver | null ) : SchemaFragment {
12
- return resolveAllOf ( fragment , {
11
+ function _mergeAllOf (
12
+ fragment : SchemaFragment ,
13
+ path : string [ ] ,
14
+ resolveRef : WalkerRefResolver | null ,
15
+ seen : WeakMap < SchemaFragment , SchemaFragment > ,
16
+ ) : SchemaFragment {
17
+ const cached = seen . get ( fragment ) ;
18
+ if ( cached !== void 0 ) {
19
+ return cached ;
20
+ }
21
+
22
+ const merged = resolveAllOf ( fragment , {
13
23
deep : false ,
14
24
resolvers : resolveAllOf . stoplightResolvers ,
15
25
...( resolveRef !== null
@@ -30,8 +40,8 @@ function _mergeAllOf(fragment: SchemaFragment, path: string[], resolveRef: Walke
30
40
schemaRefs = [ $ref ] ;
31
41
allRefs . set ( fragment , schemaRefs ) ;
32
42
} else if ( schemaRefs . includes ( $ref ) ) {
33
- const safelyResolved = JSON . parse ( stringify ( resolveRef ( null , $ref ) ) ) ;
34
- return 'allOf' in safelyResolved ? _mergeAllOf ( safelyResolved , path , resolveRef ) : safelyResolved ;
43
+ const resolved = resolveRef ( null , $ref ) ;
44
+ return 'allOf' in resolved ? _mergeAllOf ( resolved , path , resolveRef , seen ) : resolved ;
35
45
} else {
36
46
schemaRefs . push ( $ref ) ;
37
47
}
@@ -52,17 +62,25 @@ function _mergeAllOf(fragment: SchemaFragment, path: string[], resolveRef: Walke
52
62
}
53
63
: null ) ,
54
64
} ) ;
65
+
66
+ seen . set ( fragment , merged ) ;
67
+ return merged ;
55
68
}
56
69
57
- export function mergeAllOf ( fragment : SchemaFragment , path : string [ ] , walkingOptions : WalkingOptions ) {
70
+ export function mergeAllOf (
71
+ fragment : SchemaFragment ,
72
+ path : string [ ] ,
73
+ walkingOptions : WalkingOptions ,
74
+ seen : WeakMap < SchemaFragment , SchemaFragment > ,
75
+ ) {
58
76
if ( walkingOptions . resolveRef !== null && ! store . has ( walkingOptions . resolveRef ) ) {
59
77
store . set ( walkingOptions . resolveRef , new WeakMap ( ) ) ;
60
78
}
61
79
62
- let merged = _mergeAllOf ( fragment , path , walkingOptions . resolveRef ) ;
63
- while ( 'allOf' in merged ) {
64
- merged = _mergeAllOf ( merged , path , walkingOptions . resolveRef ) ;
65
- }
80
+ let merged = fragment ;
81
+ do {
82
+ merged = _mergeAllOf ( merged , path , walkingOptions . resolveRef , seen ) ;
83
+ } while ( 'allOf' in merged ) ;
66
84
67
85
return merged ;
68
86
}
0 commit comments