@@ -99,7 +99,7 @@ function dereference(basePath, $refs, options) {
9999
100100 Object.keys($refs._$refs).forEach(function(key) {
101101 var $ref = $refs._$refs[key];
102- if ($ref.pathFromRoot) {
102+ if ($ref.pathFromRoot !== '#' ) {
103103 $refs.set(basePath + $ref.pathFromRoot, $ref.value, options);
104104 }
105105 });
@@ -151,11 +151,11 @@ function crawl(obj, path, parents, $refs, options) {
151151 var pointer = $refs._resolve($refPath, options);
152152
153153 // Dereference the JSON reference
154- obj[key] = value = pointer.value;
154+ value = dereference$Ref(obj, key, pointer.value) ;
155155
156156 // Crawl the dereferenced value (unless it's circular)
157157 if (parents.indexOf(value) === -1) {
158- crawl(pointer. value, pointer.path, parents, $refs, options);
158+ crawl(value, pointer.path, parents, $refs, options);
159159 }
160160 }
161161 else if (parents.indexOf(value) === -1) {
@@ -167,6 +167,33 @@ function crawl(obj, path, parents, $refs, options) {
167167 }
168168}
169169
170+ /**
171+ * Replaces the specified JSON reference with its resolved value.
172+ *
173+ * @param {object} obj - The object that contains the JSON reference
174+ * @param {string} key - The key of the JSON reference within `obj`
175+ * @param {*} value - The resolved value
176+ * @returns {*} - Returns the new value of the JSON reference
177+ */
178+ function dereference$Ref(obj, key, value) {
179+ var $refObj = obj[key];
180+
181+ if (value && typeof(value) === 'object' && Object.keys($refObj).length > 1) {
182+ // The JSON reference has additional properties (other than "$ref"),
183+ // so merge the resolved value rather than completely replacing the reference
184+ delete $refObj.$ref;
185+ Object.keys(value).forEach(function(key) {
186+ if (!(key in $refObj)) {
187+ $refObj[key] = value[key];
188+ }
189+ });
190+ }
191+ else {
192+ // Completely replace the original reference with the resolved value
193+ return obj[key] = value;
194+ }
195+ }
196+
170197},{"./ref":9,"./util":12,"url":90}],3:[function(require,module,exports){
171198(function (Buffer){
172199'use strict';
@@ -620,7 +647,7 @@ function parse(data, path, options) {
620647 */
621648function isEmpty(value) {
622649 return !value ||
623- (typeof(value) === 'object' && Object.keys(value) === 0) ||
650+ (typeof(value) === 'object' && Object.keys(value).length === 0) ||
624651 (typeof(value) === 'string' && value.trim().length === 0) ||
625652 (value instanceof Buffer && value.length === 0);
626653}
@@ -688,7 +715,7 @@ Pointer.prototype.resolve = function(obj, options) {
688715 for (var i = 0; i < tokens.length; i++) {
689716 if (resolveIf$Ref(this, options)) {
690717 // The $ref path has changed, so append the remaining tokens to the path
691- this.path += '# /' + tokens.slice(i).join('/');
718+ this.path = util.path.ensureHash(this.path) + ' /' + tokens.slice(i).join('/');
692719 }
693720
694721 var token = tokens[i];
@@ -799,16 +826,20 @@ Pointer.parse = function(path) {
799826function resolveIf$Ref(pointer, options) {
800827 // Is the value a JSON reference? (and allowed?)
801828 if ($Ref.isAllowed$Ref(pointer.value, options)) {
802- var $refPath = url.resolve(pointer.path, pointer.value.$ref);
803-
804- // Is the value a reference to itself? If so, then there's nothing to do.
805- if ($refPath !== pointer.path) {
806- // Resolve the reference
807- var resolved = pointer.$ref.$refs._resolve($refPath);
808- pointer.$ref = resolved.$ref;
809- pointer.path = resolved.path; // pointer.path = $refPath ???
810- pointer.value = resolved.value;
811- return true;
829+ // Does the JSON reference have other properties (other than "$ref")?
830+ // If so, then don't resolve it, since it represents a new type
831+ if (Object.keys(pointer.value).length === 1) {
832+ var $refPath = url.resolve(pointer.path, pointer.value.$ref);
833+
834+ // Is the value a reference to itself? If so, then there's nothing to do.
835+ if ($refPath !== pointer.path) {
836+ // Resolve the reference
837+ var resolved = pointer.$ref.$refs._resolve($refPath);
838+ pointer.$ref = resolved.$ref;
839+ pointer.path = resolved.path; // pointer.path = $refPath ???
840+ pointer.value = resolved.value;
841+ return true;
842+ }
812843 }
813844 }
814845}
@@ -1053,7 +1084,7 @@ function download(protocol, u, options) {
10531084 reject(ono('GET %s \nHTTP 204: No Content', u.href));
10541085 }
10551086 else {
1056- resolve(body);
1087+ resolve(body || '' );
10571088 }
10581089 });
10591090
@@ -1120,7 +1151,7 @@ function $Ref($refs, path) {
11201151 *
11211152 * @type {string}
11221153 */
1123- this.pathFromRoot = '';
1154+ this.pathFromRoot = '# ';
11241155
11251156 /**
11261157 * The resolved value of the JSON reference.
@@ -1296,7 +1327,7 @@ $Refs.prototype.paths = function(types) {
12961327 var keys = Object.keys($refs);
12971328 types = Array.isArray(types) ? types : Array.prototype.slice.call(arguments);
12981329
1299- if (types.length > 0) {
1330+ if (types.length > 0 && types[0] ) {
13001331 keys = keys.filter(function(key) {
13011332 return types.indexOf($refs[key].pathType) !== -1;
13021333 });
@@ -1320,6 +1351,7 @@ $Refs.prototype.values = function(types) {
13201351
13211352 return keys.reduce(function(obj, key) {
13221353 obj[key] = $refs[key].value;
1354+ return obj;
13231355 }, {});
13241356};
13251357
0 commit comments