object-as-tree
Version:
Visualise a Javascript/Typescript object in a tree structure
161 lines (160 loc) • 5.25 kB
JavaScript
// src/color-output.ts
var supported;
try {
supported = process.stdout.hasColors();
} catch (e) {
supported = false;
}
var wrap = (start, end) => supported ? (s) => `\x1B[${start}m${s}\x1B[${end}m` : (s) => s;
var reset = wrap(0, 0);
var bold = wrap(1, 22);
var dim = wrap(2, 22);
var italic = wrap(3, 23);
var underline = wrap(4, 24);
var overline = wrap(53, 55);
var inverse = wrap(7, 27);
var hidden = wrap(8, 28);
var strikethrough = wrap(9, 29);
var black = wrap(30, 39);
var red = wrap(31, 39);
var green = wrap(32, 39);
var yellow = wrap(33, 39);
var blue = wrap(34, 39);
var magenta = wrap(35, 39);
var cyan = wrap(36, 39);
var white = wrap(37, 39);
var grey = wrap(90, 39);
// src/index.ts
function isClass(obj) {
const isConstructorClass = obj.constructor && obj.constructor.toString().substring(0, 5) === "class";
if (obj.prototype === void 0) {
return isConstructorClass;
}
const isPrototypeConstructorClass = obj.prototype.constructor && obj.prototype.constructor.toString && obj.prototype.constructor.toString().substring(0, 5) === "class";
return isConstructorClass || isPrototypeConstructorClass;
}
function tree(s) {
return dim(s);
}
function index(s) {
return dim(s.toString());
}
function key(s) {
return s;
}
function objType(s) {
return dim(s);
}
function nullObj() {
return bold("null");
}
function undefinedObj() {
return red("undefined");
}
function string(s) {
return green("'" + s.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/'/g, "\\'") + "'");
}
function number(s) {
return yellow(s.toString());
}
function boolean(s) {
return yellow(s.toString());
}
function dateObj(s) {
return objType("Date(") + magenta(s.toISOString()) + objType(")");
}
function regexpObj(s) {
return objType("RegExp(") + red(s.toString()) + objType(")");
}
function errorObj(s) {
return objType("Error(") + s.message + objType(")");
}
function functionObj(s) {
return objType("f") + " " + s.name + "()";
}
function classObj(s) {
return objType("Class") + " " + s.name;
}
function anyObj(s) {
return s.toString();
}
function comment(s) {
return dim("// " + s);
}
function objectToTree(obj, level = [], visited = /* @__PURE__ */ new Set()) {
if (obj && typeof obj === "object") {
if (visited.has(obj)) {
if (Array.isArray(obj)) {
return objType("Array(") + obj.length + objType(")") + " " + comment("Circular reference\n");
} else {
return objType("Object{}") + " " + comment("Circular reference\n");
}
}
visited.add(obj);
}
let ret = "";
if (obj === null) {
ret = nullObj() + "\n";
} else if (obj instanceof Date) {
ret = dateObj(obj) + "\n";
} else if (obj instanceof RegExp) {
ret = regexpObj(obj) + "\n";
} else if (obj instanceof Error) {
ret = errorObj(obj) + "\n";
} else if (obj instanceof String) {
ret = objType("String(") + string(obj.valueOf()) + objType(")") + "\n";
} else if (obj instanceof Number) {
ret = objType("Number(") + number(obj.valueOf()) + objType(")") + "\n";
} else if (obj instanceof Boolean) {
ret = objType("Boolean(") + boolean(obj.valueOf()) + objType(")") + "\n";
} else if (obj instanceof Set || Array.isArray(obj)) {
if (obj instanceof Set) {
ret = objType("Set(") + obj.size + objType(")") + "\n";
obj = Array.from(obj);
} else {
ret = objType("Array(") + obj.length + objType(")") + "\n";
}
for (let i = 0; i < obj.length; i++) {
ret += level.join("") + (i == obj.length - 1 ? tree("\u2514\u2500\u2022 ") : tree("\u251C\u2500\u2022 ")) + index(i) + ": " + objectToTree(obj[i], level.concat(i == obj.length - 1 ? " " : tree("\u2502 ")), visited);
}
} else if (obj instanceof Map) {
let keys = Array.from(obj.keys());
ret = objType("Map(") + obj.size + objType(")") + "\n" + keys.map((k, i) => {
return level.join("") + (i == keys.length - 1 ? tree("\u2514\u2500\u2022 ") : tree("\u251C\u2500\u2022 ")) + key(k.toString()) + ": " + objectToTree(obj.get(k), level.concat(i == keys.length - 1 ? " " : tree("\u2502 ")), visited);
}).join("");
} else if (typeof obj === "object" && !(obj instanceof Function)) {
let keys = Object.keys(obj);
ret = objType("Object{}") + "\n" + keys.map((k, i) => {
return level.join("") + (i == keys.length - 1 ? tree("\u2514\u2500\u2022 ") : tree("\u251C\u2500\u2022 ")) + key(k) + ": " + objectToTree(obj[k], level.concat(i == keys.length - 1 ? " " : tree("\u2502 ")), visited);
}).join("");
} else if (obj instanceof Function) {
if (isClass(obj)) {
ret = classObj(obj) + "\n";
} else {
ret = functionObj(obj) + "\n";
}
} else if (typeof obj === "string") {
ret = string(obj) + "\n";
} else if (typeof obj === "number") {
ret = number(obj) + "\n";
} else if (typeof obj === "boolean") {
ret = boolean(obj) + "\n";
} else if (typeof obj === "undefined") {
ret = undefinedObj() + "\n";
} else {
ret = anyObj(obj) + "\n";
}
visited.delete(obj);
return ret;
}
function asTree(obj = void 0) {
let ret = objectToTree(obj);
if (ret.length > 0 && ret[ret.length - 1] == "\n") {
return ret.slice(0, -1);
}
return ret;
}
export {
asTree
};
//# sourceMappingURL=index.mjs.map