'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var moment = require('moment'); var StackTrace = require('stacktrace-js'); var objectInspect = require('object-inspect'); var safeJsonStringify = require('safe-json-stringify'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var moment__default = /*#__PURE__*/_interopDefault(moment); var StackTrace__default = /*#__PURE__*/_interopDefault(StackTrace); var objectInspect__default = /*#__PURE__*/_interopDefault(objectInspect); var safeJsonStringify__default = /*#__PURE__*/_interopDefault(safeJsonStringify); var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); // src/loglevel.ts var LogLevel = class _LogLevel { constructor(value) { this.value = Number.MAX_VALUE; if (value instanceof _LogLevel) { return value; } this.value = value; } static valueOf(name) { const level = _LogLevel[name]; if (level instanceof _LogLevel) { return level; } return null; } valueOf() { return this.value; } }; LogLevel.TRACE = new LogLevel(0); LogLevel.DEBUG = new LogLevel(100); LogLevel.INFO = new LogLevel(200); LogLevel.WARN = new LogLevel(300); LogLevel.ERROR = new LogLevel(400); LogLevel.OFF = new LogLevel(Number.MAX_VALUE); // src/logger.ts var Logger = class { constructor() { this.level = LogLevel.INFO; this.channels = []; } setLevel(level) { this.level = level; } /** * Creates logging channel that consists of a list of processors. * * Processor is a function that accepts an array of records `{level, messages}` and returns another * array of records for consequent processors to work with. If processor returns a promise then logging * channel is suspended until this promise is resolved. * * Instead of an object with `process` method can be provided. * * @returns {Logger} */ channel(...processors) { const procs = processors.map((processor) => { const p = processor; if (typeof p === "function") { return processor; } const pobject = processor; if (pobject == null ? void 0 : pobject.process) { return pobject.process; } throw new Error( "Processor should be a function or an object with `process` callback" ); }); this.channels.push({ processors: procs, promise: void 0 }); } /** * Process records through pipeline. * * @param {Array} records * @return {Promise|null} */ process(records) { let r = records.filter( (record) => record.level.valueOf() >= this.level.valueOf() ); if (!r.length) { return records; } const promises = []; for (const channel of this.channels) { let next2 = function(p2, r2, i) { if (!r2) { return; } if (i < p2.length) { let r1; try { r1 = p2[i](r2); } catch (error) { console.error(error); } if (r1 instanceof Promise) { const r3 = r1.then((r22) => next2(p2, r22, i + 1)).catch((error) => console.log(error)); return r3; } else { return next2(p2, r1, i + 1); } } else { if (channel.promise === promise) { channel.promise = void 0; } } }; const p = [...channel.processors]; let promise; if (channel.promise) { promise = channel.promise = channel.promise.then(() => next2(p, r, 0)); } else { promise = next2(p, r, 0); if (promise instanceof Promise) { channel.promise = promise; } } if (promise) { promises.push(promise); } } if (promises.length) { return Promise.all(promises).then(() => records); } return records; } isTraceEnabled() { return this.level.valueOf() >= LogLevel.TRACE.valueOf(); } isDebugEnabled() { return this.level.valueOf() >= LogLevel.DEBUG.valueOf(); } isInfoEnabled() { return this.level.valueOf() >= LogLevel.INFO.valueOf(); } isWarnEnabled() { return this.level.valueOf() >= LogLevel.WARN.valueOf(); } isErrorEnabled() { return this.level.valueOf() >= LogLevel.ERROR.valueOf(); } /** * Send messages to channels of this logger. * * @param {Number} level Level to log provided messages with. * @param {Array} messages Messages to pass to processors. * @param {Object} [meta] Any additional meta passed to processors. * * @returns {Promise} Promise that resolves when all channels did process provided messages. */ sendMessages(level, messages, meta) { return this.process([{ level, messages, meta }]); } log(...messages) { return this.sendMessages(LogLevel.INFO, messages); } trace(...messages) { return this.sendMessages(LogLevel.TRACE, messages); } debug(...messages) { return this.sendMessages(LogLevel.DEBUG, messages); } info(...messages) { return this.sendMessages(LogLevel.INFO, messages); } warn(...messages) { return this.sendMessages(LogLevel.WARN, messages); } error(...messages) { return this.sendMessages(LogLevel.ERROR, messages); } }; // src/config.ts function parseConfig(loggerConfig, processorDictionary = {}) { const logger = new Logger(); if (!loggerConfig) { return logger; } const { level, channels } = loggerConfig; if (level) { const logLevel = LogLevel.valueOf(level); if (!logLevel) { throw new Error(`Unknown log level "${level}"`); } logger.setLevel(logLevel); } if (!channels) { return logger; } for (const channel of channels) { const processors = []; for (const processor of channel) { const { type, options } = processor; const processorFactory = processorDictionary[type]; if (type === "logger") { processors.push( parseConfig(options, processorDictionary) ); } else if (!processorFactory) { throw new Error(`Unknown processor type "${type}"`); } else { processors.push(processorFactory(options)); } } logger.channel(...processors); } return logger; } // src/processors/createAggregateProcessor.ts function createAggregateProcessor(options) { const { onDispatch } = options; let resolve; let promise; let cache = []; function next() { if (cache.length && resolve) { resolve(cache); resolve = null; promise = null; cache = []; } } function tryDispatch() { onDispatch(cache, next); } return (records) => { cache.push(...records); if (resolve) { const nextPromise = promise; tryDispatch(); return nextPromise; } else { if (!promise) { promise = new Promise((resolveSelf) => { resolve = resolveSelf; tryDispatch(); }); } return promise; } }; } // src/processors/createConsoleProcessor.ts function createConsoleProcessor() { return (records) => { for (const { level, messages } of records) { switch (level) { case LogLevel.TRACE: case LogLevel.DEBUG: if (console.debug) { console.debug(...messages); return; } break; case LogLevel.INFO: if (console.info) { console.info(...messages); return; } break; case LogLevel.WARN: if (console.warn) { console.warn(...messages); return; } break; case LogLevel.ERROR: console.error(...messages); return; } console.log(...messages); } return records; }; } function getLogLevelName(level) { for (const key in LogLevel) { if (level instanceof LogLevel && level === LogLevel[key]) { return key; } if (typeof level === "number" && level === LogLevel[key].valueOf()) { return key; } } return level; } function createDateAndLevelPrependProcessor({ dateFormat = "YYYY-MM-DD HH:MM:SS" } = {}) { return (records) => records.map((record) => { record = __spreadProps(__spreadValues({}, record), { messages: [...record.messages] }); const { messages, level } = record; messages.unshift(getLogLevelName(level), moment__default.default().format(dateFormat)); return record; }); } var LOGGER_STACK_FRAME_COUNT = 8; function createErrorWrapProcessor({ trimHeadFrames = 0, loggerStackFrameCount = LOGGER_STACK_FRAME_COUNT, testMessage = defaultTestMessage, createStackTrace = defaultCreateStackTrace } = {}) { return (records) => records.map(({ level, messages, meta }) => { messages = [...messages]; for (let i = 0; i < messages.length; ++i) { if (messages[i] instanceof Error || !testMessage(messages[i], level, i)) { continue; } const error = new Error(messages[i]); const stackFrames = StackTrace__default.default.getSync().slice( trimHeadFrames + loggerStackFrameCount ); error.stack = createStackTrace(error.name, error.message, stackFrames); messages[i] = error; } return { level, messages, meta }; }); } function defaultTestMessage(message, level, i) { return level >= LogLevel.ERROR && i === 0; } function defaultCreateStackTrace(errorType, errorMessage, stackFrames) { const callStack = []; for (const { fileName, lineNumber, columnNumber, functionName } of stackFrames) { const path = `${fileName}:${lineNumber}:${columnNumber}`; callStack.push( functionName ? `at ${functionName} (${path})` : `at ${path}` ); } return `${errorType}: ${errorMessage} ${callStack.join("\n")}`; } function createInspectProcessor({ depth = 10 } = {}) { return (records) => records.map((record) => __spreadProps(__spreadValues({}, record), { messages: record.messages.map((message) => { if (typeof message === "object" || typeof message === "function") { return objectInspect__default.default(message, { depth }); } return message; }) })); } function createMessageConcatProcessor(options = {}) { const { stringifyLoggedValue = stringifyLog } = options; return (records) => records.map(({ level, messages, meta }) => { if (messages.length === 0) { return { level, messages, meta }; } meta = __spreadValues({}, meta); let [message] = messages; if (messages.length === 1) { if (message instanceof Error) { meta.error = message; message = message.message; } else if (typeof message === "object") { meta.object = message; } message = stringifyLoggedValue(message, 50); } else if (messages.length > 1) { let i = 1; const parts = []; for (let message2 of messages) { if (typeof message2 === "object") { parts.push(`${stringifyLoggedValue(message2, 25)} (#${i})`); meta["#" + i] = message2; i += 1; } else { parts.push(message2); } } message = parts.join(" "); } return { level, messages: [message], meta }; }); } function stringifyLog(value, charLimit) { let string; if (value instanceof Error) { string = value.message; } else if (typeof value === "object") { string = safeJsonStringify__default.default(value); } else { string = String(value); } if (string.length < charLimit) { return string; } charLimit -= 1; string = string.match(new RegExp(`^.{0,${charLimit}}(?=\\s|\\s+\\b|$)`)) || string.slice(0, charLimit); return string + "\u2026"; } // src/processors/createStackTraceTransformProcessor.ts function webpackStackCleaner(stack) { return stack.replace(/\/[^(\n]+(target.out|webpack:)(~?\/)+/g, ""); } function createStackTraceTransformProcessor(options = { transformer: webpackStackCleaner }) { const { transformer } = options; return (records) => records.map((record) => __spreadProps(__spreadValues({}, record), { messages: record.messages.map((message) => { if (message instanceof Error) { return transformer(message.stack); } return message; }) })); } // src/processors/createThrottleProcessor.ts function createThrottleProcessor(options = { delay: 1e3, length: 1e3, leading: true }) { const { delay, length, leading } = options; let timeout; return createAggregateProcessor({ onDispatch(records, next) { if (records.length < length) { if (leading) { if (!timeout) { timeout = setTimeout(() => { timeout = 0; next(); }, delay); } } else { timeout = setTimeout(next, delay); } } else { clearTimeout(timeout); next(); } } }); } // src/processors/createSentryProcessor.ts function createSentryProcessor(sentry) { return (records) => { for (const { level, messages, meta } of records) { if (!messages.length) { continue; } const message = messages[0]; if (level.valueOf() < LogLevel.ERROR.valueOf()) { sentry.captureMessage(message, { level: level.valueOf() < LogLevel.WARN.valueOf() ? "info" : "warn", meta }); } else { sentry.captureException(message, { level: "error", meta }); } } return records; }; } // src/index.ts var ProcessorFactories = { logger: Logger, aggregate: createAggregateProcessor, console: createConsoleProcessor, prependDateAndLevel: createDateAndLevelPrependProcessor, inspect: createInspectProcessor, extractStackTrace: createStackTraceTransformProcessor, throttle: createThrottleProcessor, wrapError: createErrorWrapProcessor, concatMessages: createMessageConcatProcessor }; exports.LogLevel = LogLevel; exports.Logger = Logger; exports.ProcessorFactories = ProcessorFactories; exports.createAggregateProcessor = createAggregateProcessor; exports.createConsoleProcessor = createConsoleProcessor; exports.createDateAndLevelPrependProcessor = createDateAndLevelPrependProcessor; exports.createErrorWrapProcessor = createErrorWrapProcessor; exports.createInspectProcessor = createInspectProcessor; exports.createMessageConcatProcessor = createMessageConcatProcessor; exports.createSentryProcessor = createSentryProcessor; exports.createStackTraceTransformProcessor = createStackTraceTransformProcessor; exports.createThrottleProcessor = createThrottleProcessor; exports.default = Logger; exports.parseLoggerConfig = parseConfig; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map