From 1786729ab05cc176b26ad611f4a7466f2599c2dd Mon Sep 17 00:00:00 2001 From: Dean Date: Sat, 13 Jul 2019 21:52:23 -0700 Subject: [PATCH 1/2] feat: handle id/ref in json #35 --- resolvejson.js | 56 ++++++++++++++++++ test.html | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 resolvejson.js diff --git a/resolvejson.js b/resolvejson.js new file mode 100644 index 0000000..a2ccd9f --- /dev/null +++ b/resolvejson.js @@ -0,0 +1,56 @@ +// Usage +// ----- +// The module exports one entry point, the `resovlejson()` function. It takes in +// the JSON that has id/ref that you want to render as a single argument and returns JSON +// with whatever graph cycles that are in the document. Note that typically you can't +// fully expand the json as its a graph. But when navigating via the + sign it is what +// you would expect. +// +// There are two use cases, +// the first is microsoft's encodes it's graphs with $id $ref, to avoid cyclic graphs +// (or just to save space). This is resolved renderjson(resolvejson("$id","$idref", ... +// +// the second is for json schema's they encode their graphs with id $ref +// These can be resolved by renderjson(resolvejson("id", "$ref", ... +var resolvejson = (function () { + var resolvejson = function resolvejson(idProp, refProp, json) { + let byid = {}; //dictionary to keep the reference objects + (function collectObjIds(o) { + if (o.hasOwnProperty(idProp)) { + let id = o[idProp]; + byid[id] = o; + } + for (var i in o) { + if (o[i] !== null && typeof (o[i]) == "object") + collectObjIds(o[i]); + } + })(json) + json = (function replaceRefs(obj) { + if (typeof obj !== 'object' || !obj) // a primitive value + return obj; + if (obj.hasOwnProperty(refProp)) { + let ref = obj[refProp]; + //we will always have the ref stored in the map + if (ref in byid) { + return byid[ref]; + } else { + return obj + } + } + if (Array.isArray(obj)) { + obj = obj.map(replaceRefs); + } else { + for (let prop in obj) { + obj[prop] = replaceRefs(obj[prop]); + } + } + return obj; + })(json); + + return json; + } + return resolvejson; +})(); + +if (define) define({resolvejson: resolvejson}) +else (module || {}).exports = (window || {}).resolvejson = resolvejson; diff --git a/test.html b/test.html index 8521fb1..4913635 100644 --- a/test.html +++ b/test.html @@ -21,6 +21,15 @@

+

Json schema

+ +
+ +

Microsoft id/ref

+ +
+ + From 50a85654206671137e397d9d92996a94f4e9b06a Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 19 Jul 2019 12:04:25 -0700 Subject: [PATCH 2/2] fix: json schema should merge it weird that Object.create did not copy the attributes but this produced the desired results. --- resolvejson.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/resolvejson.js b/resolvejson.js index a2ccd9f..962efaa 100644 --- a/resolvejson.js +++ b/resolvejson.js @@ -32,7 +32,20 @@ var resolvejson = (function () { let ref = obj[refProp]; //we will always have the ref stored in the map if (ref in byid) { - return byid[ref]; + var wrk = byid[ref] + if (Object.keys(obj).length == 1) { + return wrk; + } + var rtn = {} + for (var i in wrk) { + rtn[i] = wrk[i] + } + for (var i in obj) { + if (i != refProp && rtn[i] !== null) { + rtn[i] = obj[i] + } + } + return rtn; } else { return obj }