@qlover/logger
Advanced tools
| "use strict";var qloverLogger=(()=>{var d=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var T=(n,t)=>{for(var e in t)d(n,e,{get:t[e],enumerable:!0})},F=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of w(t))!y.call(n,r)&&r!==e&&d(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var I=n=>F(d({},"__esModule",{value:!0}),n);var O={};T(O,{ConsoleHandler:()=>x,LogContext:()=>p,LogEvent:()=>m,Logger:()=>g,TimestampFormatter:()=>h,defaultLevels:()=>b});var m=class{constructor(t,e,o,r){this.level=t;this.args=e;this.loggerName=o;this.context=r;this.timestamp=Date.now()}timestamp};var p=class{constructor(t){this.value=t}};var b={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},g=class{constructor(t={}){this.options=t;t.name=t.name||Date.now().toString(),t.levels=t.levels||b,t.handlers=Array.isArray(t.handlers)?t.handlers:t.handlers?[t.handlers]:[]}addAppender(t){this.options.handlers.push(t)}context(t){return new p(t)}print(t,e){let{levels:o,level:r,silent:i,handlers:a}=this.options;if(i)return;let l=e.slice(-1)[0],c=e.length>1&&l instanceof p;if(l=c?l:void 0,e=c?e.slice(0,-1):e,t=l?.value?.level??t,r&&o){let s=o[r],v=o[t];if(s!=null&&v!=null&&v>s)return}let f=new m(t,e,this.options.name,l),u=Array.isArray(a)?a:[a];for(let s of u)s&&s.append(f)}log(...t){this.print("info",t)}fatal(...t){this.print("fatal",t)}error(...t){this.print("error",t)}warn(...t){this.print("warn",t)}info(...t){this.print("info",t)}debug(...t){this.print("debug",t)}trace(...t){this.print("trace",t)}};var x=class{constructor(t=null){this.formatter=t}setFormatter(t){this.formatter=t}append(t){let{level:e,args:o,loggerName:r}=t,i=this.formatter?this.formatter.format(t):[r?`[${r}]`:null,...o].filter(a=>a!=null);(console[e]||console.log)(...Array.isArray(i)?i:[i])}};var L={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},k="[{loggerName}] [{formattedTimestamp} {level}]",h=class{constructor(t={}){this.options=t}updateOptions(t){this.options={...this.options,...t}}replacePrefix(t,e){return t.replace(/\{([^{}]+)\}/g,(o,r)=>r in e?String(e[r]??""):"")}format({timestamp:t,level:e,args:o,context:r,loggerName:i}){let{locale:a="zh-CN",localeOptions:l,prefixTemplate:c=k}=this.options,f=r?.formatType??"datetime",u=f==="date"?"toLocaleDateString":f==="time"?"toLocaleTimeString":"toLocaleString",s=new Date(t)[u](a,{...L,...l});return[this.replacePrefix(c,{...r,timestamp:t.toString(),level:e,loggerName:i,formattedTimestamp:s,locale:a}),...o]}};return I(O);})(); |
+23
-0
| # @qlover/logger | ||
| ## 1.1.0 | ||
| ### Minor Changes | ||
| #### ✨ Features | ||
| - **logger:** add updateOptions method to TimestampFormatter for dynamic configuration ([341a305](https://github.com/qlover/fe-base/commit/341a305fe44bcb8cac5a22da6fa3e8632d874921)) ([#588](https://github.com/qlover/fe-base/pull/588)) | ||
| - Implemented the `updateOptions` method in `TimestampFormatter` to allow runtime updates of locale, prefix template, and locale options. | ||
| - Enhanced tests to verify the functionality of `updateOptions`, ensuring correct behavior when changing formatting options dynamically. | ||
| - Updated documentation to include details about the new method and its usage examples, improving clarity for developers. | ||
| These changes aim to enhance the flexibility of the logging system by allowing real-time adjustments to formatting settings. | ||
| #### ♻️ Refactors | ||
| - **logger:** prepend logger name to console output and update tests ([dc894bd](https://github.com/qlover/fe-base/commit/dc894bd06e76c10218a7ba632f5f0a6b412363bb)) ([#588](https://github.com/qlover/fe-base/pull/588)) | ||
| - Updated ConsoleHandler and Logger tests to prepend the logger name to console output for better context in logs. | ||
| - Modified TimestampFormatter to include the logger name in formatted output. | ||
| - Enhanced documentation to reflect changes in output formatting and behavior. | ||
| - Added handling for unknown variables in prefix templates to prevent errors during logging. | ||
| These changes aim to improve log clarity and maintainability by ensuring consistent output formatting across the logging system. | ||
| ## 1.0.0 | ||
@@ -4,0 +27,0 @@ |
+1
-1
@@ -1,1 +0,1 @@ | ||
| "use strict";var d=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var I=(n,t)=>{for(var e in t)d(n,e,{get:t[e],enumerable:!0})},T=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of w(t))!y.call(n,r)&&r!==e&&d(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var F=n=>T(d({},"__esModule",{value:!0}),n);var k={};I(k,{ConsoleHandler:()=>g,LogContext:()=>s,LogEvent:()=>p,Logger:()=>x,TimestampFormatter:()=>h,defaultLevels:()=>b});module.exports=F(k);var p=class{constructor(t,e,o,r){this.level=t;this.args=e;this.loggerName=o;this.context=r;this.timestamp=Date.now()}timestamp};var s=class{constructor(t){this.value=t}};var b={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},x=class{constructor(t={}){this.options=t;t.name=t.name||Date.now().toString(),t.levels=t.levels||b,t.handlers=Array.isArray(t.handlers)?t.handlers:t.handlers?[t.handlers]:[]}addAppender(t){this.options.handlers.push(t)}context(t){return new s(t)}print(t,e){let{levels:o,level:r,silent:f,handlers:l}=this.options;if(f)return;let a=e.slice(-1)[0],c=e.length>1&&a instanceof s;if(a=c?a:void 0,e=c?e.slice(0,-1):e,t=a?.value?.level??t,r&&o){let i=o[r],v=o[t];if(i!=null&&v!=null&&v>i)return}let m=new p(t,e,this.options.name,a),u=Array.isArray(l)?l:[l];for(let i of u)i&&i.append(m)}log(...t){this.print("info",t)}fatal(...t){this.print("fatal",t)}error(...t){this.print("error",t)}warn(...t){this.print("warn",t)}info(...t){this.print("info",t)}debug(...t){this.print("debug",t)}trace(...t){this.print("trace",t)}};var g=class{constructor(t=null){this.formatter=t}setFormatter(t){this.formatter=t}append(t){let{level:e,args:o}=t,r=this.formatter?this.formatter.format(t):o;(console[e]||console.log)(...Array.isArray(r)?r:[r])}};var L={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},h=class{constructor(t={}){this.options=t}replacePrefix(t,e){return t.replace(/\{([^{}]+)\}/g,(o,r)=>e[r]||o)}format({timestamp:t,level:e,args:o,context:r,loggerName:f}){let{locale:l="zh-CN",localeOptions:a,prefixTemplate:c="[{formattedTimestamp} {level}]"}=this.options,m=r?.formatType??"datetime",u=m==="date"?"toLocaleDateString":m==="time"?"toLocaleTimeString":"toLocaleString",i=new Date(t)[u](l,{...L,...a});return[this.replacePrefix(c,{...r,timestamp:t.toString(),level:e,loggerName:f,formattedTimestamp:i,locale:l}),...o]}};0&&(module.exports={ConsoleHandler,LogContext,LogEvent,Logger,TimestampFormatter,defaultLevels}); | ||
| "use strict";var d=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var T=(n,t)=>{for(var e in t)d(n,e,{get:t[e],enumerable:!0})},F=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of w(t))!y.call(n,r)&&r!==e&&d(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var I=n=>F(d({},"__esModule",{value:!0}),n);var O={};T(O,{ConsoleHandler:()=>x,LogContext:()=>p,LogEvent:()=>m,Logger:()=>g,TimestampFormatter:()=>h,defaultLevels:()=>b});module.exports=I(O);var m=class{constructor(t,e,o,r){this.level=t;this.args=e;this.loggerName=o;this.context=r;this.timestamp=Date.now()}timestamp};var p=class{constructor(t){this.value=t}};var b={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},g=class{constructor(t={}){this.options=t;t.name=t.name||Date.now().toString(),t.levels=t.levels||b,t.handlers=Array.isArray(t.handlers)?t.handlers:t.handlers?[t.handlers]:[]}addAppender(t){this.options.handlers.push(t)}context(t){return new p(t)}print(t,e){let{levels:o,level:r,silent:i,handlers:a}=this.options;if(i)return;let l=e.slice(-1)[0],c=e.length>1&&l instanceof p;if(l=c?l:void 0,e=c?e.slice(0,-1):e,t=l?.value?.level??t,r&&o){let s=o[r],v=o[t];if(s!=null&&v!=null&&v>s)return}let f=new m(t,e,this.options.name,l),u=Array.isArray(a)?a:[a];for(let s of u)s&&s.append(f)}log(...t){this.print("info",t)}fatal(...t){this.print("fatal",t)}error(...t){this.print("error",t)}warn(...t){this.print("warn",t)}info(...t){this.print("info",t)}debug(...t){this.print("debug",t)}trace(...t){this.print("trace",t)}};var x=class{constructor(t=null){this.formatter=t}setFormatter(t){this.formatter=t}append(t){let{level:e,args:o,loggerName:r}=t,i=this.formatter?this.formatter.format(t):[r?`[${r}]`:null,...o].filter(a=>a!=null);(console[e]||console.log)(...Array.isArray(i)?i:[i])}};var L={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},k="[{loggerName}] [{formattedTimestamp} {level}]",h=class{constructor(t={}){this.options=t}updateOptions(t){this.options={...this.options,...t}}replacePrefix(t,e){return t.replace(/\{([^{}]+)\}/g,(o,r)=>r in e?String(e[r]??""):"")}format({timestamp:t,level:e,args:o,context:r,loggerName:i}){let{locale:a="zh-CN",localeOptions:l,prefixTemplate:c=k}=this.options,f=r?.formatType??"datetime",u=f==="date"?"toLocaleDateString":f==="time"?"toLocaleTimeString":"toLocaleString",s=new Date(t)[u](a,{...L,...l});return[this.replacePrefix(c,{...r,timestamp:t.toString(),level:e,loggerName:i,formattedTimestamp:s,locale:a}),...o]}};0&&(module.exports={ConsoleHandler,LogContext,LogEvent,Logger,TimestampFormatter,defaultLevels}); |
+41
-10
@@ -437,3 +437,3 @@ // src/interface/LogEvent.ts | ||
| * const handler = new ConsoleHandler(); | ||
| * // Output: Raw message without formatting | ||
| * // Output: [loggerName] + raw message (logger name omitted if empty) | ||
| * ``` | ||
@@ -544,3 +544,3 @@ * | ||
| * }); | ||
| * // Console output: Application started | ||
| * // Console output: [app] Application started | ||
| * | ||
@@ -557,3 +557,3 @@ * // Message with context | ||
| * }); | ||
| * // Console output: Database connection failed { host: 'localhost', ... } | ||
| * // Console output: [db] Database connection failed { host: 'localhost', ... } | ||
| * ``` | ||
@@ -616,4 +616,6 @@ * | ||
| append(event) { | ||
| const { level, args } = event; | ||
| const formattedArgs = this.formatter ? this.formatter.format(event) : args; | ||
| const { level, args, loggerName } = event; | ||
| const formattedArgs = this.formatter ? this.formatter.format(event) : [loggerName ? `[${loggerName}]` : null, ...args].filter( | ||
| (x) => x != null | ||
| ); | ||
| (console[level] || console.log)(...Array.isArray(formattedArgs) ? formattedArgs : [formattedArgs]); | ||
@@ -631,2 +633,3 @@ } | ||
| }; | ||
| var defaultPrefixTemplate = "[{loggerName}] [{formattedTimestamp} {level}]"; | ||
| var TimestampFormatter = class { | ||
@@ -650,10 +653,35 @@ /** | ||
| /** | ||
| * Updates formatter options at runtime. | ||
| * Merges the given partial options into the current options; subsequent formatting uses the updated values. | ||
| * | ||
| * @param partial - Partial options to merge (e.g. locale, prefixTemplate, localeOptions) | ||
| * @since 1.1.0 | ||
| * | ||
| * @example Update locale at runtime | ||
| * ```typescript | ||
| * const formatter = new TimestampFormatter({ locale: 'zh-CN' }); | ||
| * // later: switch to English | ||
| * formatter.updateOptions({ locale: 'en-US' }); | ||
| * ``` | ||
| * | ||
| * @example Update multiple options | ||
| * ```typescript | ||
| * formatter.updateOptions({ | ||
| * locale: 'ja-JP', | ||
| * localeOptions: { timeZone: 'Asia/Tokyo', hour12: false } | ||
| * }); | ||
| * ``` | ||
| */ | ||
| updateOptions(partial) { | ||
| this.options = { ...this.options, ...partial }; | ||
| } | ||
| /** | ||
| * Replaces template variables in the prefix string with actual values | ||
| * | ||
| * This internal method handles the variable substitution in prefix templates, | ||
| * replacing placeholders like {timestamp} with their corresponding values. | ||
| * Placeholders like {timestamp} are replaced with values from vars. | ||
| * Unknown or missing variables are skipped (replaced with empty string), not left as literal. | ||
| * | ||
| * @param template - The template string containing variables in curly braces | ||
| * @param vars - Object containing variable names and their values | ||
| * @returns The template string with all variables replaced | ||
| * @returns The template string with known variables replaced, unknowns removed | ||
| * | ||
@@ -676,3 +704,6 @@ * @example Internal usage | ||
| replacePrefix(template, vars) { | ||
| return template.replace(/\{([^{}]+)\}/g, (match, p1) => vars[p1] || match); | ||
| return template.replace( | ||
| /\{([^{}]+)\}/g, | ||
| (_match, p1) => p1 in vars ? String(vars[p1] ?? "") : "" | ||
| ); | ||
| } | ||
@@ -727,3 +758,3 @@ /** | ||
| localeOptions, | ||
| prefixTemplate = "[{formattedTimestamp} {level}]" | ||
| prefixTemplate = defaultPrefixTemplate | ||
| } = this.options; | ||
@@ -730,0 +761,0 @@ const formatType = context?.formatType ?? "datetime"; |
+1
-1
| { | ||
| "name": "@qlover/logger", | ||
| "version": "1.0.0", | ||
| "version": "1.1.0", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "private": false, |
| "use strict";var qloverLogger=(()=>{var d=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var I=(n,t)=>{for(var e in t)d(n,e,{get:t[e],enumerable:!0})},T=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of w(t))!y.call(n,r)&&r!==e&&d(n,r,{get:()=>t[r],enumerable:!(o=C(t,r))||o.enumerable});return n};var F=n=>T(d({},"__esModule",{value:!0}),n);var k={};I(k,{ConsoleHandler:()=>g,LogContext:()=>s,LogEvent:()=>p,Logger:()=>x,TimestampFormatter:()=>h,defaultLevels:()=>b});var p=class{constructor(t,e,o,r){this.level=t;this.args=e;this.loggerName=o;this.context=r;this.timestamp=Date.now()}timestamp};var s=class{constructor(t){this.value=t}};var b={fatal:0,error:10,warn:20,info:30,debug:40,trace:50,log:60},x=class{constructor(t={}){this.options=t;t.name=t.name||Date.now().toString(),t.levels=t.levels||b,t.handlers=Array.isArray(t.handlers)?t.handlers:t.handlers?[t.handlers]:[]}addAppender(t){this.options.handlers.push(t)}context(t){return new s(t)}print(t,e){let{levels:o,level:r,silent:f,handlers:l}=this.options;if(f)return;let a=e.slice(-1)[0],c=e.length>1&&a instanceof s;if(a=c?a:void 0,e=c?e.slice(0,-1):e,t=a?.value?.level??t,r&&o){let i=o[r],v=o[t];if(i!=null&&v!=null&&v>i)return}let m=new p(t,e,this.options.name,a),u=Array.isArray(l)?l:[l];for(let i of u)i&&i.append(m)}log(...t){this.print("info",t)}fatal(...t){this.print("fatal",t)}error(...t){this.print("error",t)}warn(...t){this.print("warn",t)}info(...t){this.print("info",t)}debug(...t){this.print("debug",t)}trace(...t){this.print("trace",t)}};var g=class{constructor(t=null){this.formatter=t}setFormatter(t){this.formatter=t}append(t){let{level:e,args:o}=t,r=this.formatter?this.formatter.format(t):o;(console[e]||console.log)(...Array.isArray(r)?r:[r])}};var L={hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC"},h=class{constructor(t={}){this.options=t}replacePrefix(t,e){return t.replace(/\{([^{}]+)\}/g,(o,r)=>e[r]||o)}format({timestamp:t,level:e,args:o,context:r,loggerName:f}){let{locale:l="zh-CN",localeOptions:a,prefixTemplate:c="[{formattedTimestamp} {level}]"}=this.options,m=r?.formatType??"datetime",u=m==="date"?"toLocaleDateString":m==="time"?"toLocaleTimeString":"toLocaleString",i=new Date(t)[u](l,{...L,...a});return[this.replacePrefix(c,{...r,timestamp:t.toString(),level:e,loggerName:f,formattedTimestamp:i,locale:l}),...o]}};return F(k);})(); |
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
124597
3.31%3372
1.69%