UNPKG

@graphql-mesh/utils

Version:
120 lines (119 loc) 4.25 kB
import { process } from '@graphql-mesh/cross-helpers'; const ANSI_CODES = { black: '\x1b[30m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', magenta: '\x1b[35m', cyan: '\x1b[36m', white: '\x1b[37m', reset: '\x1b[0m', bold: '\x1b[1m', orange: '\x1b[48:5:166m', }; export const warnColor = msg => ANSI_CODES.orange + msg + ANSI_CODES.reset; export const infoColor = msg => ANSI_CODES.cyan + msg + ANSI_CODES.reset; export const errorColor = msg => ANSI_CODES.red + msg + ANSI_CODES.reset; export const debugColor = msg => ANSI_CODES.magenta + msg + ANSI_CODES.reset; export const titleBold = msg => ANSI_CODES.bold + msg + ANSI_CODES.reset; export var LogLevel; (function (LogLevel) { LogLevel[LogLevel["debug"] = 0] = "debug"; LogLevel[LogLevel["info"] = 1] = "info"; LogLevel[LogLevel["warn"] = 2] = "warn"; LogLevel[LogLevel["error"] = 3] = "error"; LogLevel[LogLevel["silent"] = 4] = "silent"; })(LogLevel || (LogLevel = {})); const noop = () => { }; function truthy(val) { return val === true || val === 1 || ['1', 't', 'true', 'y', 'yes'].includes(String(val)); } function getTimestamp() { return new Date().toISOString(); } function handleLazyMessage(lazyArgs) { return lazyArgs.flat(Infinity).flatMap(arg => { if (typeof arg === 'function') { return arg(); } return arg; }); } export class DefaultLogger { constructor(name, logLevel = truthy(process.env.DEBUG) || truthy(globalThis.DEBUG) || (this.name && String(process.env.DEBUG || globalThis.DEBUG || '').includes(this.name)) ? LogLevel.debug : LogLevel.info, /** @deprecated Trimming messages is no longer supported. This argument is unused and will be removed in future versions. */ _trim, console = globalThis.console) { this.name = name; this.logLevel = logLevel; this.console = console; } get prefix() { return this.name ? `[${titleBold(this.name.toString().trim())}] ` /* trailing space because prefix is directly used in logged message */ : ``; } /** Logs a message at {@link LogLevel.info} but without the "INFO" prefix. */ log(...args) { if (this.logLevel > LogLevel.info) { return noop; } this.console.log(`[${getTimestamp()}] ${this.prefix}`.trim() /* trim in case prefix is empty */, ...args); } warn(...args) { if (this.logLevel > LogLevel.warn) { return noop; } this.console.warn(`[${getTimestamp()}] WARN ${this.prefix}${ANSI_CODES.orange}`, ...args, ANSI_CODES.reset); } info(...args) { if (this.logLevel > LogLevel.info) { return noop; } this.console.info(`[${getTimestamp()}] INFO ${this.prefix}${ANSI_CODES.cyan}`, ...args, ANSI_CODES.reset); } error(...args) { if (this.logLevel > LogLevel.error) { return noop; } this.console.error(`[${getTimestamp()}] ERROR ${this.prefix}${ANSI_CODES.red}`, ...args, ANSI_CODES.reset); } debug(...lazyArgs) { if (this.logLevel > LogLevel.debug) { return noop; } const flattenedArgs = handleLazyMessage(lazyArgs); this.console.debug(`[${getTimestamp()}] DEBUG ${this.prefix}${ANSI_CODES.magenta}`, ...flattenedArgs, ANSI_CODES.reset); } child(name) { name = stringifyName(name); if (this.name?.includes(name)) { return this; } return new DefaultLogger(this.name ? `${this.name}, ${name}` : name, this.logLevel, undefined, this.console); } addPrefix(prefix) { prefix = stringifyName(prefix); if (!this.name?.includes(prefix)) { this.name = this.name ? `${this.name}, ${prefix}` : prefix; } return this; } toJSON() { return undefined; } } function stringifyName(name) { if (typeof name === 'string' || typeof name === 'number') { return `${name}`; } const names = []; for (const [key, value] of Object.entries(name)) { names.push(`${key}=${value}`); } return `${names.join(', ')}`; }