object-as-tree
Version:
Visualise a Javascript/Typescript object in a tree structure
1 lines • 11.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/color-output.ts","../src/index.ts"],"sourcesContent":["let supported;\ntry {\n\tsupported = process.stdout.hasColors();\n} catch (e) {\n\tsupported = false;\n}\n\nconst wrap = (start: number, end: number) => \n\tsupported ? (s: string) => `\\u001B[${start}m${s}\\u001B[${end}m` : (s: string) => s;\n\nexport const reset = wrap(0, 0);\nexport const bold = wrap(1, 22);\nexport const dim = wrap(2, 22);\nexport const italic = wrap(3, 23);\nexport const underline = wrap(4, 24);\nexport const overline = wrap(53, 55);\nexport const inverse = wrap(7, 27);\nexport const hidden = wrap(8, 28);\nexport const strikethrough = wrap(9, 29);\n\nexport const black = wrap(30, 39);\nexport const red = wrap(31, 39);\nexport const green = wrap(32, 39);\nexport const yellow = wrap(33, 39);\nexport const blue = wrap(34, 39);\nexport const magenta = wrap(35, 39);\nexport const cyan = wrap(36, 39);\nexport const white = wrap(37, 39);\nexport const grey = wrap(90, 39);\n","import { dim, red, green, blue, bold, magenta, yellow } from \"./color-output\";\n\n/**\n * Returns true if the object is a class\n * \n * @param obj Any object to be checked\n * @returns True if the object is a class\n */\nfunction isClass(obj: any): boolean {\n const isConstructorClass = obj.constructor && obj.constructor.toString().substring(0, 5) === 'class'\n if (obj.prototype === undefined) {\n return isConstructorClass\n }\n const isPrototypeConstructorClass = obj.prototype.constructor\n && obj.prototype.constructor.toString\n && obj.prototype.constructor.toString().substring(0, 5) === 'class'\n return isConstructorClass || isPrototypeConstructorClass\n}\n\n// Below functions are used to style the tree\n\nfunction tree(s: string) {\n return dim(s);\n}\n\nfunction index(s: number) {\n return dim(s.toString());\n}\n\nfunction key(s: string) {\n return s;\n}\n\nfunction objType(s: string) {\n return dim(s);\n}\n\nfunction nullObj() {\n return bold('null');\n}\n\nfunction undefinedObj() {\n return red('undefined');\n}\n\nfunction string(s: string) {\n return green('\\'' + s.replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r').replace(/'/g, '\\\\\\'') + '\\'');\n}\n\nfunction number(s: number) {\n return yellow(s.toString());\n}\n\nfunction boolean(s: boolean) {\n return yellow(s.toString());\n}\n\nfunction dateObj(s: Date) {\n return objType('Date(') + magenta(s.toISOString()) + objType(')');\n}\n\nfunction regexpObj(s: RegExp) {\n return objType('RegExp(') + red(s.toString()) + objType(')');\n}\n\nfunction errorObj(s: Error) {\n return objType('Error(') + s.message + objType(')');\n}\n\nfunction functionObj(s: Function) {\n return objType('f') + ' ' + s.name + '()';\n}\n\nfunction classObj(s: any) {\n return objType('Class') + ' ' + s.name;\n}\n\nfunction anyObj(s: any) {\n return s.toString();\n}\n\nfunction comment(s: string) {\n return dim('// ' + s);\n}\n\n\n/**\n * Recursive function to convert an object to a string with tree representation\n * \n * @param obj Any object to be converted to a tree string\n * @param level Array of strings to represent the level of the tree\n * @returns A string with the tree representation of the object\n */\nfunction objectToTree(obj: any, level: string[] = [], visited: Set<any> = new Set<any>()): string {\n if (obj && typeof obj === 'object') {\n if (visited.has(obj)) {\n if (Array.isArray(obj)) {\n return objType('Array(') + obj.length + objType(')') + ' ' + comment('Circular reference\\n');\n } else {\n return objType('Object{}') + ' ' + comment('Circular reference\\n');\n }\n }\n visited.add(obj);\n }\n\n let ret: string = '';\n\n if (obj === null) {\n ret = nullObj() + '\\n';\n\n } else if (obj instanceof Date) {\n ret = dateObj(obj) + '\\n';\n\n } else if (obj instanceof RegExp) {\n ret = regexpObj(obj) + '\\n';\n\n } else if (obj instanceof Error) {\n ret = errorObj(obj) + '\\n';\n\n } else if (obj instanceof String) {\n // Substitute all \\n characters with the string '\\n'\n ret = objType('String(') + string(obj.valueOf()) + objType(')') + '\\n';\n\n } else if (obj instanceof Number) {\n ret = objType('Number(') + number(obj.valueOf()) + objType(')') + '\\n';\n\n } else if (obj instanceof Boolean) {\n ret = objType('Boolean(') + boolean(obj.valueOf()) + objType(')') + '\\n';\n\n } else if (obj instanceof Set || Array.isArray(obj)) {\n if (obj instanceof Set) {\n ret = objType('Set(') + obj.size + objType(')') + '\\n';\n obj = Array.from(obj);\n } else {\n ret = objType('Array(') + obj.length + objType(')') + '\\n';\n }\n for (let i = 0; i < obj.length; i++) {\n ret += level.join('') + (i == obj.length - 1 ? tree('└─• ') : tree('├─• ')) + index(i) + ': ' + objectToTree(obj[i], level.concat(i == obj.length - 1 ? ' ' : tree('│ ')), visited);\n }\n\n } else if (obj instanceof Map) {\n let keys: any[] = Array.from(obj.keys());\n ret = objType('Map(') + obj.size + objType(')') + '\\n' +\n keys.map((k, i) => {\n return level.join('') + (i == keys.length - 1 ? tree('└─• ') : tree('├─• ')) + key(k.toString()) + ': ' + objectToTree(obj.get(k), level.concat(i == keys.length - 1 ? ' ' : tree('│ ')), visited);\n }).join('');\n\n } else if (typeof obj === 'object' && !(obj instanceof Function)) {\n let keys: any[] = Object.keys(obj);\n ret = objType('Object{}') + '\\n' +\n keys.map((k, i) => {\n return level.join('') + (i == keys.length - 1 ? tree('└─• ') : tree('├─• ')) + key(k) + ': ' + objectToTree(obj[k], level.concat(i == keys.length - 1 ? ' ' : tree('│ ')), visited);\n }).join('');\n\n } else if (obj instanceof Function) {\n // obj is a function or a class\n if (isClass(obj)) {\n ret = classObj(obj) + '\\n';\n } else {\n ret = functionObj(obj) + '\\n';\n }\n\n } else if (typeof obj === 'string') {\n // Substitute all \\n characters with the string '\\n'\n ret = string(obj) + '\\n';\n\n } else if (typeof obj === 'number') {\n ret = number(obj) + '\\n';\n\n } else if (typeof obj === 'boolean') {\n ret = boolean(obj) + '\\n';\n\n } else if (typeof obj === 'undefined') {\n ret = undefinedObj() + '\\n';\n\n } else {\n ret = anyObj(obj) + '\\n';\n }\n\n visited.delete(obj);\n\n return ret;\n}\n\n\n\n\n/**\n * Converts the object/array to the string with tree structure\n */\nexport function asTree(obj: any = undefined): string {\n // remove last \\n character from the result\n let ret: string = objectToTree(obj);\n if (ret.length > 0 && ret[ret.length - 1] == '\\n') {\n return ret.slice(0, -1);\n }\n return ret;\n}\n\n\n"],"mappings":"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","names":[]}