@@ -43,11 +43,11 @@ function crawl(obj, path, parents, $refs, options) {
4343 var pointer = $refs . _resolve ( $refPath , options ) ;
4444
4545 // Dereference the JSON reference
46- obj [ key ] = value = pointer . value ;
46+ value = dereference$Ref ( obj , key , pointer . value ) ;
4747
4848 // Crawl the dereferenced value (unless it's circular)
4949 if ( parents . indexOf ( value ) === - 1 ) {
50- crawl ( pointer . value , pointer . path , parents , $refs , options ) ;
50+ crawl ( value , pointer . path , parents , $refs , options ) ;
5151 }
5252 }
5353 else if ( parents . indexOf ( value ) === - 1 ) {
@@ -58,3 +58,30 @@ function crawl(obj, path, parents, $refs, options) {
5858 parents . pop ( ) ;
5959 }
6060}
61+
62+ /**
63+ * Replaces the specified JSON reference with its resolved value.
64+ *
65+ * @param {object } obj - The object that contains the JSON reference
66+ * @param {string } key - The key of the JSON reference within `obj`
67+ * @param {* } value - The resolved value
68+ * @returns {* } - Returns the new value of the JSON reference
69+ */
70+ function dereference$Ref ( obj , key , value ) {
71+ var $refObj = obj [ key ] ;
72+
73+ if ( value && typeof ( value ) === 'object' && Object . keys ( $refObj ) . length > 1 ) {
74+ // The JSON reference has additional properties (other than "$ref"),
75+ // so merge the resolved value rather than completely replacing the reference
76+ delete $refObj . $ref ;
77+ Object . keys ( value ) . forEach ( function ( key ) {
78+ if ( ! ( key in $refObj ) ) {
79+ $refObj [ key ] = value [ key ] ;
80+ }
81+ } ) ;
82+ }
83+ else {
84+ // Completely replace the original reference with the resolved value
85+ return obj [ key ] = value ;
86+ }
87+ }
0 commit comments