import { ConsoleColor, ResultTypes } from "@business-logic/types/Enums"; export default class LoggingUtils { public static CONSOLE_WIDTH: number = 100; //public static ICON_OK: string = "✅"; public static ICON_OK: string = "\u2705"; //public static ICON_SKIP: string = "⏩"; public static ICON_SKIP: string = "\u23ED"; //public static ICON_WARNING: string = "⚠️"; public static ICON_WARNING: string = "\u26A0\uFE0F"; //public static ICON_FAIL: string = "❗"; public static ICON_FAIL: string = "\u2757"; public static log(message: string | null, color: ConsoleColor = ConsoleColor.Default): void { if (message == null) return; console.log(`${color}%s${ConsoleColor.Reset}`, message); } public static icon(value: boolean): string; public static icon(value: ResultTypes): string; public static icon(value: any): string { if (typeof value === "boolean") return value ? this.ICON_OK : this.ICON_FAIL; switch (value) { case ResultTypes.Failure: return this.ICON_FAIL; case ResultTypes.Success: return this.ICON_OK; case ResultTypes.Skipped: return this.ICON_SKIP; } return ""; } public static logFunc(name: string, value: string | null = null, result: boolean | null = null): string { let icon = this.ICON_SKIP; if (result != null) icon = result ? this.ICON_OK : this.ICON_FAIL; if (value != null) return `${this.getShortDateTime()} [${this.centerPadString(`${name}: ${this.truncateString(value)}`)}] -> ${icon}`; return `${this.getShortDateTime()} [${this.centerPadString(name)}] -> ${icon}`; } public static logValidate(text: string, success: boolean) { return `${this.getShortDateTime()} [${this.centerPadString(text)}] -> ${success ? this.ICON_OK : this.ICON_FAIL}`; } public static truncateString(value: any, maxLength: number = this.CONSOLE_WIDTH): string { let str = typeof value === 'string' ? value : String(value); str = str.replace(/\s+/g, ' ').trim(); if (str.length <= maxLength) { return str; } return str.slice(0, maxLength - 2) + '..'; } public static sanitizeFileName(input: string): string { // Remove characters that are invalid in both Windows and Linux file systems let sanitized = input.replace(/[<>:"/\\|?*\x00-\x1F]/g, ''); // Remove leading and trailing spaces and dots sanitized = sanitized.trim().replace(/^\.+|\.+$/g, ''); // Replace remaining dots and spaces with underscores sanitized = sanitized.replace(/[\s.]+/g, '_'); // Ensure the name isn't empty after sanitization if (sanitized.length === 0) { sanitized = 'unnamed'; } // Truncate to a reasonable maximum length (e.g., 255 characters) sanitized = sanitized.slice(0, 255); return sanitized; } public static replaceEmptyLinesWithMiddleDot(input: string): string { const emptyLinesRegex: RegExp = /(.+?)(\n\s*\n)+/g; return input.replace(emptyLinesRegex, (_match, line) => { return line + '·\n'; }).replace(/\n$/, ''); } private static centerPadString(str: string, length: number = this.CONSOLE_WIDTH): string { if (str.length >= length) { return this.truncateString(str); } str = this.truncateString(str); const totalPadding = length - str.length; const leftPadding = Math.ceil(totalPadding / 2); const rightPadding = Math.floor(totalPadding / 2); return ' '.repeat(leftPadding) + str + ' '.repeat(rightPadding); } private static getShortDateTime() { return new Date().toLocaleString('en-US', { year: '2-digit', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); } public static normalizeSalesForceType(input: string, prefix: string = "Apttus_Config2__", suffix: string = "__c") { let result = input; if (result.startsWith(prefix)) result = result.slice(prefix.length); if (result.endsWith(suffix)) result = result.slice(0, -suffix.length); return result; } }