/**
* @module Logger
* @category Global
* @author Alexis L. <alexis.lecomte@supinfo.com>
*/
import "colors";
/**
* Initialization option of the logger
* @typedef {Object} Logger~InitOptions
* @property {string|null} [prefix=""] - Prefix is used at the beginning of the log
* @property {string|null} [separator=" - "] - Separator is the string that separates the date from the log message
* @property {boolean} [colors=true] - Colors is used to control whether the log should have colors or not
*/
/**
* Build option of the logger
* @typedef {Object} Logger~BuildOptions
* @property {boolean} [withTime=true] - Must show time before the log message
* @property {string|null} [ip=null] - The IP address of the user who triggered this log message
* @property {Object|null} [params=null] - An object of parameters to log
* @property {boolean} [subLevel=false] - Mark this log message as a sub-level log message
*/
/**
* Logger used on top of console
* @class
* @example
* const logger = new Logger({ prefix: "@ " });
* logger.log("hi, world");
*/
export default class Logger {
#prefix = "";
#separator = " - ";
#colors = true;
/** @param {Logger~InitOptions} [options] - The initialization options of the Logger */
constructor(options = { prefix: null, separator: null, colors: true }) {
this.setPrefix(options.prefix);
this.setSeparator(options.separator);
this.enableColors(options.colors);
}
/* ---- Setters --------------------------------- */
/**
* Changes the prefix
* @function
*
* @param {string} prefix - The new prefix
* @return {void}
*/
setPrefix(prefix) { if (prefix) this.#prefix = prefix.toString(); }
/**
* Changes the separator
* @function
*
* @param {string} separator - The new separator
* @return {void}
*/
setSeparator(separator) { if (separator) this.#separator = separator.toString(); }
/**
* Used to enable or disable colors in log messages
* @function
*
* @param {boolean} [enable=true] - Enable colors?
* @return {void}
*/
enableColors(enable = true) { this.#colors = !!enable; }
/* ---- Getters --------------------------------- */
/**
* Prefix is used at the beginning of the log
* @return {string}
*/
get prefix() { return this.#prefix; }
/**
* Separator is the string that separates the date from the log message
* @return {string}
*/
get separator() { return this.#separator; }
/**
* Colors is used to control whether the log should have colors or not
* @return {boolean}
*/
get hasColors() { return this.#colors; }
/* ---- Functions-------------------------------- */
/**
* Builds a date string using a user's locale or the specified one.
* @function
* @private
*
* @param {Date} date - Date to stringify
* @param {boolean} withTime - Include time in the date string?
* @param {string} locale - The locale to used. User's locale if null.
* @return {string}
*/
_dateToString(date, withTime = true, locale = "fr-FR") {
return withTime ? date.toLocaleString(locale) : date.toLocaleDateString(locale);
}
/**
* Build the complete log message to show
* @function
* @private
*
* @param {string} message - The message to log
* @param {Logger~BuildOptions} options - Build options
* @return {string} - The message once it has been built
*/
_build(message, options = { withTime: true, ip: null, params: null, subLevel: false }) {
const now = options.withTime ? (this._dateToString(new Date())) : "";
const ip = options.ip ? `[${options.ip}]` : "";
let params = [];
if (options.params) {
Object.entries(options.params).forEach(([key, value]) => params.push(`${key}=${value}`));
params = params.join(", ");
} else params = "";
let preSep = `${this.prefix}${now} ${ip}${this.separator}`.green;
let postSep = `${message} ${params.gray}`;
if (options.subLevel) {
preSep = `${this.prefix}${" ".repeat(3)}`.gray;
postSep = postSep.gray;
}
const str = `${preSep}${postSep}`;
return this.hasColors ? str : str.stripColors;
}
/**
* Equivalent of console.log with various options
* @function
*
* @param {string} message - The message to log
* @param {Logger~BuildOptions} [options] - Build options
* @return {void}
*/
log(message, options) { console.log(this._build(message, { withTime: true, ...options })); }
/**
* Equivalent of console.info with various options
* @function
*
* @param {string} message - The message to log
* @param {Logger~BuildOptions} [options] - Build options
* @return {void}
*/
info(message, options) { console.info(this._build(message, { withTime: true, ...options })); }
/**
* Equivalent of console.warn with various options
* @function
*
* @param {string} message - The message to log
* @param {Logger~BuildOptions} [options] - Build options
* @return {void}
*/
warn(message, options) { console.warn(this._build(message, { withTime: true, ...options }).stripColors.yellow); }
/**
* Equivalent of console.error with various options
* @function
*
* @param {string} message - The message to log
* @param {Logger~BuildOptions} [options] - Build options
* @return {void}
*/
error(message, options) { console.warn(this._build(message, { withTime: true, ...options }).stripColors.red); }
}
Source