Skip to content

Commit

Permalink
feat: handle id/ref in json caldwell#35
Browse files Browse the repository at this point in the history
  • Loading branch information
andifreed committed Jul 14, 2019
1 parent ff346a6 commit 1786729
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 0 deletions.
56 changes: 56 additions & 0 deletions resolvejson.js
Original file line number Diff line number Diff line change
@@ -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;
154 changes: 154 additions & 0 deletions test.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ <h1></h1>

<div id="dest"></div>

<h2>Json schema</h2>

<div id="schema"></div>

<h2>Microsoft id/ref</h2>

<div id="idref"></div>

<script type="text/javascript" src="resolvejson.js"></script>
<script type="text/javascript" src="renderjson.js"></script>
<script>
document.getElementById("dest").appendChild(
Expand Down Expand Up @@ -245,6 +254,151 @@ <h1></h1>
else return v;
});
document.getElementById("dest").appendChild(renderjson({ window: window, document: document, bad_nums:[1/0, parseInt("abcd")], "#dest":document.getElementById("dest") }));
document.getElementById("idref").appendChild(
renderjson(
resolvejson("$id", "$ref",
[
{
"$id":"1",
"Name":"Alice",
"Sibling":{
"$id":"2",
"Name":"Bob",
"Sibling":{
"$ref":"1"
}
}
},
{
"$ref":"2"
}
]
)
)
)

document.getElementById("schema").appendChild(
renderjson(
resolvejson("id", "$ref",
{
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:SimpleSubClassRoot",
"properties": {
"action": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AppAction",
"required": true,
"oneOf": [{
"$ref": "urn:jsonschema:rmistry:schema:test:AddActivityAppAction"
}, {
"$ref": "urn:jsonschema:rmistry:schema:test:AddNoteAppAction"
}, {
"$ref": "urn:jsonschema:rmistry:schema:test:AppAction"
}]
}
},
"definitions": {
"urn:jsonschema:rmistry:schema:test:AssignTo": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AssignTo",
"required": true,
"oneOf": [{
"$ref": "urn:jsonschema:rmistry:schema:test:AssignToDefault"
}, {
"$ref": "urn:jsonschema:rmistry:schema:test:AssignToGroup"
}]
},
"urn:jsonschema:rmistry:schema:test:AssignToDefault": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AssignToDefault",
"additionalProperties": false,
"properties": {
"properties": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"target": {
"type": "string",
"required": true
}
}
},
"urn:jsonschema:rmistry:schema:test:AssignToGroup": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AssignToGroup",
"additionalProperties": false,
"properties": {
"groupName": {
"type": "string",
"required": true
},
"target": {
"type": "string",
"required": true
}
}
},
"urn:jsonschema:rmistry:schema:test:AddActivityAppAction": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AddActivityAppAction",
"additionalProperties": false,
"properties": {
"action": {
"type": "string",
"required": true
},
"addToParent": {
"type": "boolean"
},
"assignTo": {
"type": "object",
"$ref": "urn:jsonschema:rmistry:schema:test:AssignTo",
"required": true
},
"properties": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"urn:jsonschema:rmistry:schema:test:AddNoteAppAction": {
"type": "object",
"id": "urn:jsonschema:rmistry:schema:test:AddNoteAppAction",
"additionalProperties": false,
"properties": {
"action": {
"type": "string",
"required": true
},
"addToParent": {
"type": "boolean"
},
"markConfidential": {
"type": "boolean",
"required": true
},
"properties": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"topic": {
"type": "string",
"required": true
}
}
}
}
}
)
)
)

</script>
</body>
</html>

0 comments on commit 1786729

Please sign in to comment.