'use strict'; const internals = { kCircularString: '[Circular]', kAnsiCodes: { bold: '[1m', italics: '[3m', underline: '[4m', inverse: '[7m', strikethrough: '[9m', bold_off: '[22m', italics_off: '[23m', underline_off: '[24m', inverse_off: '[27m', strikethrough_off: '[29m', black: '[30m', red: '[31m', green: '[32m', yellow: '[33m', blue: '[34m', magenta: '[35m', cyan: '[36m', white: '[37m', default: '[39m', black_bg: '[40m', red_bg: '[41m', green_bg: '[42m', yellow_bg: '[43m', blue_bg: '[44m', magenta_bg: '[45m', cyan_bg: '[46m', white_bg: '[47m', default_bg: '[49m', reset: '[0m' }, // Get High Res time depending on platform. Currently only supporting node. getHighResTime() { return process.hrtime.bigint(); } }; // Initialise relative time. internals.initialTimestamp = BigInt(Date.now()) * 1000000n; internals.initialHighResTime = internals.getHighResTime(); /** * Container object for utilities used by loggers. * * @class Utilities */ module.exports = { /** * Returns the current timestamp in nanoseconds as a bigint. * * @function now * @memberof Utilities * @return {bigint} current time in nanoseconds, including fractions. */ now() { return internals.initialTimestamp + internals.getHighResTime() - internals.initialHighResTime; }, /** * Stringifies objects, avoiding circular references. * * @function stringify * @memberof Utilities * @param {Object} object the object to stringify * @return {String} the stringified object */ stringify(object) { const cache = new Set(); return JSON.stringify(object, (key, value) => { if (typeof value === 'bigint') { return String(value) + 'n'; } if (typeof value === 'object' && value !== null) { if (cache.has(value)) { return internals.kCircularString; } cache.add(value); } return value; }); }, /** * Given an ansi keyword, it will return the appropriate code. * * @function getAnsiCode * @memberof Utilities * @param {String} ansiString the name of the desired code * @return {String} the ansi code */ getAnsiCode(ansiString) { return internals.kAnsiCodes[ansiString] || internals.kAnsiCodes.reset; }, /** * Given a level, it will return the appropriate ansi keyword related * to it. * * @function getLevelAnsi * @memberof Utilities * @param {number} level the level of the log * @return {String} the ansi keyword */ getLevelAnsi(level) { switch (level) { case 0: case 1: case 2: case 3: return 'red'; case 4: return 'yellow'; case 5: case 6: return 'blue'; case 7: return 'green'; default: return 'default'; } } };