1- import { DEFAULT_TAGS , type TagConfig , type BuiltinTag } from "./lib/tags" ;
1+ import { DEFAULT_TAGS , TagConfig , BuiltinTag } from "./lib/tags" ;
22import { buildPrefix , formatData } from "./utils/formatter" ;
3- import type { FgColor , BgColor } from "./utils/colors" ;
3+ import { FgColor , BgColor } from "./utils/colors" ;
44
55// ─── Types ────────────────────────────────────────────────────────────────────
66
@@ -49,19 +49,66 @@ export interface LoggerOptions {
4949 tags ?: Record < string , TagConfig > ;
5050}
5151
52+ // ─── Environment ──────────────────────────────────────────────────────────────
53+
54+ const isBrowser = typeof window !== "undefined" ;
55+
56+ // ─── Browser dispatch ─────────────────────────────────────────────────────────
57+
58+ /**
59+ * In browser environments, ANSI codes don't render.
60+ * Use CSS-styled console groups instead.
61+ */
62+ function dispatchBrowser (
63+ tag : string ,
64+ args : unknown [ ] ,
65+ level : TagConfig [ "level" ] ,
66+ timestamp : boolean ,
67+ ) : void {
68+ const time = timestamp ? `${ new Date ( ) . toISOString ( ) } ` : "" ;
69+ const label = `${ time } [${ tag . toUpperCase ( ) } ]` ;
70+
71+ const styles : Record < string , string > = {
72+ error : "color:#ff4d4f;font-weight:bold" ,
73+ warn : "color:#faad14;font-weight:bold" ,
74+ info : "color:#1890ff;font-weight:bold" ,
75+ debug : "color:#722ed1;font-weight:bold" ,
76+ log : "color:#13c2c2;font-weight:bold" ,
77+ } ;
78+
79+ const style = styles [ level ] ?? styles . log ;
80+
81+ switch ( level ) {
82+ case "info" :
83+ console . info ( `%c${ label } ` , style , ...args ) ;
84+ break ;
85+ case "warn" :
86+ console . warn ( `%c${ label } ` , style , ...args ) ;
87+ break ;
88+ case "error" :
89+ console . error ( `%c${ label } ` , style , ...args ) ;
90+ break ;
91+ case "debug" :
92+ console . debug ( `%c${ label } ` , style , ...args ) ;
93+ break ;
94+ default :
95+ console . log ( `%c${ label } ` , style , ...args ) ;
96+ break ;
97+ }
98+ }
99+
52100// ─── Factory ──────────────────────────────────────────────────────────────────
53101
54102/**
55103 * Creates a pretty-log instance with optional configuration.
56104 *
57- * All tag methods are auto-generated via a Proxy, so any dot-access
58- * becomes a scoped logger: `logger.user(data)`, `logger.payment(data)`, etc.
105+ * Works in both Node.js (ANSI colors) and browser (CSS-styled console).
59106 *
60107 * @example
61108 * const clog = createLogger();
62- * clog.user({ id: 1 }); // [timestamp] USER { id: 1 }
63- * clog.error('Something broke'); // [timestamp] ERROR Something broke
64- * clog.myTag('custom stuff'); // [timestamp] MYTAG custom stuff
109+ * clog.user({ id: 1 });
110+ * clog.error('Something broke');
111+ * clog.myTag('custom stuff');
65112 */
66113export function createLogger ( options : LoggerOptions = { } ) : PrettyLogger {
67114 const { timestamp = true , silent = false , tags : customTags = { } } = options ;
@@ -71,9 +118,6 @@ export function createLogger(options: LoggerOptions = {}): PrettyLogger {
71118 ...customTags ,
72119 } ;
73120
74- /**
75- * Core log dispatch — called by every tag method.
76- */
77121 function dispatch ( tag : string , args : unknown [ ] ) : void {
78122 if ( silent ) return ;
79123
@@ -83,14 +127,20 @@ export function createLogger(options: LoggerOptions = {}): PrettyLogger {
83127 level : "log" ,
84128 } ;
85129
130+ // Browser — use CSS-styled console
131+ if ( isBrowser ) {
132+ dispatchBrowser ( tag , args , config . level , timestamp ) ;
133+ return ;
134+ }
135+
136+ // Node.js — use ANSI colors
86137 const prefix = timestamp
87138 ? buildPrefix ( tag , config . fg , config . bg )
88139 : buildPrefix ( tag , config . fg , config . bg ) . replace ( / ^ \S + \s / , "" ) ;
89140
90141 const formatted = args . map ( ( a ) => formatData ( a ) ) . join ( " " ) ;
91142 const line = `${ prefix } ${ formatted } ` ;
92143
93- // Route to the right console method
94144 switch ( config . level ) {
95145 case "info" :
96146 console . info ( line ) ;
@@ -110,10 +160,6 @@ export function createLogger(options: LoggerOptions = {}): PrettyLogger {
110160 }
111161 }
112162
113- /**
114- * Proxy intercepts any property access and returns a log function
115- * bound to that property name as the tag.
116- */
117163 return new Proxy ( { } as PrettyLogger , {
118164 get ( _target , prop : string ) {
119165 return ( ...args : unknown [ ] ) => dispatch ( prop , args ) ;
@@ -127,7 +173,7 @@ export function createLogger(options: LoggerOptions = {}): PrettyLogger {
127173 * Ready-to-use logger instance with default settings.
128174 *
129175 * @example
130- * import { clog } from 'pretty-log';
176+ * import { clog } from 'pretty-log-tagged ';
131177 * clog.user({ id: 1 });
132178 * clog.error('Oops');
133179 */
0 commit comments