import { statSync } from "fs"; import { Dispatch } from "./Dispatch"; import { ILogItem } from "./ILogItem"; import { LogLevel } from "./LogLevel"; export class SmartDispatch extends Dispatch { process(item: ILogItem) { let origin = item.origin; if (!item.origin) { let err = new Error(); // we need to look through the stack and keep track of intermediate dispatches let stack = err.stack!.split("\n"); let i = 0; while (!stack[i].includes("at SmartDispatch.process")) i++; let src = stack[i + 2].trim(); let path = null; // now we need to format the src (at ...:..:.. or at App. ..., etc) if (src.includes("at ")) src = src.split("at ")[1]; if (src.includes(" (")) src = src.split(" (")[1]; if (src.includes(")")) src = src.split(")")[0]; let file = { path: src.split(":")[0], line: src.split(":")[1], column: src.split(":")[2], }; try { path = statSync(file.path).isFile() ? file.path : null; } catch (e) { path = null; } if (path) { // trim the path to the project root if (path.startsWith(process.cwd())) path = "." + path.slice(process.cwd().length); src = `${path}:${file.line}:${file.column}`; } origin = src; } if (!item.level) item.level = LogLevel.Trace; if (!item.timestamp) item.timestamp = new Date(); super.process({ ...item, origin }); } }