@@ -2,6 +2,7 @@ import stampit from 'stampit';
2
2
import { propEq } from 'ramda' ;
3
3
import { ApiDOMError } from '@swagger-api/apidom-error' ;
4
4
import {
5
+ Element ,
5
6
RefElement ,
6
7
isElement ,
7
8
isMemberElement ,
@@ -11,6 +12,7 @@ import {
11
12
toValue ,
12
13
refract ,
13
14
visit ,
15
+ cloneDeep ,
14
16
} from '@swagger-api/apidom-core' ;
15
17
import { uriToPointer as uriToElementID } from '@swagger-api/apidom-json-pointer' ;
16
18
@@ -72,19 +74,34 @@ const ApiDOMDereferenceVisitor = stampit({
72
74
parse : { ...this . options . parse , mediaType : 'text/plain' } ,
73
75
} ) ;
74
76
75
- // register new Reference with ReferenceSet
76
- const reference = Reference ( {
77
+ // register new mutable reference with a refSet
78
+ const mutableReference = Reference ( {
77
79
uri : baseURI ,
78
- value : parseResult ,
80
+ value : cloneDeep ( parseResult ) ,
79
81
depth : this . reference . depth + 1 ,
80
82
} ) ;
83
+ refSet . add ( mutableReference ) ;
84
+
85
+ if ( this . options . dereference . immutable ) {
86
+ // register new immutable reference with a refSet
87
+ const immutableReference = Reference ( {
88
+ uri : `immutable://${ baseURI } ` ,
89
+ value : parseResult ,
90
+ depth : this . reference . depth + 1 ,
91
+ } ) ;
92
+ refSet . add ( immutableReference ) ;
93
+ }
81
94
82
- refSet . add ( reference ) ;
83
-
84
- return reference ;
95
+ return mutableReference ;
85
96
} ,
86
97
87
- async RefElement ( refElement : RefElement , key : any , parent : any , path : any , ancestors : any [ ] ) {
98
+ async RefElement (
99
+ refElement : RefElement ,
100
+ key : string | number ,
101
+ parent : Element | undefined ,
102
+ path : ( string | number ) [ ] ,
103
+ ancestors : [ Element | Element [ ] ] ,
104
+ ) {
88
105
const refURI = toValue ( refElement ) ;
89
106
const refNormalizedURI = refURI . includes ( '#' ) ? refURI : `#${ refURI } ` ;
90
107
const retrievalURI = this . toBaseURI ( refNormalizedURI ) ;
@@ -139,13 +156,22 @@ const ApiDOMDereferenceVisitor = stampit({
139
156
/**
140
157
* Transclusion of a Ref Element SHALL be defined in the if/else block below.
141
158
*/
142
- if ( isObjectElement ( referencedElement ) && isObjectElement ( ancestors [ ancestors . length - 1 ] ) ) {
159
+ if (
160
+ isObjectElement ( referencedElement ) &&
161
+ isObjectElement ( ancestors [ ancestors . length - 1 ] ) &&
162
+ Array . isArray ( parent ) &&
163
+ typeof key === 'number'
164
+ ) {
143
165
/**
144
166
* If the Ref Element is held by an Object Element and references an Object Element,
145
167
* its content entries SHALL be inserted in place of the Ref Element.
146
168
*/
147
169
parent . splice ( key , 1 , ...referencedElement . content ) ;
148
- } else if ( isArrayElement ( referencedElement ) && Array . isArray ( parent ) ) {
170
+ } else if (
171
+ isArrayElement ( referencedElement ) &&
172
+ Array . isArray ( parent ) &&
173
+ typeof key === 'number'
174
+ ) {
149
175
/**
150
176
* If the Ref Element is held by an Array Element and references an Array Element,
151
177
* its content entries SHALL be inserted in place of the Ref Element.
@@ -163,7 +189,7 @@ const ApiDOMDereferenceVisitor = stampit({
163
189
parent [ key ] = referencedElement ; // eslint-disable-line no-param-reassign
164
190
}
165
191
166
- return false ;
192
+ return ! parent ? referencedElement : false ;
167
193
} ,
168
194
} ,
169
195
} ) ;
0 commit comments