UNPKG

@visulima/pail

Version:

Highly configurable Logger for Node.js, Edge and Browser.

193 lines (190 loc) 6.52 kB
import { stdout, stderr } from 'node:process'; import colorize, { red, greenBright, cyan, green, grey, white, bgGrey, underline } from '@visulima/colorize'; import { renderError } from '@visulima/error/error'; import { inspect } from '@visulima/inspector'; import { d as defaultInspectorConfig, t as terminalSize, f as formatLabel, s as stringLength, w as wrapAnsi } from './format-label-DCVqdv1Z.mjs'; import { E as EMPTY_SYMBOL } from './constants-BYYZ5WNW.mjs'; import { A as AbstractPrettyReporter, g as getLongestBadge } from './abstract-pretty-reporter-izJgxoMv.mjs'; import { g as getLongestLabel } from './get-longest-label-CM8kLFWH.mjs'; import { w as writeStream } from './write-stream-BBAF33Zm.mjs'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); const pailFileFilter = /* @__PURE__ */ __name((line) => !/[\\/]pail[\\/]dist/.test(line), "pailFileFilter"); class PrettyReporter extends AbstractPrettyReporter { static { __name(this, "PrettyReporter"); } #stdout; #stderr; #interactiveManager; #interactive = false; #inspectOptions; #errorOptions; constructor(options = {}) { const { error: errorOptions, inspect: inspectOptions, ...rest } = options; super({ uppercase: { label: true, ...rest.uppercase }, ...rest }); this.#inspectOptions = { ...defaultInspectorConfig, ...inspectOptions }; this.#errorOptions = { ...errorOptions, color: { fileLine: green, hint: cyan, marker: red, message: red, method: greenBright, title: red } }; this.#stdout = stdout; this.#stderr = stderr; } setStdout(stdout_) { this.#stdout = stdout_; } setStderr(stderr_) { this.#stderr = stderr_; } setInteractiveManager(manager) { this.#interactiveManager = manager; } setIsInteractive(interactive) { this.#interactive = interactive; } log(meta) { this._log(this._formatMessage(meta), meta.type.level); } // eslint-disable-next-line sonarjs/cognitive-complexity _formatMessage(data) { const { columns } = terminalSize(); let size = columns; if (typeof this._styles.messageLength === "number") { size = this._styles.messageLength; } const { badge, context, date, error, file, groups, label, message, prefix, repeated, scope, suffix, traceError, type } = data; const { color } = this._loggerTypes[type.name]; const colorized = color ? colorize[color] : white; const groupSpaces = groups.map(() => " ").join(""); const items = []; if (groups.length > 0) { items.push(groupSpaces + grey("[" + groups.at(-1) + "]") + " "); } if (date) { items.push(grey(this._styles.dateFormatter(typeof date === "string" ? new Date(date) : date)) + " "); } if (badge) { items.push(colorized(badge)); } else { const longestBadge = getLongestBadge(this._loggerTypes); if (longestBadge.length > 0) { items.push(grey(".".repeat(longestBadge.length)) + " "); } } const longestLabel = getLongestLabel(this._loggerTypes); if (label) { items.push(colorized(formatLabel(label, this._styles)) + " ", grey(".".repeat(longestLabel.length - stringLength(label)))); } else { items.push(grey(".".repeat(longestLabel.length + 2))); } if (repeated) { items.push(bgGrey.white("[" + repeated + "x]") + " "); } if (Array.isArray(scope) && scope.length > 0) { items.push(" " + grey("[" + scope.join(" > ") + "]") + " "); } if (prefix) { items.push( grey( (Array.isArray(scope) && scope.length > 0 ? ". " : " ") + "[" + (this._styles.underline.prefix ? underline(prefix) : prefix) + "]" ) + " " ); } const titleSize = stringLength(items.join(" ")); if (file) { const fileMessage = file.name + (file.line ? ":" + file.line : ""); const fileMessageSize = stringLength(fileMessage); if (fileMessageSize + titleSize + 2 > size) { items.push(grey(" " + fileMessage)); } else { items.push(grey(".".repeat(size - titleSize - fileMessageSize - 2) + " " + fileMessage)); } } else { items.push(grey(".".repeat(size - titleSize - 1))); } if (items.length > 0) { items.push("\n\n"); } if (message !== EMPTY_SYMBOL) { const formattedMessage = typeof message === "string" ? message : inspect(message, this.#inspectOptions); items.push( groupSpaces + wrapAnsi(formattedMessage, size - 3, { hard: true, trim: false, wordWrap: true }) ); } if (context) { let hasError = false; items.push( ...context.map((value) => { if (value instanceof Error) { hasError = true; return "\n\n" + renderError(value, { ...this.#errorOptions, filterStacktrace: pailFileFilter, prefix: groupSpaces }); } if (typeof value === "object") { return " " + inspect(value, this.#inspectOptions); } const newValue = (hasError ? "\n\n" : " ") + value; hasError = false; return newValue; }) ); } if (error) { items.push( renderError(error, { ...this.#errorOptions, filterStacktrace: pailFileFilter, prefix: groupSpaces }) ); } if (traceError) { items.push( "\n\n" + renderError(traceError, { ...this.#errorOptions, filterStacktrace: pailFileFilter, hideErrorCauseCodeView: true, hideErrorCodeView: true, hideErrorErrorsCodeView: true, hideMessage: true, prefix: groupSpaces }) ); } if (suffix) { items.push("\n", groupSpaces + grey(this._styles.underline.suffix ? underline(suffix) : suffix)); } return items.join("") + "\n"; } _log(message, logLevel) { const streamType = ["error", "trace", "warn"].includes(logLevel) ? "stderr" : "stdout"; const stream = streamType === "stderr" ? this.#stderr : this.#stdout; if (this.#interactive && this.#interactiveManager !== void 0 && stream.isTTY) { this.#interactiveManager.update(streamType, message.split("\n"), 0); } else { writeStream(message + "\n", stream); } } } export { PrettyReporter };