UNPKG

app-lib-log

Version:

个人日志组件 -【app-lib-log】

1,771 lines (1,526 loc) 50.5 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else { var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } })(this, () => { return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 363: /***/ (function(module) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(); else { var i, a; } })(this, () => { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __nested_webpack_require_481__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __nested_webpack_require_481__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__nested_webpack_require_481__.o(definition, key) && !__nested_webpack_require_481__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/global */ /******/ (() => { /******/ __nested_webpack_require_481__.g = (function() { /******/ if (typeof globalThis === 'object') return globalThis; /******/ try { /******/ return this || new Function('return this')(); /******/ } catch (e) { /******/ if (typeof window === 'object') return window; /******/ } /******/ })(); /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __nested_webpack_require_481__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __nested_webpack_require_481__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; __nested_webpack_require_481__.r(__webpack_exports__); /* harmony export */ __nested_webpack_require_481__.d(__webpack_exports__, { /* harmony export */ "ENV": () => (/* binding */ ENV), /* harmony export */ "bindToGlobal": () => (/* binding */ bindToGlobal), /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), /* harmony export */ "getEnv": () => (/* binding */ getEnv), /* harmony export */ "getGlobal": () => (/* binding */ getGlobal), /* harmony export */ "getbindData": () => (/* binding */ getbindData), /* harmony export */ "isBindToGlobal": () => (/* binding */ isBindToGlobal), /* harmony export */ "isBroswerEnv": () => (/* binding */ isBroswerEnv), /* harmony export */ "isNodeEnv": () => (/* binding */ isNodeEnv) /* harmony export */ }); /** * 支持的环境变量 * ``` * * NODE: 'node', // ndoejs 环境 * * BROWSER: 'browser', // 浏览器环境 * ``` */ const ENV = { NODE: 'node', // ndoejs 环境 BROWSER: 'browser', // 浏览器环境 } /** * 获取当前环境 * * @function * @returns {string} 当前环境常量 */ const getEnv = () => { // 切换为判断是否为nodejs 因为小程序使用的时候不是nodejs 当做浏览器模式 const isNodeJs = typeof process !== 'undefined' && process.release != null && process.release.name === 'node'; if (isNodeJs) return ENV.NODE; return ENV.BROWSER; } /** * 判断是否为nodejs环境 * * @function * @returns {Boolean} * * true 是nodejs环境 * * false 不是nodejs环境 */ const isNodeEnv = () => getEnv() === ENV.NODE; /** * 判断是否为浏览器环境 * * @function * @returns {Boolean} * * true 是浏览器环境 * * false 不是浏览器环境 */ const isBroswerEnv = () => getEnv() === ENV.BROWSER; /** * 获取全局变量 * * * @returns {Object} - 获取的全局变量 * * window * * global * @description * 获取当前运行环境的全局变量 * * 支持浏览器 window * * 支持nodejs gloabl * @function */ // export const getGlobal = () => { // let root; // if (typeof global === 'object') { // root = global; // } else { // root = this.window; // } // return root; // } const getGlobal = () => { return __nested_webpack_require_481__.g; } /** * 获取绑定数据 * * * @param {string} namespace 命名空间 * @returns {any} 已绑定的值 * @function */ const getbindData = (namespace) => { let root = getGlobal(); if (!root) throw new Error('未找到当前环境的全局变量'); return root[namespace]; } /** * 绑定数据到全局 * * * @param {string} namespace 命名空间 * @param {any} bindData 绑定数据 * @param {boolean} [isForce=false] 是否强制绑定 - 存在当前值时,进行强制绑定 * @returns {any} 全局已绑定的值 * @function */ const bindToGlobal = (namespace, bindData, isForce) => { let isBind = isBindToGlobal(namespace); if (isBind && !isForce) return getbindData(namespace); let root = getGlobal() root[namespace] = bindData; return bindData; } /** * 是否也绑定到全局 * * * @param {string} namespace 命名空间 * @param {Object} [needbindData='undefined'] - 绑定对象 * @returns {boolean} 是否绑定 * * true 已绑定 * * false 未绑定 * @description * 是否也绑定到全局 * * needbindData 绑定对象不为undefined时: * * 比对值相等 或者 json 序列化后相等 则表示已绑定 * @function */ const isBindToGlobal = (namespace, needbindData) => { if (!namespace) throw new Error('必须执行绑定名称'); let root = getGlobal(); /** * @throws {DOMException} */ if (!root) throw new Error('未找到当前环境的全局变量'); let bindData = root[namespace]; // 全局对象上的属性为undifed 表示未绑定 if (void 0 === bindData) return false; // 需要比对指定绑定的值 值直接相等或者json 序列化后相等 则表示1已绑定 if (void 0 != needbindData) { return bindData === needbindData || JSON.stringify(bindData) === JSON.stringify(needbindData); } return true; } /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (bindToGlobal); /******/ return __webpack_exports__; /******/ })() ; }); //# sourceMappingURL=index-bundle.js.map /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be in strict mode. (() => { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { "ALL_FUNCTIONS": () => (/* binding */ ALL_FUNCTIONS), "LEVEL": () => (/* binding */ LEVEL), "Logger": () => (/* binding */ Logger), "TYPE": () => (/* binding */ TYPE), "create": () => (/* binding */ create), "default": () => (/* binding */ src), "log": () => (/* binding */ log) }); ;// CONCATENATED MODULE: ./src/chalk/source/vendor/ansi-styles/index.js const ANSI_BACKGROUND_OFFSET = 10; const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`; const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`; const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; const styles = { modifier: { reset: [0, 0], // 21 isn't widely supported and 22 does the same thing bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29], }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], // Bright color blackBright: [90, 39], gray: [90, 39], // Alias of `blackBright` grey: [90, 39], // Alias of `blackBright` redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39], }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], // Bright color bgBlackBright: [100, 49], bgGray: [100, 49], // Alias of `bgBlackBright` bgGrey: [100, 49], // Alias of `bgBlackBright` bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49], }, }; const modifierNames = Object.keys(styles.modifier); const foregroundColorNames = Object.keys(styles.color); const backgroundColorNames = Object.keys(styles.bgColor); const colorNames = [...foregroundColorNames, ...backgroundColorNames]; function assembleStyles() { const codes = new Map(); for (const [groupName, group] of Object.entries(styles)) { for (const [styleName, style] of Object.entries(group)) { styles[styleName] = { open: `\u001B[${style[0]}m`, close: `\u001B[${style[1]}m`, }; group[styleName] = styles[styleName]; codes.set(style[0], style[1]); } Object.defineProperty(styles, groupName, { value: group, enumerable: false, }); } Object.defineProperty(styles, 'codes', { value: codes, enumerable: false, }); styles.color.close = '\u001B[39m'; styles.bgColor.close = '\u001B[49m'; styles.color.ansi = wrapAnsi16(); styles.color.ansi256 = wrapAnsi256(); styles.color.ansi16m = wrapAnsi16m(); styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js Object.defineProperties(styles, { rgbToAnsi256: { value(red, green, blue) { // We use the extended greyscale palette here, with the exception of // black and white. normal palette only has 4 greyscale shades. if (red === green && green === blue) { if (red < 8) { return 16; } if (red > 248) { return 231; } return Math.round(((red - 8) / 247) * 24) + 232; } return 16 + (36 * Math.round(red / 255 * 5)) + (6 * Math.round(green / 255 * 5)) + Math.round(blue / 255 * 5); }, enumerable: false, }, hexToRgb: { value(hex) { const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); if (!matches) { return [0, 0, 0]; } let [colorString] = matches; if (colorString.length === 3) { colorString = [...colorString].map(character => character + character).join(''); } const integer = Number.parseInt(colorString, 16); return [ /* eslint-disable no-bitwise */ (integer >> 16) & 0xFF, (integer >> 8) & 0xFF, integer & 0xFF, /* eslint-enable no-bitwise */ ]; }, enumerable: false, }, hexToAnsi256: { value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)), enumerable: false, }, ansi256ToAnsi: { value(code) { if (code < 8) { return 30 + code; } if (code < 16) { return 90 + (code - 8); } let red; let green; let blue; if (code >= 232) { red = (((code - 232) * 10) + 8) / 255; green = red; blue = red; } else { code -= 16; const remainder = code % 36; red = Math.floor(code / 36) / 5; green = Math.floor(remainder / 6) / 5; blue = (remainder % 6) / 5; } const value = Math.max(red, green, blue) * 2; if (value === 0) { return 30; } // eslint-disable-next-line no-bitwise let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red)); if (value === 2) { result += 60; } return result; }, enumerable: false, }, rgbToAnsi: { value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), enumerable: false, }, hexToAnsi: { value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), enumerable: false, }, }); return styles; } const ansiStyles = assembleStyles(); /* harmony default export */ const ansi_styles = (ansiStyles); ;// CONCATENATED MODULE: ./src/chalk/source/vendor/supports-color/browser.js /* eslint-env browser */ let isBlinkBasedBrowser = false; if (typeof navigator != 'undefined') { isBlinkBasedBrowser = navigator && navigator.userAgentData ? navigator.userAgentData.brands.some(({ brand }) => brand === 'Chromium') : /\b(Chrome|Chromium)\//.test(navigator.userAgent); } const colorSupport = isBlinkBasedBrowser ? { level: 1, hasBasic: true, has256: false, has16m: false, } : false; const supportsColor = { stdout: colorSupport, stderr: colorSupport, }; /* harmony default export */ const browser = (supportsColor); ;// CONCATENATED MODULE: ./src/chalk/source/utilities.js // TODO: When targeting Node.js 16, use `String.prototype.replaceAll`. function stringReplaceAll(string, substring, replacer) { let index = string.indexOf(substring); if (index === -1) { return string; } const substringLength = substring.length; let endIndex = 0; let returnValue = ''; do { returnValue += string.slice(endIndex, index) + substring + replacer; endIndex = index + substringLength; index = string.indexOf(substring, endIndex); } while (index !== -1); returnValue += string.slice(endIndex); return returnValue; } function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) { let endIndex = 0; let returnValue = ''; do { const gotCR = string[index - 1] === '\r'; returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix; endIndex = index + 1; index = string.indexOf('\n', endIndex); } while (index !== -1); returnValue += string.slice(endIndex); return returnValue; } ;// CONCATENATED MODULE: ./src/chalk/source/index.js const {stdout: stdoutColor, stderr: stderrColor} = browser; const GENERATOR = Symbol('GENERATOR'); const STYLER = Symbol('STYLER'); const IS_EMPTY = Symbol('IS_EMPTY'); // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', 'ansi', 'ansi256', 'ansi16m', ]; const source_styles = Object.create(null); const applyOptions = (object, options = {}) => { if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { throw new Error('The `level` option should be an integer from 0 to 3'); } // Detect level if not set manually const colorLevel = stdoutColor ? stdoutColor.level : 0; object.level = options.level === undefined ? colorLevel : options.level; }; class Chalk { constructor(options) { // eslint-disable-next-line no-constructor-return return chalkFactory(options); } } const chalkFactory = options => { const chalk = (...strings) => strings.join(' '); applyOptions(chalk, options); Object.setPrototypeOf(chalk, createChalk.prototype); return chalk; }; function createChalk(options) { return chalkFactory(options); } Object.setPrototypeOf(createChalk.prototype, Function.prototype); for (const [styleName, style] of Object.entries(ansi_styles)) { source_styles[styleName] = { get() { const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]); Object.defineProperty(this, styleName, {value: builder}); return builder; }, }; } source_styles.visible = { get() { const builder = createBuilder(this, this[STYLER], true); Object.defineProperty(this, 'visible', {value: builder}); return builder; }, }; const getModelAnsi = (model, level, type, ...arguments_) => { if (model === 'rgb') { if (level === 'ansi16m') { return ansi_styles[type].ansi16m(...arguments_); } if (level === 'ansi256') { return ansi_styles[type].ansi256(ansi_styles.rgbToAnsi256(...arguments_)); } return ansi_styles[type].ansi(ansi_styles.rgbToAnsi(...arguments_)); } if (model === 'hex') { return getModelAnsi('rgb', level, type, ...ansi_styles.hexToRgb(...arguments_)); } return ansi_styles[type][model](...arguments_); }; const usedModels = ['rgb', 'hex', 'ansi256']; for (const model of usedModels) { source_styles[model] = { get() { const {level} = this; return function (...arguments_) { const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansi_styles.color.close, this[STYLER]); return createBuilder(this, styler, this[IS_EMPTY]); }; }, }; const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); source_styles[bgModel] = { get() { const {level} = this; return function (...arguments_) { const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansi_styles.bgColor.close, this[STYLER]); return createBuilder(this, styler, this[IS_EMPTY]); }; }, }; } const proto = Object.defineProperties(() => {}, { ...source_styles, level: { enumerable: true, get() { return this[GENERATOR].level; }, set(level) { this[GENERATOR].level = level; }, }, }); const createStyler = (open, close, parent) => { let openAll; let closeAll; if (parent === undefined) { openAll = open; closeAll = close; } else { openAll = parent.openAll + open; closeAll = close + parent.closeAll; } return { open, close, openAll, closeAll, parent, }; }; const createBuilder = (self, _styler, _isEmpty) => { // Single argument is hot path, implicit coercion is faster than anything // eslint-disable-next-line no-implicit-coercion const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype Object.setPrototypeOf(builder, proto); builder[GENERATOR] = self; builder[STYLER] = _styler; builder[IS_EMPTY] = _isEmpty; return builder; }; const applyStyle = (self, string) => { if (self.level <= 0 || !string) { return self[IS_EMPTY] ? '' : string; } let styler = self[STYLER]; if (styler === undefined) { return string; } const {openAll, closeAll} = styler; if (string.includes('\u001B')) { while (styler !== undefined) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code // will be colored, and the rest will simply be 'plain'. string = stringReplaceAll(string, styler.close, styler.open); styler = styler.parent; } } // We can move both next actions out of loop, because remaining actions in loop won't have // any/visible effect on parts we add here. Close the styling before a linebreak and reopen // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 const lfIndex = string.indexOf('\n'); if (lfIndex !== -1) { string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); } return openAll + string + closeAll; }; Object.defineProperties(createChalk.prototype, source_styles); const chalk = createChalk(); const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0}); /* harmony default export */ const source = ((/* unused pure expression or super */ null && (chalk))); // EXTERNAL MODULE: ./node_modules/.pnpm/app-lib-global@1.0.44/node_modules/app-lib-global/publish/umd/index-bundle.js var index_bundle = __webpack_require__(363); ;// CONCATENATED MODULE: ./src/index.js /*************************************************************************************************** * * * 注意 * 1. 由于类的注释 在 jsdoc-to-md 的组件中不能显示,故将类内部的方法独立出来 * 2. 由于箭头函数没有 this 指向到类 同时为了能在实例上显示具体的执行方法,便于简写能一目了然 故使用函数式声明 * * * 参考地址 * * https://jsdoc.app/ 官方文档 * * https://github.com/jsdoc/jsdoc github * * @ignore ***************************************************************************************************/ /** * * * 测试全局方法 * @constant ALL_FUNCTIONS * @description * * 日志级别相关方法 * * |级别 | 堆栈 | 调试 | 日志 | 信息 | 成功 | 表格 | 时间 | 警告 | 错误 | * |-|-|-|-|-|-|-|-|-|-| * |方法名|trace|debug|log|info|success|table|time|warn/warnNoTrace|error/errorNoTrace| * |简写|t|d|l|i|s|T|tt|w/wn|e/wn| * |模块化|mTrace|mDebug|mLog|mInfo|mSuccess|mTable|mTime|mWarn/mWarnNoTrace|mError/mErrorNoTrace| * |简写|mt|md|ml|mi|ms|mT|mtt|mw/mwn|me/mwn| * * * 彩色转换与其他方法 * > 参考详细文档 * */ const ALL_FUNCTIONS = []; /** * @ignore * 是否浏览器模式 */ const isBroswer = (0,index_bundle.isBroswerEnv)(); /** * @ignore * 环境变量 */ const env = (0,index_bundle.getEnv)(); /** * @ignore * 终端彩色打印 */ const src_chalk = new Chalk({ level: 2 }); /** * 支持的打印类型 * @constant * @name TYPE * @description * 日志类型 * * |级别 | 堆栈 | 调试 | 日志 | 信息 | 成功 | 表格 | 时间 | 警告 | 错误 | * |-|-|-|-|-|-|-|-|-|-| * |常量名称|TRACE|DEBUG|LOG|INFO|SUCCESS|TABLE|TIME|WARN|ERROR| * |常量值|trace|debug|log|info|success|table|time|warn|error| */ const TYPE = { TRACE: 'trace', DEBUG: 'debug', INFO: 'info', LOG: 'log', SUCCESS: 'success', TABLE: 'table', TIME: 'time', WARN: 'warn', ERROR: 'error', }; /** * 日志级别 * @constant * @name LEVEL * @description * 日志级别 * * 通过 setOption({level:number}) 进行打印高于该值 (number) 的日志 * * 调整该顺序值进行灵活打印 * * 或者只打印某几项日志 * * |级别 | 堆栈 | 调试 | 日志 | 信息 | 成功 | 表格 | 时间 | 警告 | 错误 | * |-|-|-|-|-|-|-|-|-|-| * |常量名|trace|debug|log|info|success|table|time|warn|error| * |常量值|10|20|30|31|32|33|40|60|70| */ const LEVEL = { trace: 10, // 跟踪 堆栈 debug: 20, // 调试 info: 30, // 信息 log: 31,// 元素的 log success: 32,// 成功--便于开发高亮标识 table: 33, time: 40, // 时间--带时间戳 warn: 60, // 告警 error: 70 // 错误 }; // 多彩的配置 const colorful = { node: { maxCharLength: 9, // 显示级别的最大字符长度 9 即 success+ 两个空格 textAlgin: 'right', // 支持 left/right 和 center space: "", // 级别标识后的间隔距离 // 模块标识背景和颜色 module: { background: '#0a0afb', color: '#ffffff' }, trace: { background: '#4a4848', color: '#ffffff' }, debug: { background: '#4a4848', color: '#ffffff', index: ' ' }, info: { background: '#08df08', color: '#ffffff', index: ' ' }, success: { background: '#0808ef', color: '#ffffff', index: ' ' }, warn: { background: '#ffff08', color: '#ff0000' }, error: { background: '#f50303', color: '#ffffff' }, time: { background: '#47b2b2', color: '#ffffff', index: ' ' } }, browser: { maxCharLength: 9, // 显示级别的最大字符长度 9 即 success+ 两个空格 textAlgin: 'right', // 支持 left/right 和 center // 缩进 - 由于 chrome 浏览器对不同级别的日志打印有的带堆栈和三角 故对不带堆栈的进行缩进 保持对齐 index: "background: transparent;margin-left:4px;", // 空间隔 多个标签之间得到间隔 space: "background: transparent;", // 每种 log 的标签样式 便于开发中快速 copy 样式代码 trace: "background: linear-gradient(90deg, #b7b2b2,#8080804d, #b7b2b2); color:white; font-weight:bold; border-radius: 1px; ", debug: "background:linear-gradient(70deg, #b7b2b2, #8080804d, #b7b2b2); color:white; font-weight:bold; border-radius: 1px;", info: "background: linear-gradient(70deg, #00800085, #57d4c1,#57d4c1, #00800085); color:white; font-weight:bold;border-radius: 1px;", success: "background: linear-gradient(70deg, #172bdca1, #0000ff36, #172bdca1); color:white; font-weight:bold;border-radius: 1px;", time: "background: linear-gradient(70deg, #00bfffcf,#00bfff4f,#00bfffcf); color:white; font-weight:bold;border-radius: 1px;", warn: "background: linear-gradient(90deg, #eab60e, #eab60e6e, #eab60e); color:yellow; font-weight:bold; border-radius: 1px;", error: "background: linear-gradient(90deg, #ff00006b, #ff000033,#ff000033, #ff00006b); color:red; font-weight:bold; border-radius: 1px;", // 日期标签 dateTime: "background: none; border: 1px #ad10da4d solid; color:#ad10dacf; font-weight:bold; border-radius: 1px;", // 模块标签 module: "background: linear-gradient(70deg, #0a0afb, #44448a); color:white; font-weight:bold; border-radius: 1px;padding:0 5px" } }; /** * 日志配置 * @constant * @name option * @description * 默认配置 * * setOption - 进行设置 * * getOption - 获取当前的配置 * * |参数名 | 参数类型 | 参数默认值 | 参数描述 | 备注 | * |-|-|-|-|-| * |bindGlobalName|string|log|全局的名称 | 直接在 windows 或者 nodejs 环境中直接使用 log 即可 | * |level|number/array|20|打印日志级别 | 低于该级别的类型忽略输出/或者打印指定级别 ['warn',error] 的日志 | * |moduleName|string|''|模块名称 | 模块打印的名称|mxx 打印时直接输入自定义名称即可 | * |isModule|boolean|false|是否开启模块标识打印 | 关闭模块打印表示 | * |isColorful|boolean|true|是否开启彩色打印 | * |colorful|object|参考彩色配置 | 不同终端、不同级别颜色配置 | * |LEVEL|object|参考 LEVEL|配置打印级别值 | 灵活调整日志级别顺序 | * |dateFormatter|string/function|'YYYY-MM-DD HH:mm:ss'|日期打印格式化输出 | * |onLogger|function|null|日志输出记录 | 用于日志的收集管理 | */ const defaultOption = { bindGlobalName: 'log', level: 0, moduleName: '', isModule: false, isColorful: true, colorful: colorful[env], LEVEL, dateFormatter: 'YYYY-MM-DD HH:mm:ss', onLogger: null, logFn: console, }; const PLACE_HOLDER = '%c'; const MODULE_PLACE_HOLDER = '%s'; /** * 默认日期格式化 * @ignore */ const formatDate = (date, fmt) => { var o = { "M+": date.getMonth() + 1, //月份 "D+": date.getDate(), //日 "H+": date.getHours(), //小时 "m+": date.getMinutes(), //分 "s+": date.getSeconds() //秒 }; if (/(Y+)/.test(fmt)) { //根据 y 的长度来截取年 fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); } for (var k in o) { if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); } return fmt; } /********************************************************************************** * * 便于 MARKDOWN 中显示 API 采用 prototype 形式 * ********************************************************************************** */ /** * 设置配置 * * 设置后即刻生效 * * 后续日志打印按照该设置进行 * @function * @param {object} option 参考默认 option 配置 * @returns {objcet} 新的参数配置 option * */ const setOption = function (option) { this.option = { ...this.option, ...option }; return this.option; } /** * 获取配置 * @function * @returns {object} 参考默认 option */ const getOption = function () { return this.option; } // TODO // 考虑到小程序部支持 nodejs 的 process // 临时注释掉 后续兼容处理 小程序不支持的 nodejs 部分 /** * 根据命令行终端参数动态设置日志级别 * * --debug * * process.env.DEBUG * 仅在 nodejs 中生效 * debug 模式 默认级别为 0 否则为 21 * @name auotLevel/auotLogLevel * @function * @returns {object} log 日志实例 */ const auotLogLevel = function () { // const { DEBUG } = process?.env || {}; // // 命令行参数优先 直接设置环境变量 DEBUG 或者 // let debug = process.argv.slice(2).includes('--debug') || DEBUG; // this.setOption({ level: debug && debug != 'undefined' ? 0 : 21 }); } /********************************************************************************** * 直接设置颜色输出形式 [只适合 nodejs] ********************************************************************************** */ /** * * 输出执行缩进 显示块长度 文件颜色 和背景色的 文本 * 1. option 参数 * * indent 缩进 * * width 块的长度 * * algin 对齐 * * color 颜色 * * background 背景颜色 * @name tb/transTextColorBlock * @function * @param {string} text * @param {object} opitons * @returns {string} 彩色文案 * */ function transTextColorBlock(text, opitons) { let { indent, width, algin, color, background } = opitons return log.fill(indent || 0) + log.tx(log.autoFillText(text, width, algin), color, background); } /** * 转换文本颜色 * @name tx/transTextColor * @function * @param {string} text 文本内容 * @param {string} color 文字颜色 hex 格式 * @param {string} background 背景颜色 hex 格式 * @returns {string} 彩色文案 */ function transTextColor(text, color, background) { let cTextFn = src_chalk.hex(color || '#ffffff'); if (background) { cTextFn = cTextFn.bgHex(background); } return cTextFn(text) } /** * 转换文本颜色并且打印 * * 不受级别控制 * @function * @name txl/transTextColorAndLog * @param {string} text 文本内容 * @param {string} color 文字颜色 hex 格式 * @param {string} background 背景颜色 hex 格式 * @returns {string} 彩色文本内容 **/ function transTextColorAndLog(text, color, background) { return this.tx(text, color, background) } /** * 转换指定级别文本颜色 * * 不受级别控制 * @name tl/transLevelTextColor * @function * @param {string} [level=TYPE.INFO] 日志界别 参考 log.TYPE * @param {string} text 打印的文本内容 * @param {boolean} isBackground 是否包含背景 * @returns {string} 彩色文本内容 */ function transLevelTextColor(level = TYPE.INFO, text = '', isBackground = true) { let { background, color } = colorful.node[level] || colorful.node[TYPE.INFO]; // 打印文本 let cTextFn = src_chalk.hex(color || background || '#ffffff'); if (isBackground && background) { cTextFn = cTextFn.bgHex(background); } return cTextFn(text) } /** * 转换指定级别文本颜色 * * 不受级别控制 * @name tll/transLevelTextColorAndLog * @function * @param {string} [level=TYPE.INFO] 日志界别 参考 log.TYPE * @param {string} text 打印的文本内容 * @param {boolean} isBackground 是否包含背景 * @returns {string} 彩色文本内容 */ function transLevelTextColorAndLog(level = TYPE.INFO, text = '', isBackground = false) { defaultOption.logFn.log.apply(null, this.tl(level, text, isBackground)); } /** * 打印指定的脚本 * * 带级别字段和内容 * * @name tlh/transLevelHeaderAndLog * @function * @param {string} level 级别 * @param {string} text 文本内容 * @param {string} chalkOption 颜色配置参数 { bg, color } 形式 * @returns {string} 转换后的字符内容 */ function transLevelHeaderAndLog(level, text, chalkOption) { const type = typeof chalkOption; if (!['object', 'undefined'].includes(type)) { return this.error(`transLevelTextColorAndLog(level,text,chalkOption) 方法参数 chalkOption 传递错误,请传递{ bg, color }对象形式`) } let args = level ? this._getTerminalColorfulArguments(level) : []; args = args.length ? [args.join('')] : args; // 如果不传递背景值 则按照配置的级别答应字体颜色 无背景颜色 let { background } = colorful.node[level]; let { bg, color } = chalkOption || { color: background || '#ffffff' }; // 打印文本 let cTextFn = src_chalk.hex(color || background || '#ffffff'); if (bg) { cTextFn = cTextFn.bgHex(bg); } args.push(cTextFn(' ' + text + ' ')) return args.join(''); } /********************************************************************************** * 按照级别形式 ********************************************************************************** */ /** * trace 调试打印 * @name t/trace * @function * @param {any} args 打印的内容 * @returns {null} */ function trace(...args) { return this.exe(TYPE.TRACE, args); } /** * debug 调试打印 * @name d/debug * @function * @param {any} args 打印的内容 * @returns {null} */ function debug(...arg) { return this.exe(TYPE.DEBUG, [...arguments]); } /** * info 信息打印 * @name i/info * @function * @param {any} args 打印的内容 * @returns {null} */ function info(...arg) { return this.exe(TYPE.INFO, [...arguments]); } /** * log 日志打印 * @name l/log * @function * @param {any} args 打印的内容 * @returns {null} */ function logFn(...arg) { return this.exe(TYPE.LOG, [...arguments]); } /** * success 成功打印 * @name s/success * @function * @param {any} args 打印的内容 * @returns {null} */ function success(...arg) { return this.exe(TYPE.SUCCESS, [...arguments]); } /** * time 时间打印 * @name tt/time * @function * @param {any} args 打印的内容 * @returns {null} */ function time(...arg) { return this.exe(TYPE.TIME, [...arguments]); } /** * table 表格打印 * @name T/table * @function * @param {any} args 打印的内容 * @returns {null} */ function table(...arg) { return this.exe(TYPE.TABLE, [...arguments]); } /** * warn 警告打印 * @name w/warn * @function * @param {any} args 打印的内容 * @returns {null} */ function warn(...arg) { return this.exe(TYPE.WARN, [...arguments]); } /** * debug 调试打印 * * 不带堆栈 * @name wn/warnNoTrace * @function * @param {any} args 打印的内容 * @returns {null} */ function warnNoTrace(...arg) { return this.exe(TYPE.WARN, [...arguments], { noTrace: true }); } /** * error 错误打印 * * @name e/error * @function * @param {any} args 打印的内容 * @returns {null} */ function error(...arg) { return this.exe(TYPE.ERROR, [...arguments]); } /** * error 调试打印 * * 不带堆栈 * @name en/errorNoTrace * @function * @param {any} args 打印的内容 * @returns {null} */ function errorNoTrace(...arg) { return this.exe(TYPE.ERROR, [...arguments], { noTrace: true }); } /********************************************************************************** * 模块按照级别输出形式 ********************************************************************************** */ /** * mTrace 堆栈打印 (模块化) * * @name mt/mTrace * @function * @param {any} args 打印的内容 * @returns {null} */ function mTrace(...arg) { return this._mExecute(TYPE.TRACE, [...arguments]); } /** * mDebug 调试打印 (模块化) * * @name md/mDebug * @function * @param {any} args 打印的内容 * @returns {null} */ function mDebug(...arg) { return this._mExecute(TYPE.DEBUG, [...arguments]); } /** * mInfo 信息打印 (模块化) * * @name mi/mInfo * @function * @param {any} args 打印的内容 * @returns {null} */ function mInfo(...arg) { return this._mExecute(TYPE.INFO, [...arguments]); } /** * mLog 日志打印 (模块化) * * 原生的控制台打印 * @name ml/mLog * @function * @param {any} args 打印的内容 * @returns {null} */ function mLog(...arg) { return this._mExecute(TYPE.LOG, [...arguments]); } /** * mSuccess 成功打印 (模块化) * * @name ms/mSuccess * @function * @param {any} args 打印的内容 * @returns {null} */ function mSuccess(...arg) { return this._mExecute(TYPE.SUCCESS, [...arguments]); } /** * mTime 调试打印 (模块化) * * @name mtt/mTime * @function * @param {any} args 打印的内容 * @returns {null} */ function mTime(...arg) { return this._mExecute(TYPE.TIME, [...arguments]); } /** * mTable 表格打印 (模块化) * * @name mT/mTable * @function * @param {any} args 打印的内容 * @returns {null} */ function mTable(...arg) { return this._mExecute(TYPE.TABLE, [...arguments]); } /** * mWarn 告警打印 (模块化) * * @name mw/mWarn * @function * @param {any} args 打印的内容 * @returns {null} */ function mWarn(...arg) { return this._mExecute(TYPE.WARN, [...arguments]); } /** * mWarnNoTrace 调试打印 (模块化) * * 不带堆栈 * @name mwn/mWarnNoTrace * @function * @param {any} args 打印的内容 * @returns {null} */ function mWarnNoTrace(...arg) { return this._mExecute(TYPE.WARN, [...arguments], { noTrace: true }); } /** * mError 调试打印 (模块化) * @name me/mError * @function * @param {any} args 打印的内容 * @returns {null} */ function mError(...arg) { return this._mExecute(TYPE.ERROR, [...arguments]); } /** * mErrorNoTrace 调试打印 (模块化) * * 不带堆栈 * @name men/mErrorNoTrace * @function * @param {any} args 打印的内容 * @returns {null} */ function mErrorNoTrace(...arg) { return this._mExecute(TYPE.ERROR, [...arguments], { noTrace: true }); } /** * autoFillText 动态补全文本 * * 常用于打印类似各种级别的日志 配置配合 tl 使用 * @param {string} text 文本内容 * @param {number} length 长度 默认级别打印的长度设置保持一致 超出长度按照超出的部分显示 * @param {string} aligin 对齐 支持 center,left 和 默认 right * @returns 整合的字段 */ function autoFillText(text, length, aligin = 'right') { let defaultLength = this.option.colorful.maxCharLength; return this._autoFillLength(length || defaultLength, text, aligin); } /** * * 填充文本 (一般是空白) * * @param {number} length 填充的次数 * @param {string} content 填充的内容 * @returns string 填充后的内容 */ function fill(length, content) { return this._fill(length, content); } const instanceSupportFunctions = { // 默认操作 setOption, getOption, auotLogLevel, auotLevel: auotLogLevel, // 文本操作 autoFillText, fill, transTextColorBlock, tb: transTextColorBlock, // 基础操作 trace, debug, info, log: logFn, success, time, table, warn, warnNoTrace, error, errorNoTrace, // 简化操作 t: trace, d: debug, i: info, l: logFn, s: success, tt: time, T: table, w: warn, wn: warnNoTrace, e: error, en: errorNoTrace, // 模块化 mTrace, mDebug, mInfo, mLog, mSuccess, mTime, mTable, mWarn, mWarnNoTrace, mError, mErrorNoTrace, // 简化模块化输出 mt: mTrace, md: mDebug, mi: mInfo, ml: mLog, ms: mSuccess, mtt: mTime, mT: mTable, mw: mWarn, mwn: mWarnNoTrace, me: mError, men: mErrorNoTrace, // // 带颜色的操作 transTextColor, transTextColorAndLog, transLevelTextColor, transLevelTextColorAndLog, transLevelHeaderAndLog, tx: transTextColor, txl: transTextColorAndLog, tl: transLevelTextColor, tll: transLevelTextColorAndLog, tlh: transLevelHeaderAndLog, }; /** * 动态设置 prototype 上的方式 * @ignore * @param {object} instanceSupportFunctions 支持的方法 非箭头函数 */ const initMethonds = (instance) => { for (let key in instanceSupportFunctions) { instance[key] = instanceSupportFunctions[key] } } /** * 日志类 * 创建日志 */ class Logger { /** * Create a Logger * @param {object} option 参考默认 option */ constructor(option) { this.option = { ...defaultOption, ...option }; initMethonds(this); } // 是否缩进 _isIndex(level) { return ![TYPE.TRACE, TYPE.WARN, TYPE.ERROR].includes(level); } // 获取空格间隔 _getSpace(num) { let space = ''; for (let i = 0; i < num; i++) { space += ' '; } return space; } // 获取对齐的字段 _getAlgin(level, algin, maxCharLength) { let length = maxCharLength - level.length; let pre = 0; let suf = 1; if (algin === 'center') { // 除不尽时 前者取消值 后面间隔取大值 pre = Math.floor(length / 2); // 向下取整 suf = Math.ceil(length / 2); // 向上取整 } else { // 靠右对齐 pre = length - 1; } return PLACE_HOLDER + this._getSpace(pre) + level.toLowerCase() + this._getSpace(suf); } // 获取多色的参数显示 _getBroswerColorfulArguments(level) { let { isColorful, colorful, moduleName, dateFormatter } = this.option; let { textAlgin, maxCharLength, index, space, module, dateTime } = colorful; if (!isColorful) return []; let template = ''; let arg = []; // 是否缩进 if (this._isIndex(level)) { template += PLACE_HOLDER + ' '; arg.push(index); } // 不同级别不同间隔和不同的样式 template += this._getAlgin(level, textAlgin, maxCharLength); arg.push(colorful[level.toLowerCase()]); // 添加模块标识 if (moduleName) { template += PLACE_HOLDER + ' ' + PLACE_HOLDER + MODULE_PLACE_HOLDER; arg = arg.concat([space, module, moduleName]); } // 添加time 时间戳标识 if (level === TYPE.TIME) { template += PLACE_HOLDER + ' ' + PLACE_HOLDER + MODULE_PLACE_HOLDER; let dateTimeString = (typeof dateFormatter === 'string') ? formatDate(new Date(), dateFormatter) : dateFormatter(new Date()) arg = arg.concat([space, dateTime, dateTimeString]); } return [template].concat(arg); } _fill(length, fillString = ' ') { let res = []; for (let i = 0; i < length; i++) { res.push(fillString) } return res.join(''); } // 居中时获取前后补充的长度 _getPosition(needFillLength) { // 需要补充的长度 let avg = needFillLength / 2; return [Math.ceil(avg), Math.floor(avg)] } // 动态配置长度 _autoFillLength(length, str, textAlgin = "right") { // 尾部默认一个空格显示漂亮一下 str = str + ' '; let less = length - str.length; // 居中补充 if (textAlgin === 'center') { let [preLength, endLength] = this._getPosition(less); return this._fill(preLength) + str + this._fill(endLength); } if (less <= 0) return str; return textAlgin == 'right' ? this._fill(less) + str : str + this._fill(less); } _getTerminalColorfulArguments(level, options = {}) { let { isColorful, colorful, moduleName, dateFormatter } = this.option; if (!isColorful) return []; let { textAlgin, maxCharLength, space, module } = colorful; let { background, color, index } = colorful[level] || colorful['trace']; let arg = []; // 是否缩进 if (options.noTrace || index) { arg.push(options.noTrace ? colorful.debug.index : index); } // 不同级别不同间隔和不同的样式 let template = this._autoFillLength(maxCharLength, level.toLowerCase(), textAlgin); arg.push(src_chalk.bgHex(background).hex(color)(template)) // 类型标识与后面文案的间距 arg.push(space); // 添加模块标识 if (moduleName) { arg.push(src_chalk.bgHex(module.background).hex(module.color)(' ' + moduleName + ' ')); } // 添加time 时间戳标识 if (level === TYPE.TIME) { let dateTimeString = (typeof dateFormatter === 'string') ? formatDate(new Date(), dateFormatter) : dateFormatter(new Date()) arg = arg.concat([dateTimeString]); } return arg; } // 根据配置和不同环境 不同的输出 TODO 扩展其他情况 _output(type, innerArg, outerArg, options = {}) { let { onLogger, level } = this.option; // 配置的打印级别小于当前打印的级别 if (typeof level === 'number') { // if (level > LEVEL[type]) return; if (level > this.option.LEVEL[type]) return; // 支持动态设置日志级别 } else if (Array.isArray(level)) { if (!level.includes(type)) { return false; } }; // 外部输出 onLogger && onLogger(type, outerArg); let output = this.option.logFn; // 内部打印 if (output) { // node js 下 兼容 error 与 warm 打印堆栈 let foramtType = (!isBroswer && [TYPE.WARN, TYPE.ERROR].includes(type)) && !options.noTrace ? TYPE.TRACE : type; // 兼容浏览器下能打印 debug foramtType = (isBroswer && [TYPE.DEBUG].includes(type)) ? TYPE.INFO : foramtType; let fn = output[foramtType.toLowerCase()] || output[TYPE.INFO]; // 兼容表格直接输出 if (foramtType.toLowerCase() === TYPE.TABLE) { output.table.apply(null, outerArg); } else if (foramtType.toLowerCase() === TYPE.TIME) { output.log.apply(null, innerArg.concat(outerArg)) } else if (foramtType.toLowerCase() === TYPE.LOG) { output.log.apply(null, outerArg) } else { fn.apply(null, innerArg.concat(outerArg)); } } } exe(level, userArg, options) { let arg = isBroswer ? this._getBroswerColorfulArguments(level) : this._getTerminalColorfulArguments(level, options); this._output(level, arg, userArg, options); return null; } _mExecute(level, userArg, options = {}) { this.option.moduleName = userArg[0]; let fn = level.toLowerCase() + (options.noTrace ? 'NoTrace' : ''); this[fn] && this[fn].apply(this, userArg.slice(1, userArg.length)); this.option.moduleName = ''; } } // autoAppendClassFn(fns); /** * 创建日志实例 * * @function * @description * 1. 第一次引入 默认创建实例 * 2. 后续导入 直接返回第一次创建的实例 * * @param {Object} option 详细参数参考 option * @returns {object} logInstance 日志实例 */ const create = function (option) { let namespace = option.bindGlobalName; if (!(0,index_bundle.isBindToGlobal)(namespace)) { return (0,index_bundle.bindToGlobal)(namespace, new Logger(option || {})) } return (0,index_bundle.getbindData)(namespace); } /** * 默认自动创建实例 * * @constant * @description * * 默认会挂载全局 直接通过 log 来使用 * */ const log = create(defaultOption); /* harmony default export */ const src = (log); })(); /******/ return __webpack_exports__; /******/ })() ; }); //# sourceMappingURL=index-bundle.js.map