UNPKG

@tduyng/prettyoutput

Version:

Library to format JSON objects into a colorful, YAML-style output. Ideal for pretty printing logs with high performance.

116 lines 4.42 kB
import { indentString, renderDash, renderMaxDepth, renderMaxDepthArrayValue, renderMaxDepthObjectValue, renderMultilineString, renderObjectErrorStack, renderObjectKey, renderSerializable, renderSerializableArrayValue, renderSerializableObjectValue, } from './renderer.js'; import { indent, isSerializable, maxLength } from './utils.js'; const defaultStack = (input) => ({ input, noRender: true, indentation: '', depth: 0, }); const parseOptions = (opts = {}) => { const optsColors = opts.colors || {}; const color = { keys: optsColors.keys || 'green', dash: optsColors.dash || 'green', number: optsColors.number || 'blue', string: optsColors.string, true: optsColors.true || 'green', false: optsColors.false || 'red', null: optsColors.null || 'grey', undefined: optsColors.undefined || 'grey', }; return { indentation: indent(opts.indentationLength || 2), maxDepth: opts.maxDepth ?? 3, colors: !opts.noColor ? color : undefined, alignKeyValues: opts.alignKeyValues !== false, hideUndefined: opts.hideUndefined ?? false, }; }; const prettyOutput = (input, opts, indentLevel = 0) => { const options = parseOptions(opts); const stack = [{ indentation: indent(indentLevel), depth: 0, input }]; let output = ''; while (stack.length > 0) { const item = stack.pop(); if (!item) continue; const { indentation, depth, input, noRender } = item; if (noRender) { output += input; continue; } if (depth > options.maxDepth) { output += renderMaxDepth(indentation); continue; } if (isSerializable(input)) { output += renderSerializable(input, options, indentation); continue; } if (typeof input === 'string') { output += renderMultilineString(input, options, indentation); continue; } if (Array.isArray(input)) { handleArrayRendering(input, options, stack, indentation, depth); continue; } if (typeof input === 'object' && input !== null) { handleObjectRendering(input, options, stack, indentation, depth); } } return output; }; const handleArrayRendering = (input, options, stack, indentation, depth) => { for (let i = input.length - 1; i >= 0; i--) { const value = input[i]; if (isSerializable(value)) { stack.push(defaultStack(renderSerializableArrayValue(value, options, indentation))); continue; } if (depth + 1 > options.maxDepth) { stack.push(defaultStack(renderMaxDepthArrayValue(options, indentation))); continue; } stack.push({ input: value, indentation: indentString(indentation, options), depth: depth + 1, }); stack.push(defaultStack(`${renderDash(options, indentation)}\n`)); } }; const handleObjectRendering = (input, options, stack, indentation, depth) => { const keys = Object.getOwnPropertyNames(input); const valueColumn = options.alignKeyValues ? maxLength(keys) : 0; for (let i = keys.length - 1; i >= 0; i--) { const key = keys[i]; if (!key) continue; const value = input[key]; if (input instanceof Error && key === 'stack') { stack.push(defaultStack(renderObjectErrorStack(key, value, options, indentation))); continue; } if (isSerializable(value)) { const result = renderSerializableObjectValue(key, value, valueColumn, options, indentation); if (result !== undefined) stack.push(defaultStack(result)); continue; } if (depth + 1 > options.maxDepth) { stack.push(defaultStack(renderMaxDepthObjectValue(key, valueColumn, options, indentation))); continue; } stack.push({ input: value, depth: depth + 1, indentation: indentString(indentation, options), }); stack.push(defaultStack(`${renderObjectKey(key, options, indentation)}\n`)); } }; export default prettyOutput; export { prettyOutput }; export { prettyOutput as prettyoutput }; //# sourceMappingURL=index.js.map