fracturedjsonjs
Version:
JSON formatter that produces highly readable but fairly compact output
80 lines (79 loc) • 3.56 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConvertDataToDom = void 0;
const JsonItem_1 = require("./JsonItem");
const JsonItemType_1 = require("./JsonItemType");
const FracturedJsonError_1 = require("./FracturedJsonError");
/**
* Converts from JavaScript data (objects, strings, etc) to FracturedJson's DOM, to allow it to be formatted.
*/
function ConvertDataToDom(element, propName, recursionLimit = 100) {
var _a;
if (recursionLimit <= 0)
throw new FracturedJsonError_1.FracturedJsonError("Depth limit exceeded - possible circular reference");
const elementType = typeof element;
switch (elementType) {
case "function":
case "symbol":
case "undefined":
return undefined;
}
// If whatever it is has a custom "toJSON" method (like the built-in Date class), let the native JSON code
// figure it all out. toJSON could, in theory, give the string representation of a complex object or null or
// who knows what, so we need to parse it out again before dealing with it.
if (element && element["toJSON"]) {
const convertedElement = JSON.parse(JSON.stringify(element));
return ConvertDataToDom(convertedElement, propName, recursionLimit - 1);
}
// Let native JSON deal with escapes and such in the prop names.
const item = new JsonItem_1.JsonItem();
item.Name = (propName) ? JSON.stringify(propName) : "";
if (element === null) {
item.Type = JsonItemType_1.JsonItemType.Null;
item.Value = "null";
}
else if (Array.isArray(element)) {
// In arrays, undefined (including anything that can't be converted) are treated as null and take up space
// in the array.
item.Type = JsonItemType_1.JsonItemType.Array;
item.Children = element.map(ch => {
var _a;
return (_a = ConvertDataToDom(ch, undefined, recursionLimit - 1)) !== null && _a !== void 0 ? _a : ConvertDataToDom(null, undefined, recursionLimit - 1);
});
item.Children = [];
for (let i = 0; i < element.length; ++i) {
item.Children[i] = (_a = ConvertDataToDom(element[i], undefined, recursionLimit - 1)) !== null && _a !== void 0 ? _a : ConvertDataToDom(null, undefined, recursionLimit - 1);
}
}
else if (elementType === "object") {
// In objects, undefined values (including anything that can't be converted) are omitted.
item.Type = JsonItemType_1.JsonItemType.Object;
for (const kvp of Object.entries(element)) {
const childItem = ConvertDataToDom(kvp[1], kvp[0], recursionLimit - 1);
if (childItem)
item.Children.push(childItem);
}
}
else {
switch (elementType) {
case "string":
item.Type = JsonItemType_1.JsonItemType.String;
break;
case "number":
case "bigint":
item.Type = JsonItemType_1.JsonItemType.Number;
break;
case "boolean":
item.Type = (element) ? JsonItemType_1.JsonItemType.True : JsonItemType_1.JsonItemType.False;
break;
}
item.Value = JSON.stringify(element);
}
if (item.Children.length > 0) {
const highestChildComplexity = item.Children.map(ch => ch.Complexity)
.reduce((p, v) => Math.max(p, v));
item.Complexity = highestChildComplexity + 1;
}
return item;
}
exports.ConvertDataToDom = ConvertDataToDom;
;