'use strict'; const util = require("util"); const path = require("path"); const chalk = require("chalk"); const spy = require("through2-spy"); const fancyLog = require("fancy-log"); const repeatString = require("repeat-string"); const padWidth = 5; const typeColors = { error: "red", warn: "yellow", info: "cyan", debug: "gray" } function hexify(buff) { let bytes = []; for (let i = 0; i < buff.length; i++) { bytes.push(buff.toString("hex", i, i + 1)); } return bytes; } function renderError(err) { let message, stack; if (err.stack != null) { let stackLines = err.stack.split("\n"); message = stackLines[0]; stack = stackLines.slice(1); } else { message = `${err.name}: ${err.message}`; } let properties = Object.keys(err).map((key) => { if (["name", "message", "stack"].indexOf(key) === -1) { return { key: key, value: err[key] }; } }).filter((item) => item != null); if (stack != null) { properties.push({ key: "stacktrace", literal: stack.map((line) => line.trim()).join("\n") }) } let renderedProperties = properties.map((property) => { let renderedValue; if (property.literal != null) { renderedValue = property.literal; } else if (typeof property.value === "string") { renderedValue = property.value; } else { renderedValue = util.inspect(property.value, {colors: true}); } return `${chalk.bold.blue(property.key)}:\n${indentMultiline(renderedValue)}`; }).join("\n"); let details = indentMultiline(renderedProperties); return `${chalk.bold.red(message)}\n${details}` } function indentMultiline(text, spaces = 4) { let indent = repeatString(" ", spaces); return text.split("\n").map((line) => indent + line).join("\n"); } module.exports = function namedLog(name, options = {}) { let prefix = `[${chalk.green(name)}]`; function createLog(type) { let prefixes = [prefix]; if (type) { let typeColor = (typeColors[type] != null) ? typeColors[type] : "white"; let typePrefix = `[${chalk[typeColor](type)}]`; prefixes.push(typePrefix); } return function log(...args) { if (args[0] instanceof Error) { let renderedError = renderError(args[0]); fancyLog.apply(null, prefixes.concat([renderedError])); } else { fancyLog.apply(null, prefixes.concat(args)); } } } return { debug: createLog("debug"), info: createLog("info"), warn: createLog("warn"), error: createLog("error"), log: createLog(), stream: function() { return spy.obj((file) => { let shortPath, firstBytes, suffix; let byteLimit = (options.byteLimit != null) ? options.byteLimit : 20; if (options.basePath != null) { shortPath = path.relative(options.basePath, file.path); } else { shortPath = path.basename(file.path); } if (file.contents.length <= byteLimit) { firstBytes = file.contents; suffix = ""; } else { firstBytes = file.contents.slice(0, byteLimit); suffix = " ..." } this.info(`>`); }); } } }