import path from "path"; import { DEBUG } from "./variables"; import fs from "fs"; export type LogOptions = Omit["0"], "type">; export class Logger { public currentLogFile: string; public tag?: string; public divider: string = "\n"; private get pathToLogFolder(): string { return path.join(__dirname, "../logs"); } private get pathToCurrentLog(): string { return path.join(__dirname, "../logs", this.currentLogFile); } constructor(options?: { tag?: string; divider?: string }) { this.currentLogFile = this.createNewLogFile(); if (options === undefined) return; if (options.tag !== undefined) this.tag = options.tag; if (options.divider !== undefined) this.divider = options.divider; } private createNewLogFile() { const date = new Date().toISOString().split("T"); date[1] = date[1].split(".")[0].replaceAll(":", "-"); const fileName = `${date.join("-")}.log`; const newLogPath = path.join(this.pathToLogFolder, fileName); if (!fs.existsSync(newLogPath)) fs.writeFileSync(newLogPath, ""); const latestLogPath = path.join(this.pathToLogFolder, "./latest.log"); if (fs.existsSync(latestLogPath)) fs.writeFileSync(latestLogPath, ""); return fileName; } private toString(object: any) { if (typeof object === "object") return Object.prototype.toString.call(object); else if (Array.isArray(object)) return object.join(); else if (typeof object === "number") return object.toString(); else if (typeof object === "boolean") return object.toString(); else if (typeof object === "string") return object; return "Cannot transfrom object to string"; } private appendTextToLog(content: string) { fs.appendFileSync(this.pathToCurrentLog, content); fs.appendFileSync(path.join(this.pathToLogFolder, "./latest.log"), content); } private writeEntry( options: { tag?: string; type: "log" | "error" | "warn" | "info"; }, ...args: any ) { const strings: string[] = []; for (const argument of args) { const string = this.toString(argument); strings.push(string); } const dateString = new Date().toLocaleString(undefined, { formatMatcher: "best fit", dateStyle: "short", timeStyle: "medium", }); let string = `[${dateString}] `; const tags = [ ["LTAG", this.tag], ["TAG", options.tag], ].filter((i) => i[1] !== undefined); if (tags.length > 0) { string += "["; for (const [tagName, tag] of tags) { string += `${tagName}: ${tag}`; } string += "] "; } string += `[${options.type.toUpperCase()}] `; string += strings.join(this.divider + "\t"); string += this.divider; this.appendTextToLog(string); } public log(options?: LogOptions, ...args: any) { if (!DEBUG) console.log(...args); this.writeEntry({ type: "log", ...options }, ...args); } public error(options?: LogOptions, ...args: any) { if (!DEBUG) console.error(...args); this.writeEntry({ type: "error", ...options }, ...args); } public warn(options?: LogOptions, ...args: any) { if (!DEBUG) console.warn(...args); this.writeEntry({ type: "warn", ...options }, ...args); } public info(options?: LogOptions, ...args: any) { if (!DEBUG) console.info(...args); this.writeEntry({ type: "info", ...options }, ...args); } } export const logger = new Logger({});