@visulima/pail
Version:
Highly configurable Logger for Node.js, Edge and Browser.
193 lines (190 loc) • 6.52 kB
JavaScript
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 };