@lorefnon/tslog
Version:
Extensible TypeScript Logger for Node.js and Browser.
107 lines (106 loc) • 4.1 kB
JavaScript
import { formatTemplate } from "../../formatTemplate.js";
import { formatWithOptions } from "./util.inspect.polyfil.js";
import { jsonStringifyRecursive } from "./helper.jsonStringifyRecursive.js";
export default {
getCallerStackFrame,
getErrorTrace,
getMeta,
transportJSON,
transportFormatted,
isBuffer,
isError,
prettyFormatLogObj,
prettyFormatErrorObj,
};
const meta = {
runtime: ![typeof window, typeof document].includes("undefined") ? "Browser" : "Generic",
browser: globalThis?.["navigator"]?.userAgent,
};
const pathRegex = /(?:(?:file|https?|global code|[^@]+)@)?(?:file:)?((?:\/[^:/]+){2,})(?::(\d+))?(?::(\d+))?/;
export function getMeta(logLevelId, logLevelName, stackDepthLevel, hideLogPositionForPerformance, name, parentNames) {
return Object.assign({}, meta, {
name,
parentNames,
date: new Date(),
logLevelId,
logLevelName,
path: !hideLogPositionForPerformance ? getCallerStackFrame(stackDepthLevel) : undefined,
});
}
export function getCallerStackFrame(stackDepthLevel, error = Error()) {
return stackLineToStackFrame(error?.stack?.split("\n")?.filter((line) => !line.includes("Error: "))?.[stackDepthLevel]);
}
export function getErrorTrace(error) {
return error?.stack
?.split("\n")
?.filter((line) => !line.includes("Error: "))
?.reduce((result, line) => {
result.push(stackLineToStackFrame(line));
return result;
}, []);
}
function stackLineToStackFrame(line) {
const href = globalThis?.location?.origin;
const pathResult = {
fullFilePath: undefined,
fileName: undefined,
fileNameWithLine: undefined,
fileColumn: undefined,
fileLine: undefined,
filePath: undefined,
filePathWithLine: undefined,
method: undefined,
};
if (line != null) {
const match = line.match(pathRegex);
if (match) {
pathResult.filePath = match[1].replace(/\?.*$/, "");
pathResult.fullFilePath = `${href}${pathResult.filePath}`;
const pathParts = pathResult.filePath.split("/");
pathResult.fileName = pathParts[pathParts.length - 1];
pathResult.fileLine = match[2];
pathResult.fileColumn = match[3];
pathResult.filePathWithLine = `${pathResult.filePath}:${pathResult.fileLine}`;
pathResult.fileNameWithLine = `${pathResult.fileName}:${pathResult.fileLine}`;
}
}
return pathResult;
}
export function isError(e) {
return e instanceof Error;
}
export function prettyFormatLogObj(maskedArgs, settings) {
return maskedArgs.reduce((result, arg) => {
isError(arg) ? result.errors.push(prettyFormatErrorObj(arg, settings)) : result.args.push(arg);
return result;
}, { args: [], errors: [] });
}
export function prettyFormatErrorObj(error, settings) {
const errorStackStr = getErrorTrace(error).map((stackFrame) => {
return formatTemplate(settings, settings.prettyErrorStackTemplate, { ...stackFrame }, true);
});
const placeholderValuesError = {
errorName: ` ${error.name} `,
errorMessage: Object.getOwnPropertyNames(error)
.reduce((result, key) => {
if (key !== "stack") {
result.push(error[key]);
}
return result;
}, [])
.join(", "),
errorStack: errorStackStr.join("\n"),
};
return formatTemplate(settings, settings.prettyErrorTemplate, placeholderValuesError);
}
export function transportFormatted(logMetaMarkup, logArgs, logErrors, settings) {
const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
settings.prettyInspectOptions.colors = settings.stylePrettyLogs;
console.log(logMetaMarkup + formatWithOptions(settings.prettyInspectOptions, ...logArgs) + logErrorsStr);
}
export function transportJSON(json) {
console.log(jsonStringifyRecursive(json));
}
export function isBuffer(arg) {
return arg ? false : false;
}