tslog
Version:
Extensible TypeScript Logger for Node.js and Browser.
930 lines (929 loc) • 38.9 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseLogger = exports.loggerEnvironment = void 0;
exports.createLoggerEnvironment = createLoggerEnvironment;
const urlToObj_js_1 = require("./urlToObj.js");
const metaFormatting_js_1 = require("./internal/metaFormatting.js");
const errorUtils_js_1 = require("./internal/errorUtils.js");
const formatTemplate_js_1 = require("./formatTemplate.js");
const util_inspect_polyfill_js_1 = require("./internal/util.inspect.polyfill.js");
const stackTrace_js_1 = require("./internal/stackTrace.js");
const environment_js_1 = require("./internal/environment.js");
const jsonStringifyRecursive_js_1 = require("./internal/jsonStringifyRecursive.js");
function createLoggerEnvironment() {
const runtimeInfo = detectRuntimeInfo();
const meta = createRuntimeMeta(runtimeInfo);
const usesBrowserStack = runtimeInfo.name === "browser" || runtimeInfo.name === "worker";
const callerIgnorePatterns = usesBrowserStack
? [...(0, stackTrace_js_1.getDefaultIgnorePatterns)(), /node_modules[\\/].*tslog/i]
: [...(0, stackTrace_js_1.getDefaultIgnorePatterns)(), /node:(?:internal|vm)/i, /\binternal[\\/]/i];
let cachedCwd;
const environment = {
getMeta(logLevelId, logLevelName, stackDepthLevel, hideLogPositionForPerformance, name, parentNames) {
return Object.assign({}, meta, {
name,
parentNames,
date: new Date(),
logLevelId,
logLevelName,
path: !hideLogPositionForPerformance ? environment.getCallerStackFrame(stackDepthLevel) : undefined,
});
},
getCallerStackFrame(stackDepthLevel, error = new Error()) {
const frames = (0, stackTrace_js_1.buildStackTrace)(error, (line) => parseStackLine(line));
if (frames.length === 0) {
return {};
}
const autoIndex = (0, stackTrace_js_1.findFirstExternalFrameIndex)(frames, callerIgnorePatterns);
const useManualIndex = Number.isFinite(stackDepthLevel) && stackDepthLevel >= 0;
const resolvedIndex = useManualIndex ? (0, stackTrace_js_1.clampIndex)(stackDepthLevel, frames.length) : (0, stackTrace_js_1.clampIndex)(autoIndex, frames.length);
return frames[resolvedIndex] ?? {};
},
getErrorTrace(error) {
return (0, stackTrace_js_1.buildStackTrace)(error, (line) => parseStackLine(line));
},
isError(value) {
return isNativeError(value);
},
isBuffer(value) {
return typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" ? Buffer.isBuffer(value) : false;
},
prettyFormatLogObj(maskedArgs, settings) {
return maskedArgs.reduce((result, arg) => {
if (environment.isError(arg)) {
result.errors.push(environment.prettyFormatErrorObj(arg, settings));
}
else {
result.args.push(arg);
}
return result;
}, { args: [], errors: [] });
},
prettyFormatErrorObj(error, settings) {
const stackLines = formatStackFrames(environment.getErrorTrace(error), settings);
const causeSections = (0, errorUtils_js_1.collectErrorCauses)(error).map((cause, index) => {
const header = `Caused by (${index + 1}): ${cause.name ?? "Error"}${cause.message ? `: ${cause.message}` : ""}`;
const frames = formatStackFrames((0, stackTrace_js_1.buildStackTrace)(cause, (line) => parseStackLine(line)), settings);
return [header, ...frames].join("\n");
});
const placeholderValuesError = {
errorName: ` ${error.name} `,
errorMessage: formatErrorMessage(error),
errorStack: [...stackLines, ...causeSections].join("\n"),
};
return (0, formatTemplate_js_1.formatTemplate)(settings, settings.prettyErrorTemplate, placeholderValuesError);
},
transportFormatted(logMetaMarkup, logArgs, logErrors, logMeta, settings) {
const prettyLogs = settings.stylePrettyLogs !== false;
const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
const sanitizedMetaMarkup = stripAnsi(logMetaMarkup);
const metaMarkupForText = prettyLogs ? logMetaMarkup : sanitizedMetaMarkup;
if (shouldUseCss(prettyLogs)) {
settings.prettyInspectOptions.colors = false;
const formattedArgs = formatWithOptionsSafe(settings.prettyInspectOptions, logArgs);
const cssMeta = logMeta != null ? buildCssMetaOutput(settings, logMeta) : { text: sanitizedMetaMarkup, styles: [] };
const hasCssMeta = cssMeta.text.length > 0 && cssMeta.styles.length > 0;
const metaOutput = hasCssMeta ? cssMeta.text : sanitizedMetaMarkup;
const output = metaOutput + formattedArgs + logErrorsStr;
if (hasCssMeta) {
console.log(output, ...cssMeta.styles);
}
else {
console.log(output);
}
return;
}
settings.prettyInspectOptions.colors = prettyLogs;
const formattedArgs = formatWithOptionsSafe(settings.prettyInspectOptions, logArgs);
console.log(metaMarkupForText + formattedArgs + logErrorsStr);
},
transportJSON(json) {
console.log((0, jsonStringifyRecursive_js_1.jsonStringifyRecursive)(json));
},
};
if (getNodeEnv() === "test") {
environment.__resetWorkingDirectoryCacheForTests = () => {
cachedCwd = undefined;
};
}
return environment;
function parseStackLine(line) {
return usesBrowserStack ? parseBrowserStackLine(line) : parseServerStackLine(line);
}
function parseServerStackLine(rawLine) {
if (typeof rawLine !== "string" || rawLine.length === 0) {
return undefined;
}
const trimmedLine = rawLine.trim();
if (!trimmedLine.includes(" at ") && !trimmedLine.startsWith("at ")) {
return undefined;
}
const line = trimmedLine.replace(/^at\s+/, "");
let method;
let location = line;
const methodMatch = line.match(/^(.*?)\s+\((.*)\)$/);
if (methodMatch) {
method = methodMatch[1];
location = methodMatch[2];
}
const sanitizedLocation = location.replace(/^\(/, "").replace(/\)$/, "");
const withoutQuery = sanitizedLocation.replace(/\?.*$/, "");
let fileLine;
let fileColumn;
let filePathCandidate = withoutQuery;
const segments = withoutQuery.split(":");
if (segments.length >= 3 && /^\d+$/.test(segments[segments.length - 1] ?? "")) {
fileColumn = segments.pop();
fileLine = segments.pop();
filePathCandidate = segments.join(":");
}
else if (segments.length >= 2 && /^\d+$/.test(segments[segments.length - 1] ?? "")) {
fileLine = segments.pop();
filePathCandidate = segments.join(":");
}
let normalizedPath = filePathCandidate.replace(/^file:\/\//, "");
const cwd = getWorkingDirectory();
if (cwd != null && normalizedPath.startsWith(cwd)) {
normalizedPath = normalizedPath.slice(cwd.length);
normalizedPath = normalizedPath.replace(/^[\\/]/, "");
}
if (normalizedPath.length === 0) {
normalizedPath = filePathCandidate;
}
const normalizedPathWithoutLine = normalizeFilePath(normalizedPath);
const effectivePath = normalizedPathWithoutLine.length > 0 ? normalizedPathWithoutLine : normalizedPath;
const pathSegments = effectivePath.split(/\\|\//);
const fileName = pathSegments[pathSegments.length - 1];
const fileNameWithLine = fileName && fileLine ? `${fileName}:${fileLine}` : undefined;
const filePathWithLine = effectivePath && fileLine ? `${effectivePath}:${fileLine}` : undefined;
return {
fullFilePath: sanitizedLocation,
fileName,
fileNameWithLine,
fileColumn,
fileLine,
filePath: effectivePath,
filePathWithLine,
method,
};
}
function parseBrowserStackLine(line) {
const href = globalThis.location?.origin;
if (line == null) {
return undefined;
}
const match = line.match(BROWSER_PATH_REGEX);
if (!match) {
return undefined;
}
const filePath = match[1]?.replace(/\?.*$/, "");
if (filePath == null) {
return undefined;
}
const pathParts = filePath.split("/");
const fileLine = match[2];
const fileColumn = match[3];
const fileName = pathParts[pathParts.length - 1];
return {
fullFilePath: href ? `${href}${filePath}` : filePath,
fileName,
fileNameWithLine: fileName && fileLine ? `${fileName}:${fileLine}` : undefined,
fileColumn,
fileLine,
filePath,
filePathWithLine: fileLine ? `${filePath}:${fileLine}` : undefined,
method: undefined,
};
}
function formatStackFrames(frames, settings) {
return frames.map((stackFrame) => (0, formatTemplate_js_1.formatTemplate)(settings, settings.prettyErrorStackTemplate, { ...stackFrame }, true));
}
function formatErrorMessage(error) {
return Object.getOwnPropertyNames(error)
.filter((key) => key !== "stack" && key !== "cause")
.reduce((result, key) => {
const value = error[key];
if (typeof value === "function") {
return result;
}
result.push(String(value));
return result;
}, [])
.join(", ");
}
function shouldUseCss(prettyLogs) {
return prettyLogs && (runtimeInfo.name === "browser" || runtimeInfo.name === "worker") && (0, environment_js_1.consoleSupportsCssStyling)();
}
function stripAnsi(value) {
return value.replace(ANSI_REGEX, "");
}
function buildCssMetaOutput(settings, metaValue) {
if (metaValue == null) {
return { text: "", styles: [] };
}
const { template, placeholders } = (0, metaFormatting_js_1.buildPrettyMeta)(settings, metaValue);
const parts = [];
const styles = [];
let lastIndex = 0;
const placeholderRegex = /{{(.+?)}}/g;
let match;
while ((match = placeholderRegex.exec(template)) != null) {
if (match.index > lastIndex) {
parts.push(template.slice(lastIndex, match.index));
}
const key = match[1];
const rawValue = placeholders[key] != null ? String(placeholders[key]) : "";
const tokens = collectStyleTokens(settings.prettyLogStyles?.[key], rawValue);
const css = tokensToCss(tokens);
if (css.length > 0) {
parts.push(`%c${rawValue}%c`);
styles.push(css, "");
}
else {
parts.push(rawValue);
}
lastIndex = placeholderRegex.lastIndex;
}
if (lastIndex < template.length) {
parts.push(template.slice(lastIndex));
}
return {
text: parts.join(""),
styles,
};
}
function collectStyleTokens(style, value) {
if (style == null) {
return [];
}
if (typeof style === "string") {
return [style];
}
if (Array.isArray(style)) {
return style.flatMap((token) => collectStyleTokens(token, value));
}
if (typeof style === "object") {
const normalizedValue = value.trim();
const nextStyle = style[normalizedValue] ?? style["*"];
if (nextStyle == null) {
return [];
}
return collectStyleTokens(nextStyle, value);
}
return [];
}
function tokensToCss(tokens) {
const seen = new Set();
const cssParts = [];
for (const token of tokens) {
const css = styleTokenToCss(token);
if (css != null && css.length > 0 && !seen.has(css)) {
seen.add(css);
cssParts.push(css);
}
}
return cssParts.join("; ");
}
function styleTokenToCss(token) {
const color = COLOR_TOKENS[token];
if (color != null) {
return `color: ${color}`;
}
const background = BACKGROUND_TOKENS[token];
if (background != null) {
return `background-color: ${background}`;
}
switch (token) {
case "bold":
return "font-weight: bold";
case "dim":
return "opacity: 0.75";
case "italic":
return "font-style: italic";
case "underline":
return "text-decoration: underline";
case "overline":
return "text-decoration: overline";
case "inverse":
return "filter: invert(1)";
case "hidden":
return "visibility: hidden";
case "strikethrough":
return "text-decoration: line-through";
default:
return undefined;
}
}
function getWorkingDirectory() {
if (cachedCwd === undefined) {
cachedCwd = (0, environment_js_1.safeGetCwd)() ?? null;
}
return cachedCwd ?? undefined;
}
function shouldCaptureHostname() {
return runtimeInfo.name === "node" || runtimeInfo.name === "deno" || runtimeInfo.name === "bun";
}
function shouldCaptureRuntimeVersion() {
return runtimeInfo.name === "node" || runtimeInfo.name === "deno" || runtimeInfo.name === "bun";
}
function createRuntimeMeta(info) {
if (info.name === "browser" || info.name === "worker") {
return {
runtime: info.name,
browser: info.userAgent,
};
}
const metaStatic = {
runtime: info.name,
};
if (shouldCaptureRuntimeVersion()) {
metaStatic.runtimeVersion = info.version ?? "unknown";
}
if (shouldCaptureHostname()) {
metaStatic.hostname = info.hostname ?? "unknown";
}
return metaStatic;
}
function formatWithOptionsSafe(options, args) {
try {
return (0, util_inspect_polyfill_js_1.formatWithOptions)(options, ...args);
}
catch {
return args.map(stringifyFallback).join(" ");
}
}
function stringifyFallback(value) {
if (typeof value === "string") {
return value;
}
try {
return JSON.stringify(value);
}
catch {
return String(value);
}
}
function normalizeFilePath(value) {
if (typeof value !== "string" || value.length === 0) {
return value;
}
const replaced = value.replace(/\\+/g, "\\").replace(/\\/g, "/");
const hasRootDoubleSlash = replaced.startsWith("//");
const hasLeadingSlash = replaced.startsWith("/") && !hasRootDoubleSlash;
const driveMatch = replaced.match(/^[A-Za-z]:/);
const drivePrefix = driveMatch ? driveMatch[0] : "";
const withoutDrive = drivePrefix ? replaced.slice(drivePrefix.length) : replaced;
const segments = withoutDrive.split("/");
const normalizedSegments = [];
for (const segment of segments) {
if (segment === "" || segment === ".") {
continue;
}
if (segment === "..") {
if (normalizedSegments.length > 0) {
normalizedSegments.pop();
}
continue;
}
normalizedSegments.push(segment);
}
let normalized = normalizedSegments.join("/");
if (hasRootDoubleSlash) {
normalized = `//${normalized}`;
}
else if (hasLeadingSlash) {
normalized = `/${normalized}`;
}
else if (drivePrefix !== "") {
normalized = `${drivePrefix}${normalized.length > 0 ? `/${normalized}` : ""}`;
}
if (normalized.length === 0) {
return value;
}
return normalized;
}
function detectRuntimeInfo() {
if ((0, environment_js_1.isBrowserEnvironment)()) {
const navigatorObj = globalThis.navigator;
return {
name: "browser",
userAgent: navigatorObj?.userAgent,
};
}
const globalScope = globalThis;
if (typeof globalScope.importScripts === "function") {
return {
name: "worker",
userAgent: globalScope.navigator?.userAgent,
};
}
const globalAny = globalThis;
if (globalAny.Bun != null) {
const bunVersion = globalAny.Bun.version;
return {
name: "bun",
version: bunVersion != null ? `bun/${bunVersion}` : undefined,
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location),
};
}
if (globalAny.Deno != null) {
const denoHostname = resolveDenoHostname(globalAny.Deno);
const denoVersion = globalAny.Deno?.version?.deno;
return {
name: "deno",
version: denoVersion != null ? `deno/${denoVersion}` : undefined,
hostname: denoHostname ?? getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location),
};
}
if (globalAny.process?.versions?.node != null || globalAny.process?.version != null) {
return {
name: "node",
version: globalAny.process?.versions?.node ?? globalAny.process?.version,
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location),
};
}
if (globalAny.process != null) {
return {
name: "node",
version: "unknown",
hostname: getEnvironmentHostname(globalAny.process, globalAny.Deno, globalAny.Bun, globalAny.location),
};
}
return {
name: "unknown",
};
}
function getEnvironmentHostname(nodeProcess, deno, bun, location) {
const processHostname = nodeProcess?.env?.HOSTNAME ?? nodeProcess?.env?.HOST ?? nodeProcess?.env?.COMPUTERNAME;
if (processHostname != null && processHostname.length > 0) {
return processHostname;
}
const bunHostname = bun?.env?.HOSTNAME ?? bun?.env?.HOST ?? bun?.env?.COMPUTERNAME;
if (bunHostname != null && bunHostname.length > 0) {
return bunHostname;
}
try {
const denoEnvGet = deno?.env?.get;
if (typeof denoEnvGet === "function") {
const value = denoEnvGet("HOSTNAME");
if (value != null && value.length > 0) {
return value;
}
}
}
catch {
}
if (location?.hostname != null && location.hostname.length > 0) {
return location.hostname;
}
return undefined;
}
function resolveDenoHostname(deno) {
try {
if (typeof deno?.hostname === "function") {
const value = deno.hostname();
if (value != null && value.length > 0) {
return value;
}
}
}
catch {
}
const locationHostname = globalThis.location?.hostname;
if (locationHostname != null && locationHostname.length > 0) {
return locationHostname;
}
return undefined;
}
function getNodeEnv() {
const globalProcess = globalThis?.process;
return globalProcess?.env?.NODE_ENV;
}
function isNativeError(value) {
if (value instanceof Error) {
return true;
}
if (value != null && typeof value === "object") {
const objectTag = Object.prototype.toString.call(value);
if (/\[object .*Error\]/.test(objectTag)) {
return true;
}
const name = value.name;
if (typeof name === "string" && name.endsWith("Error")) {
return true;
}
}
return false;
}
}
const ANSI_REGEX = /\u001b\[[0-9;]*m/g;
const COLOR_TOKENS = {
black: "#000000",
red: "#ef5350",
green: "#66bb6a",
yellow: "#fdd835",
blue: "#42a5f5",
magenta: "#ab47bc",
cyan: "#26c6da",
white: "#fafafa",
blackBright: "#424242",
redBright: "#ff7043",
greenBright: "#81c784",
yellowBright: "#ffe082",
blueBright: "#64b5f6",
magentaBright: "#ce93d8",
cyanBright: "#4dd0e1",
whiteBright: "#ffffff",
};
const BACKGROUND_TOKENS = {
bgBlack: "#000000",
bgRed: "#ef5350",
bgGreen: "#66bb6a",
bgYellow: "#fdd835",
bgBlue: "#42a5f5",
bgMagenta: "#ab47bc",
bgCyan: "#26c6da",
bgWhite: "#fafafa",
bgBlackBright: "#424242",
bgRedBright: "#ff7043",
bgGreenBright: "#81c784",
bgYellowBright: "#ffe082",
bgBlueBright: "#64b5f6",
bgMagentaBright: "#ce93d8",
bgCyanBright: "#4dd0e1",
bgWhiteBright: "#ffffff",
};
const BROWSER_PATH_REGEX = /(?:(?:file|https?|global code|[^@]+)@)?(?:file:)?((?:\/[^:/]+){2,})(?::(\d+))?(?::(\d+))?/;
const runtime = createLoggerEnvironment();
exports.loggerEnvironment = runtime;
__exportStar(require("./interfaces.js"), exports);
class BaseLogger {
constructor(settings, logObj, stackDepthLevel = Number.NaN) {
this.logObj = logObj;
this.stackDepthLevel = stackDepthLevel;
this.runtime = runtime;
this.maxErrorCauseDepth = 5;
this.settings = {
type: settings?.type ?? "pretty",
name: settings?.name,
parentNames: settings?.parentNames,
minLevel: settings?.minLevel ?? 0,
argumentsArrayName: settings?.argumentsArrayName,
hideLogPositionForProduction: settings?.hideLogPositionForProduction ?? false,
prettyLogTemplate: settings?.prettyLogTemplate ??
"{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}\t{{logLevelName}}\t{{filePathWithLine}}{{nameWithDelimiterPrefix}}\t",
prettyErrorTemplate: settings?.prettyErrorTemplate ?? "\n{{errorName}} {{errorMessage}}\nerror stack:\n{{errorStack}}",
prettyErrorStackTemplate: settings?.prettyErrorStackTemplate ?? " • {{fileName}}\t{{method}}\n\t{{filePathWithLine}}",
prettyErrorParentNamesSeparator: settings?.prettyErrorParentNamesSeparator ?? ":",
prettyErrorLoggerNameDelimiter: settings?.prettyErrorLoggerNameDelimiter ?? "\t",
stylePrettyLogs: settings?.stylePrettyLogs ?? true,
prettyLogTimeZone: settings?.prettyLogTimeZone ?? "UTC",
prettyLogStyles: settings?.prettyLogStyles ?? {
logLevelName: {
"*": ["bold", "black", "bgWhiteBright", "dim"],
SILLY: ["bold", "white"],
TRACE: ["bold", "whiteBright"],
DEBUG: ["bold", "green"],
INFO: ["bold", "blue"],
WARN: ["bold", "yellow"],
ERROR: ["bold", "red"],
FATAL: ["bold", "redBright"],
},
dateIsoStr: "white",
filePathWithLine: "white",
name: ["white", "bold"],
nameWithDelimiterPrefix: ["white", "bold"],
nameWithDelimiterSuffix: ["white", "bold"],
errorName: ["bold", "bgRedBright", "whiteBright"],
fileName: ["yellow"],
fileNameWithLine: "white",
},
prettyInspectOptions: settings?.prettyInspectOptions ?? {
colors: true,
compact: false,
depth: Infinity,
},
metaProperty: settings?.metaProperty ?? "_meta",
maskPlaceholder: settings?.maskPlaceholder ?? "[***]",
maskValuesOfKeys: settings?.maskValuesOfKeys ?? ["password"],
maskValuesOfKeysCaseInsensitive: settings?.maskValuesOfKeysCaseInsensitive ?? false,
maskValuesRegEx: settings?.maskValuesRegEx,
prefix: [...(settings?.prefix ?? [])],
attachedTransports: [...(settings?.attachedTransports ?? [])],
overwrite: {
mask: settings?.overwrite?.mask,
toLogObj: settings?.overwrite?.toLogObj,
addMeta: settings?.overwrite?.addMeta,
addPlaceholders: settings?.overwrite?.addPlaceholders,
formatMeta: settings?.overwrite?.formatMeta,
formatLogObj: settings?.overwrite?.formatLogObj,
transportFormatted: settings?.overwrite?.transportFormatted,
transportJSON: settings?.overwrite?.transportJSON,
},
};
this.captureStackForMeta = this._shouldCaptureStack();
}
log(logLevelId, logLevelName, ...args) {
if (logLevelId < this.settings.minLevel) {
return;
}
const resolvedArgs = this._resolveLogArguments(args);
const logArgs = [...this.settings.prefix, ...resolvedArgs];
const maskedArgs = this.settings.overwrite?.mask != null
? this.settings.overwrite?.mask(logArgs)
: this.settings.maskValuesOfKeys != null && this.settings.maskValuesOfKeys.length > 0
? this._mask(logArgs)
: logArgs;
const thisLogObj = this.logObj != null ? this._recursiveCloneAndExecuteFunctions(this.logObj) : undefined;
const logObj = this.settings.overwrite?.toLogObj != null ? this.settings.overwrite?.toLogObj(maskedArgs, thisLogObj) : this._toLogObj(maskedArgs, thisLogObj);
const logObjWithMeta = this.settings.overwrite?.addMeta != null
? this.settings.overwrite?.addMeta(logObj, logLevelId, logLevelName)
: this._addMetaToLogObj(logObj, logLevelId, logLevelName);
const logMeta = logObjWithMeta?.[this.settings.metaProperty];
let logMetaMarkup;
let logArgsAndErrorsMarkup = undefined;
if (this.settings.overwrite?.formatMeta != null) {
logMetaMarkup = this.settings.overwrite?.formatMeta(logObjWithMeta?.[this.settings.metaProperty]);
}
if (this.settings.overwrite?.formatLogObj != null) {
logArgsAndErrorsMarkup = this.settings.overwrite?.formatLogObj(maskedArgs, this.settings);
}
if (this.settings.type === "pretty") {
logMetaMarkup = logMetaMarkup ?? this._prettyFormatLogObjMeta(logObjWithMeta?.[this.settings.metaProperty]);
logArgsAndErrorsMarkup = logArgsAndErrorsMarkup ?? runtime.prettyFormatLogObj(maskedArgs, this.settings);
}
if (logMetaMarkup != null && logArgsAndErrorsMarkup != null) {
if (this.settings.overwrite?.transportFormatted != null) {
const transport = this.settings.overwrite.transportFormatted;
const declaredParams = transport.length;
if (declaredParams < 4) {
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors);
}
else if (declaredParams === 4) {
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta);
}
else {
transport(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta, this.settings);
}
}
else {
runtime.transportFormatted(logMetaMarkup, logArgsAndErrorsMarkup.args, logArgsAndErrorsMarkup.errors, logMeta, this.settings);
}
}
else {
if (this.settings.overwrite?.transportJSON != null) {
this.settings.overwrite.transportJSON(logObjWithMeta);
}
else if (this.settings.type !== "hidden") {
runtime.transportJSON(logObjWithMeta);
}
}
if (this.settings.attachedTransports != null && this.settings.attachedTransports.length > 0) {
this.settings.attachedTransports.forEach((transportLogger) => {
transportLogger(logObjWithMeta);
});
}
return logObjWithMeta;
}
attachTransport(transportLogger) {
this.settings.attachedTransports.push(transportLogger);
}
getSubLogger(settings, logObj) {
const subLoggerSettings = {
...this.settings,
...settings,
parentNames: this.settings?.parentNames != null && this.settings?.name != null
? [...this.settings.parentNames, this.settings.name]
: this.settings?.name != null
? [this.settings.name]
: undefined,
prefix: [...this.settings.prefix, ...(settings?.prefix ?? [])],
};
const subLogger = new this.constructor(subLoggerSettings, logObj ?? this.logObj, this.stackDepthLevel);
return subLogger;
}
_mask(args) {
const maskKeys = this._getMaskKeys();
return args?.map((arg) => {
return this._recursiveCloneAndMaskValuesOfKeys(arg, maskKeys);
});
}
_getMaskKeys() {
const maskKeys = this.settings.maskValuesOfKeys ?? [];
const signature = maskKeys.map(String).join("|");
if (this.settings.maskValuesOfKeysCaseInsensitive === true) {
if (this.maskKeysCache?.source === maskKeys && this.maskKeysCache.caseInsensitive === true && this.maskKeysCache.signature === signature) {
return this.maskKeysCache.normalized;
}
const normalized = maskKeys.map((key) => (typeof key === "string" ? key.toLowerCase() : String(key).toLowerCase()));
this.maskKeysCache = {
source: maskKeys,
caseInsensitive: true,
normalized,
signature,
};
return normalized;
}
this.maskKeysCache = {
source: maskKeys,
caseInsensitive: false,
normalized: maskKeys,
signature,
};
return maskKeys;
}
_resolveLogArguments(args) {
if (args.length === 1 && typeof args[0] === "function") {
const candidate = args[0];
if (candidate.length === 0) {
const result = candidate();
return Array.isArray(result) ? result : [result];
}
}
return args;
}
_recursiveCloneAndMaskValuesOfKeys(source, keys, seen = []) {
if (seen.includes(source)) {
return { ...source };
}
if (typeof source === "object" && source !== null) {
seen.push(source);
}
if (runtime.isError(source) || runtime.isBuffer(source)) {
return source;
}
else if (source instanceof Map) {
return new Map(source);
}
else if (source instanceof Set) {
return new Set(source);
}
else if (Array.isArray(source)) {
return source.map((item) => this._recursiveCloneAndMaskValuesOfKeys(item, keys, seen));
}
else if (source instanceof Date) {
return new Date(source.getTime());
}
else if (source instanceof URL) {
return (0, urlToObj_js_1.urlToObject)(source);
}
else if (source !== null && typeof source === "object") {
const baseObject = runtime.isError(source) ? this._cloneError(source) : Object.create(Object.getPrototypeOf(source));
return Object.getOwnPropertyNames(source).reduce((o, prop) => {
const lookupKey = this.settings?.maskValuesOfKeysCaseInsensitive !== true
? prop
: typeof prop === "string"
? prop.toLowerCase()
: String(prop).toLowerCase();
o[prop] = keys.includes(lookupKey)
? this.settings.maskPlaceholder
: (() => {
try {
return this._recursiveCloneAndMaskValuesOfKeys(source[prop], keys, seen);
}
catch {
return null;
}
})();
return o;
}, baseObject);
}
else {
if (typeof source === "string") {
let modifiedSource = source;
for (const regEx of this.settings?.maskValuesRegEx || []) {
modifiedSource = modifiedSource.replace(regEx, this.settings?.maskPlaceholder || "");
}
return modifiedSource;
}
return source;
}
}
_recursiveCloneAndExecuteFunctions(source, seen = []) {
if (this.isObjectOrArray(source) && seen.includes(source)) {
return this.shallowCopy(source);
}
if (this.isObjectOrArray(source)) {
seen.push(source);
}
if (Array.isArray(source)) {
return source.map((item) => this._recursiveCloneAndExecuteFunctions(item, seen));
}
else if (source instanceof Date) {
return new Date(source.getTime());
}
else if (this.isObject(source)) {
return Object.getOwnPropertyNames(source).reduce((o, prop) => {
const descriptor = Object.getOwnPropertyDescriptor(source, prop);
if (descriptor) {
Object.defineProperty(o, prop, descriptor);
const value = source[prop];
o[prop] = typeof value === "function" ? value() : this._recursiveCloneAndExecuteFunctions(value, seen);
}
return o;
}, Object.create(Object.getPrototypeOf(source)));
}
else {
return source;
}
}
isObjectOrArray(value) {
return typeof value === "object" && value !== null;
}
isObject(value) {
return typeof value === "object" && !Array.isArray(value) && value !== null;
}
shallowCopy(source) {
if (Array.isArray(source)) {
return [...source];
}
else {
return { ...source };
}
}
_toLogObj(args, clonedLogObj = {}) {
args = args?.map((arg) => (runtime.isError(arg) ? this._toErrorObject(arg) : arg));
if (this.settings.argumentsArrayName == null) {
if (args.length === 1 && !Array.isArray(args[0]) && runtime.isBuffer(args[0]) !== true && !(args[0] instanceof Date)) {
clonedLogObj = typeof args[0] === "object" && args[0] != null ? { ...args[0], ...clonedLogObj } : { 0: args[0], ...clonedLogObj };
}
else {
clonedLogObj = { ...clonedLogObj, ...args };
}
}
else {
clonedLogObj = {
...clonedLogObj,
[this.settings.argumentsArrayName]: args,
};
}
return clonedLogObj;
}
_cloneError(error) {
const cloned = new error.constructor();
Object.getOwnPropertyNames(error).forEach((key) => {
cloned[key] = error[key];
});
return cloned;
}
_toErrorObject(error, depth = 0, seen = new Set()) {
if (!seen.has(error)) {
seen.add(error);
}
const errorObject = {
nativeError: error,
name: error.name ?? "Error",
message: error.message,
stack: runtime.getErrorTrace(error),
};
if (depth >= this.maxErrorCauseDepth) {
return errorObject;
}
const causeValue = error.cause;
if (causeValue != null) {
const normalizedCause = (0, errorUtils_js_1.toError)(causeValue);
if (!seen.has(normalizedCause)) {
errorObject.cause = this._toErrorObject(normalizedCause, depth + 1, seen);
}
}
return errorObject;
}
_addMetaToLogObj(logObj, logLevelId, logLevelName) {
return {
...logObj,
[this.settings.metaProperty]: runtime.getMeta(logLevelId, logLevelName, this.stackDepthLevel, !this.captureStackForMeta, this.settings.name, this.settings.parentNames),
};
}
_shouldCaptureStack() {
if (this.settings.hideLogPositionForProduction) {
return false;
}
if (this.settings.type === "json") {
return true;
}
const template = this.settings.prettyLogTemplate ?? "";
const stackPlaceholders = /{{\s*(file(Name|Path|Line|PathWithLine|NameWithLine)|fullFilePath)\s*}}/;
if (stackPlaceholders.test(template)) {
return true;
}
return false;
}
_prettyFormatLogObjMeta(logObjMeta) {
return (0, metaFormatting_js_1.buildPrettyMeta)(this.settings, logObjMeta).text;
}
}
exports.BaseLogger = BaseLogger;