app-lib-log
Version:
个人日志组件 -【app-lib-log】
1,557 lines (1,329 loc) • 44 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("app-lib-global"));
else if(typeof define === 'function' && define.amd)
define(["app-lib-global"], factory);
else {
var a = typeof exports === 'object' ? factory(require("app-lib-global")) : factory(root["app-lib-global"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, (__WEBPACK_EXTERNAL_MODULE__144__) => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 144:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE__144__;
/***/ })
/******/ });
/************************************************************************/
/******/ // 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](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 isolated against other modules in the chunk.
(() => {
// 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: external "app-lib-global"
var external_app_lib_global_ = __webpack_require__(144);
;// 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,external_app_lib_global_.isBroswerEnv)();
/**
* @ignore
* 环境变量
*/
const env = (0,external_app_lib_global_.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,external_app_lib_global_.isBindToGlobal)(namespace)) {
return (0,external_app_lib_global_.bindToGlobal)(namespace, new Logger(option || {}))
}
return (0,external_app_lib_global_.getbindData)(namespace);
}
/**
* 默认自动创建实例
*
* @constant
* @description
* * 默认会挂载全局 直接通过 log 来使用
*
*/
const log = create(defaultOption);
/* harmony default export */ const src = (log);
})();
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=index.js.map