"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const util = require("util"); const chalk_1 = require("chalk"); const guards_1 = require("../../guards"); const format_1 = require("./format"); exports.LOGGER_STATUS_COLORS = new Map([ ['debug', chalk_1.default.magenta.dim], ['info', chalk_1.default.gray], ['ok', chalk_1.default.green], ['warn', chalk_1.default.yellow], ['error', chalk_1.default.red], ['announce', chalk_1.default.cyan], ]); class Logger { constructor({ level = 'info', prefix = '', stream = process.stdout }) { this.firstLineColored = ['warn', 'error', 'announce']; this.level = level; this.prefix = prefix; this.stream = stream; } debug(msg) { this._log('debug', msg); } info(msg) { this._log('info', msg); } ok(msg) { this._log('ok', msg); } warn(msg) { this._log('warn', msg); } error(msg) { this._log('error', msg); } announce(msg) { this._log('announce', msg); } msg(msg) { if (typeof msg === 'function') { msg = msg(); } this.stream.write(this.enforceLF(msg)); } log(msg) { this.msg(msg); } nl(num = 1) { this.stream.write(this.enforceLF('\n'.repeat(num))); } shouldLog(level) { return guards_1.LOG_LEVELS.indexOf(level) >= guards_1.LOG_LEVELS.indexOf(this.level); } enforceLF(str) { return str.match(/[\r\n]$/) ? str : str + '\n'; } getStatusColor(level) { const color = exports.LOGGER_STATUS_COLORS.get(level); if (!color) { return chalk_1.default.reset; } return color; } _log(level, msg) { if (this.shouldLog(level)) { let prefix = this.prefix; if (typeof msg === 'function') { msg = msg(); } if (prefix) { if (typeof prefix === 'function') { prefix = prefix(); } msg = util.format(prefix, msg); } const color = this.getStatusColor(level); const status = color.bold.bgBlack; const b = chalk_1.default.dim; const msgLines = format_1.wordWrap(msg, { indentation: level === 'info' ? 0 : level.length + 3 }).split('\n'); if (msg.trim().includes('\n')) { msg = msgLines.map((l, i) => { // We want these log messages to stand out a bit, so automatically // color the first line and separate the first line from the other // lines if the message is multi-lined. if (i === 0 && this.firstLineColored.includes(level)) { return color(l) + (msgLines.length > 1 ? '\n' : ''); } return l; }).join('\n') + '\n\n'; } else { msg = msgLines.join('\n'); } msg = this.enforceLF(msg); const fmtLevel = () => b('[') + status(level.toUpperCase()) + b(']'); if (level !== 'info') { msg = `${fmtLevel()} ${msg}`; } this.stream.write(util.format(msg)); } } } exports.Logger = Logger;