Added 'resolveLocal()'

This commit is contained in:
Ryan Leonard 2017-03-21 16:26:51 -07:00
parent 8febb78ca0
commit e6d64ce58a
2 changed files with 91 additions and 0 deletions

View File

@ -1,3 +1,5 @@
var path = require("path");
/**
* Applies a single JSON reference lookup to an object. Does not resolve references in the returned document.
* @param {string} ref the JSON reference to search for - e.g. `"#/foo/bar"`
@ -21,6 +23,38 @@ function jsonSearch(ref, obj) {
return current;
}
/**
* Resolve all local JSON references in a single document. Resolves absolute references (`#/test/`) and relative paths
* (`../test`), but does not change any references to remote files.
* Mutates the given object with resolved references.
* @param {Object} doc the root JSON document that references are being resolved in.
* @param {Object} obj a section of the JSON document that is being evaluated.
* @param {String} ref the path to the current object inside the JSON document, as a JSON reference.
*/
function resolveLocal(doc, obj, ref) {
if(typeof obj !== "object") {
throw new TypeError("resolveLocal() must be given an object. Given "+typeof obj);
}
for(var k in obj) {
var val = obj[k];
if(typeof val !== "object") { continue; }
if(val.$ref) {
var $ref = val.$ref;
if($ref.indexOf("./") === 0 || $ref.indexOf("../") === 0) {
$ref = path.join(ref, k, $ref);
}
if($ref.indexOf("#/") === 0) {
Object.assign(val, jsonSearch($ref, doc));
delete val.$ref;
}
}
else {
resolveLocal(doc, val, path.join(ref, k));
}
}
}
module.exports = {
jsonSearch: jsonSearch,
resolveLocal: resolveLocal,
};

View File

@ -45,4 +45,61 @@ describe("json-reference.js", function() {
});
describe("resolveLocal()", function() {
it("should resolve absolute references", function() {
var obj = {
def: {a: 1},
ref: { "$ref": "#/def" },
};
json.resolveLocal(obj, obj, "#/");
obj.should.deep.equal({
def: {a: 1},
ref: {a: 1},
});
});
it("should resolve relative references", function() {
var obj = {
def: {a: 1},
ref: { "$ref": "../def" },
};
json.resolveLocal(obj, obj, "#/");
obj.should.deep.equal({
def: {a: 1},
ref: {a: 1},
});
});
it("should resolve deep references", function() {
var obj = {
def: { foo: {a: 1} },
ref: {
root: { "$ref": "#/def/foo" },
local: { "$ref": "../../def/foo" },
},
};
json.resolveLocal(obj, obj, "#/");
obj.should.deep.equal({
def: { foo: {a: 1} },
ref: {
root: {a: 1},
local: {a: 1},
},
});
});
it("should leave remote references", function() {
var def = {
relative: { "$ref": "Pet.json" },
root: { "$ref": "/home/test/Pet.json" },
remote: { "$ref": "http://example.com/Pet.json" },
};
var obj = Object.create(def);
json.resolveLocal(obj, obj, "#/");
obj.should.deep.equal(def);
});
});
});