@tduyng/prettyoutput
Version:
Library to format JSON objects into a colorful, YAML-style output. Ideal for pretty printing logs with high performance.
115 lines • 4.41 kB
JavaScript
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, prettyOutput as prettyoutput };
//# sourceMappingURL=index.js.map