UNPKG

mwn

Version:

JavaScript & TypeScript MediaWiki bot framework for Node.js

195 lines 5.16 kB
"use strict"; /** * semlog * A semantic logger that colors and formats messages automatically according to the content * * Adapted from https://github.com/Fannon/semlog * * @author Simon Heimler * @author Siddharth VP - removed use of globals and adapted to TypeScript, * also removed some unnecessary features like in-memory log retention * and keeping track of statistics */ Object.defineProperty(exports, "__esModule", { value: true }); exports.updateLoggingConfig = updateLoggingConfig; exports.log = log; exports.message = message; exports.debug = debug; exports.error = error; exports.colorize = colorize; exports.pad = pad; exports.getDateArray = getDateArray; exports.humanDate = humanDate; const util = require("node:util"); const chalk = require("chalk"); const logConfig = { printDebug: true, printVerbose: true, stream: process.stdout, }; /** * Configure global logging options. * * Note: To suppress API warnings, use `suppressAPIWarnings` flag in bot instance options instead. */ function updateLoggingConfig(options) { Object.assign(logConfig, options); } /** * Custom Logging function * * Writes logs to console or file, stringifies objects first * * @param obj */ function log(obj) { if (obj && obj instanceof Error) { error(obj); } else if (obj && typeof obj === 'object') { debug(obj); } else { message(obj); } } // Functions below are exported only for unit testing function message(msg) { if (typeof msg !== 'string') { try { msg = '' + JSON.stringify(msg); } catch (e) { msg = `[E] [Logger] Could not stringify given parameter: ${e.message}`; } } msg = colorize(msg); if (msg.trim && msg.trim().length > 0) { msg = colorize('[' + humanDate() + '] ', 'gray') + msg; } if (!logConfig.printVerbose && msg.indexOf('[V]') >= 0) { // Supressing output of verbose message } else if (!logConfig.printDebug && msg.indexOf('[D]') >= 0) { // Supressing output of debug message } else { writeToLog(msg); } } /** * Prints out debugging information for the current model object * @param obj */ function debug(obj) { // Print indented JSON let msg = JSON.stringify(obj, null, 4); writeToLog(colorize(msg, 'gray')); } /** * Prints errors * @param obj */ function error(obj) { writeToLog(colorize('[E] ' + obj.message, 'red')); let stringified; try { stringified = JSON.stringify(obj, null, 4); } catch (e) { // Circular object? stringified = `Failed to stringify error: ${e.message}`; } writeToLog(colorize(stringified, 'gray')); if (obj.stack) { writeToLog(colorize(obj.stack, 'gray')); } } const colorMap = { '[E]': 'red', // ERROR '[W]': 'yellow', // WARNING '[?]': 'yellow', // MISSING '[S]': 'green', // SUCCESS '[i]': 'blue', // INFO '[+]': 'green', // ADDED '[-]': 'red', // REMOVED '[C]': 'cyan', // CHANGED '[U]': 'gray', // UNCHANGED '[=]': 'gray', // EQUAL '[/]': 'gray', // SKIPPED '[V]': 'magenta', // VERBOSE '[D]': 'magenta', // DEBUG '[T]': 'magenta', // TO-DO '[TODO]': 'magenta', // TO-DO }; /** * Colors the messages by searching for specific indicator strings * * @param {string} msg * @param {string} colorName * @returns {string} */ function colorize(msg, colorName) { if (logConfig.stream !== process.stdout) { return msg; } if (colorName) { return chalk[colorName](msg); } for (let [code, color] of Object.entries(colorMap)) { if (msg && msg.indexOf && msg.startsWith(code)) { return chalk[color](msg); } } return msg; } function writeToLog(message) { if (logConfig.stream === process.stdout) { console.log(message); } else { logConfig.stream.write(util.format.apply(null, [message]) + '\n'); } } /** * Pad a number with n digits * * @param {number} number number to pad * @param {number} digits number of total digits * @returns {string} */ function pad(number, digits) { return new Array(Math.max(digits - String(number).length + 1, 0)).join('0') + number; } /** * Returns an array with date / time information * Starts with year at index 0 up to index 6 for milliseconds * * @param {Date} date Optional date object. If falsy, will take current time. * @returns {Array} */ function getDateArray(date) { date = date || new Date(); return [ date.getFullYear(), pad(date.getMonth() + 1, 2), pad(date.getDate(), 2), pad(date.getHours(), 2), pad(date.getMinutes(), 2), pad(date.getSeconds(), 2), pad(date.getMilliseconds(), 2), ]; } /** * Returns nicely formatted date-time * @example 2015-02-10 16:01:12 * * @param {object} [date] * @returns {string} */ function humanDate(date) { date = date || new Date(); let d = getDateArray(date); return d[0] + '-' + d[1] + '-' + d[2] + ' ' + d[3] + ':' + d[4] + ':' + d[5]; } //# sourceMappingURL=log.js.map