UNPKG

ng2-logger

Version:

isomorphic logger for browser/server in typescript

310 lines 8.54 kB
//#region imports import chalk from 'chalk'; // @backend import * as stringify from 'json-stringify-safe'; import { Helpers__NS__contain, Helpers__NS__error, Helpers__NS__info, Helpers__NS__log, Helpers__NS__success, Helpers__NS__taskDone, Helpers__NS__taskStarted, Helpers__NS__warn, UtilsOs__NS__isNode } from 'tnp-core/lib-prod'; //#region @backend const randomcolor = require('randomcolor').default ?? require('randomcolor'); //#endregion //#endregion //#region level export var Level; (function (Level) { Level[Level["DATA"] = 0] = "DATA"; Level[Level["INFO"] = 1] = "INFO"; Level[Level["WARN"] = 2] = "WARN"; Level[Level["ERROR"] = 3] = "ERROR"; Level[Level["SUCCESS"] = 4] = "SUCCESS"; Level[Level["TASK_STARTED"] = 5] = "TASK_STARTED"; Level[Level["TASK_DONE"] = 6] = "TASK_DONE"; })(Level || (Level = {})); //#endregion //#region constants export const LevelKey = { [Level.DATA]: 'data', [Level.INFO]: 'info', [Level.WARN]: 'warn', [Level.ERROR]: 'error', [Level.SUCCESS]: 'success', [Level.TASK_STARTED]: 'taskstarted', [Level.TASK_DONE]: 'taskdone', }; export const LevelOrder = [ LevelKey[Level.DATA], LevelKey[Level.TASK_STARTED], LevelKey[Level.TASK_DONE], LevelKey[Level.INFO], LevelKey[Level.SUCCESS], LevelKey[Level.WARN], LevelKey[Level.ERROR], ]; const levelIcon = { [Level.INFO]: 'ℹ️', [Level.ERROR]: '❌', [Level.WARN]: '⚠️', [Level.SUCCESS]: '✅', [Level.TASK_STARTED]: '🚀', [Level.TASK_DONE]: '🏁', [Level.DATA]: '', }; //#endregion //#region log namespace //namespace Log //#region internal state const instances = new Map(); let originalConsole = null; let permanentlyDisabled = false; const consoleMethods = ['log', 'info', 'warn', 'error']; let globalLevel = null; //#endregion //#region settings export const Log__NS__settings = { mutedModules: [], showTimestamp: false, }; //#endregion //#region helpers const isMutedModule = (moduleName) => { if (Log__NS__settings.mutedModules.length === 0) return false; return !Helpers__NS__contain(Log__NS__settings.mutedModules, moduleName); }; //#endregion //#region public api export const Log__NS__create = (moduleName, ...level) => { const log = new Logger(moduleName, getRandomColor(), level, isMutedModule(moduleName), undefined); instances.set(moduleName, log); return log; }; export const Log__NS__setGlobalLevel = (level) => { globalLevel = level; }; export const Log__NS__onlyLevel = (...levels) => { instances.forEach(instance => { instance.allowed = levels; }); }; export const Log__NS__onlyModules = (...modules) => { instances.forEach(instance => { const moduleName = instance.moduleName; const isAllowed = modules.some(m => { if (typeof m === 'string') { return m === moduleName; } if (m instanceof RegExp) { return m.test(moduleName); } return false; }); // mute if NOT allowed instance.isMuted = !isAllowed; }); }; export const Log__NS__disableAllLogsPermanetly = () => { if (permanentlyDisabled) return; if (!originalConsole) { originalConsole = {}; consoleMethods.forEach(m => { originalConsole[m] = console[m]; }); } consoleMethods.forEach(m => { console[m] = () => { }; }); permanentlyDisabled = true; }; export const Log__NS__disableAllLogs = () => { if (permanentlyDisabled) return; if (!originalConsole) { originalConsole = {}; consoleMethods.forEach(m => { originalConsole[m] = console[m]; }); } consoleMethods.forEach(m => { console[m] = () => { }; }); }; export const Log__NS__enableAllLogs = () => { if (permanentlyDisabled) return; if (!originalConsole) return; consoleMethods.forEach(m => { if (originalConsole && originalConsole[m]) { console[m] = originalConsole[m]; } }); }; //#endregion //#region logger class class Logger { moduleName; color; allowed; isMuted; moduleWidth; constructor(moduleName, color, allowed, isMuted, /** * Set how much characters in terminal/console * your module name should take */ moduleWidth) { this.moduleName = moduleName; this.color = color; this.allowed = allowed; this.isMuted = isMuted; this.moduleWidth = moduleWidth; this.createLevelMethod(Level.DATA); this.createLevelMethod(Level.DATA, 'd'); this.createLevelMethod(Level.INFO); this.createLevelMethod(Level.INFO, 'i'); this.createLevelMethod(Level.WARN); this.createLevelMethod(Level.WARN, 'w'); this.createLevelMethod(Level.ERROR); this.createLevelMethod(Level.ERROR, 'er'); this.createLevelMethod(Level.SUCCESS); this.createLevelMethod(Level.TASK_STARTED); this.createLevelMethod(Level.TASK_DONE); } setLevel(l) { this.allowed = [l]; return this; } mute() { this.isMuted = true; return this; } logOnlyWhen(expression) { this.isMuted = typeof expression === 'function' ? !expression() : !expression; } createLevelMethod(level, overrideMethodName) { const methodName = overrideMethodName ? overrideMethodName : LevelKey[level]; this[methodName] = (message, ...data) => { if (this.isMuted) return this; if (globalLevel !== null && level < globalLevel) { return this; } if (this.allowed.length === 0 || Helpers__NS__contain(this.allowed, level)) { displayMsg(message, data.length === 0 ? undefined : data, this.moduleName, this.color, level, this.moduleWidth, permanentlyDisabled); } return this; }; } } //#endregion //end of namespace Log //#endregion //#region get random color const getRandomColor = () => { //#region @backend if (UtilsOs__NS__isNode) { return randomcolor({ luminosity: 'light' }); } //#endregion const letters = '0123456789ABCDEF'; return ('#' + Array.from({ length: 6 }) .map(() => letters[Math.floor(Math.random() * 16)]) .join('')); }; //#endregion //#region console log const consoleLog = (data, level) => { //#region @backend if (level === Level.INFO) Helpers__NS__info(data); else if (level === Level.ERROR) Helpers__NS__error(data, true, true); else if (level === Level.WARN) Helpers__NS__warn(data, false); else if (level === Level.SUCCESS) Helpers__NS__success(data); else if (level === Level.TASK_STARTED) Helpers__NS__taskStarted(data); else if (level === Level.TASK_DONE) Helpers__NS__taskDone(data); else Helpers__NS__log(data, 0, true); //#endregion }; //#endregion //#region display message const displayMsg = (message, params, moduleName, moduleColor, level, moduleWidth, permanentlyDisabled) => { if (permanentlyDisabled) return; if (message) { message = `${levelIcon[level]} ${message?.toString()}`; } else { message = levelIcon[level]; } const timestamp = Log__NS__settings ? `[${new Date().toISOString()}] ` : ''; if (moduleWidth) { const diff = moduleWidth - moduleName.length; if (diff > 0) { for (let i = 0; i < diff; i++) { moduleName += ' '; } } } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ //#region @backend if (UtilsOs__NS__isNode) { const header = chalk.bgHex(moduleColor)(chalk.black(moduleName)) + ' ' + chalk.dim(timestamp + message); consoleLog(header, level); if (params) { params.forEach(p => consoleLog(stringify(p, null, 2), level)); } } //#endregion }; //#endregion //# sourceMappingURL=ng2-logger.js.map