@mks2508/better-logger 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/dist/Logger.d.ts.map +1 -0
- package/dist/ScopedLogger.d.ts.map +1 -0
- package/dist/chunks/{Logger-D8pK7XXt.js → Logger-C9zTFYBh.js} +2 -2
- package/dist/chunks/Logger-C9zTFYBh.js.map +1 -0
- package/dist/chunks/{Logger-CTAaDeZi.js → Logger-Th9SfADL.js} +3 -3
- package/dist/chunks/Logger-Th9SfADL.js.map +1 -0
- package/dist/chunks/{ScopedLogger-D-7q8uVP.js → ScopedLogger-HgV_J-ug.js} +2 -2
- package/dist/chunks/{ScopedLogger-D-7q8uVP.js.map → ScopedLogger-HgV_J-ug.js.map} +1 -1
- package/dist/chunks/{ScopedLogger-hS0qSkZD.js → ScopedLogger-uAAeJkfA.js} +2 -2
- package/dist/chunks/{ScopedLogger-hS0qSkZD.js.map → ScopedLogger-uAAeJkfA.js.map} +1 -1
- package/dist/chunks/environment-5I5unY89.js +4 -0
- package/dist/chunks/environment-5I5unY89.js.map +1 -0
- package/dist/chunks/{environment-Bxbnw4pd.js → environment-wXLQvk5g.js} +103 -11
- package/dist/chunks/environment-wXLQvk5g.js.map +1 -0
- package/dist/chunks/formatting-CiFnwe1I.js +2 -0
- package/dist/chunks/formatting-CiFnwe1I.js.map +1 -0
- package/dist/chunks/formatting-DIhpRCCk.js +380 -0
- package/dist/chunks/formatting-DIhpRCCk.js.map +1 -0
- package/dist/cli/CommandProcessor.d.ts.map +1 -0
- package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
- package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
- package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
- package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
- package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/{types/constants.d.ts → constants.d.ts} +108 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +127 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +6 -5
- package/dist/core.js.map +1 -1
- package/dist/example.d.ts.map +1 -0
- package/dist/exports-module.d.ts.map +1 -0
- package/dist/exports.cjs +1 -1
- package/dist/exports.js +2 -2
- package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
- package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
- package/dist/handlers/FileLogHandler.d.ts.map +1 -0
- package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +124 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -5
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -0
- package/dist/styling/LogStyleBuilder.d.ts.map +1 -0
- package/dist/styling/SemanticStyles.d.ts.map +1 -0
- package/dist/styling/SmartPresets.d.ts.map +1 -0
- package/dist/styling/StyleBuilder.d.ts.map +1 -0
- package/dist/styling/banners.d.ts.map +1 -0
- package/dist/styling/index.d.ts.map +1 -0
- package/dist/styling/themes.d.ts.map +1 -0
- package/dist/styling-module.d.ts.map +1 -0
- package/dist/styling.cjs +1 -1
- package/dist/styling.js +3 -3
- package/dist/types/core.d.ts +229 -122
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/handlers.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -119
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/ansi-colors.d.ts +156 -0
- package/dist/utils/ansi-colors.d.ts.map +1 -0
- package/dist/utils/environment.d.ts.map +1 -0
- package/dist/{types/utils → utils}/formatting.d.ts +22 -1
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/{types/utils → utils}/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/opentui-detection.d.ts.map +1 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/stackTrace.d.ts.map +1 -0
- package/dist/utils/timestamps.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/Logger.ts +3 -6
- package/src/constants.ts +131 -1
- package/src/core.ts +11 -7
- package/src/handlers/ExportLogHandler.ts +2 -1
- package/src/index.ts +30 -2
- package/src/styling/SemanticStyles.ts +1 -1
- package/src/types/core.ts +15 -1
- package/src/types/index.ts +1 -0
- package/src/utils/ansi-colors.ts +333 -0
- package/src/utils/formatting.ts +196 -6
- package/src/utils/index.ts +23 -11
- package/vite.config.ts +1 -1
- package/dist/chunks/Logger-CTAaDeZi.js.map +0 -1
- package/dist/chunks/Logger-D8pK7XXt.js.map +0 -1
- package/dist/chunks/environment-Bxbnw4pd.js.map +0 -1
- package/dist/chunks/environment-Dm66zOML.js +0 -4
- package/dist/chunks/environment-Dm66zOML.js.map +0 -1
- package/dist/chunks/formatting-C0riPC5_.js +0 -95
- package/dist/chunks/formatting-C0riPC5_.js.map +0 -1
- package/dist/chunks/formatting-DNCAV66-.js +0 -2
- package/dist/chunks/formatting-DNCAV66-.js.map +0 -1
- package/dist/types/Logger.d.ts.map +0 -1
- package/dist/types/ScopedLogger.d.ts.map +0 -1
- package/dist/types/cli/CommandProcessor.d.ts.map +0 -1
- package/dist/types/cli/commands/ConfigCommand.d.ts.map +0 -1
- package/dist/types/cli/commands/ExportCommand.d.ts.map +0 -1
- package/dist/types/cli/commands/HistoryCommand.d.ts.map +0 -1
- package/dist/types/cli/commands/StatusCommand.d.ts.map +0 -1
- package/dist/types/cli/commands/ThemeCommand.d.ts.map +0 -1
- package/dist/types/cli/help.d.ts.map +0 -1
- package/dist/types/cli/index.d.ts.map +0 -1
- package/dist/types/constants.d.ts.map +0 -1
- package/dist/types/example.d.ts.map +0 -1
- package/dist/types/exports-module.d.ts.map +0 -1
- package/dist/types/handlers/AnalyticsLogHandler.d.ts.map +0 -1
- package/dist/types/handlers/ExportLogHandler.d.ts.map +0 -1
- package/dist/types/handlers/FileLogHandler.d.ts.map +0 -1
- package/dist/types/handlers/RemoteLogHandler.d.ts.map +0 -1
- package/dist/types/handlers/index.d.ts.map +0 -1
- package/dist/types/main.d.ts.map +0 -1
- package/dist/types/styling/LogStyleBuilder.d.ts.map +0 -1
- package/dist/types/styling/SemanticStyles.d.ts.map +0 -1
- package/dist/types/styling/SmartPresets.d.ts.map +0 -1
- package/dist/types/styling/StyleBuilder.d.ts.map +0 -1
- package/dist/types/styling/banners.d.ts.map +0 -1
- package/dist/types/styling/index.d.ts.map +0 -1
- package/dist/types/styling/themes.d.ts.map +0 -1
- package/dist/types/styling-module.d.ts.map +0 -1
- package/dist/types/types/core.d.ts +0 -221
- package/dist/types/types/core.d.ts.map +0 -1
- package/dist/types/types/handlers.d.ts.map +0 -1
- package/dist/types/types/index.d.ts +0 -7
- package/dist/types/types/index.d.ts.map +0 -1
- package/dist/types/utils/environment.d.ts.map +0 -1
- package/dist/types/utils/formatting.d.ts.map +0 -1
- package/dist/types/utils/index.d.ts.map +0 -1
- package/dist/types/utils/opentui-detection.d.ts.map +0 -1
- package/dist/types/utils/output.d.ts.map +0 -1
- package/dist/types/utils/stackTrace.d.ts.map +0 -1
- package/dist/types/utils/timestamps.d.ts.map +0 -1
- /package/dist/{types/Logger.d.ts → Logger.d.ts} +0 -0
- /package/dist/{types/ScopedLogger.d.ts → ScopedLogger.d.ts} +0 -0
- /package/dist/{types/cli → cli}/CommandProcessor.d.ts +0 -0
- /package/dist/{types/cli → cli}/commands/ConfigCommand.d.ts +0 -0
- /package/dist/{types/cli → cli}/commands/ExportCommand.d.ts +0 -0
- /package/dist/{types/cli → cli}/commands/HistoryCommand.d.ts +0 -0
- /package/dist/{types/cli → cli}/commands/StatusCommand.d.ts +0 -0
- /package/dist/{types/cli → cli}/commands/ThemeCommand.d.ts +0 -0
- /package/dist/{types/cli → cli}/help.d.ts +0 -0
- /package/dist/{types/cli → cli}/index.d.ts +0 -0
- /package/dist/{types/example.d.ts → example.d.ts} +0 -0
- /package/dist/{types/exports-module.d.ts → exports-module.d.ts} +0 -0
- /package/dist/{types/handlers → handlers}/AnalyticsLogHandler.d.ts +0 -0
- /package/dist/{types/handlers → handlers}/ExportLogHandler.d.ts +0 -0
- /package/dist/{types/handlers → handlers}/FileLogHandler.d.ts +0 -0
- /package/dist/{types/handlers → handlers}/RemoteLogHandler.d.ts +0 -0
- /package/dist/{types/handlers → handlers}/index.d.ts +0 -0
- /package/dist/{types/main.d.ts → main.d.ts} +0 -0
- /package/dist/{types/styling → styling}/LogStyleBuilder.d.ts +0 -0
- /package/dist/{types/styling → styling}/SemanticStyles.d.ts +0 -0
- /package/dist/{types/styling → styling}/SmartPresets.d.ts +0 -0
- /package/dist/{types/styling → styling}/StyleBuilder.d.ts +0 -0
- /package/dist/{types/styling → styling}/banners.d.ts +0 -0
- /package/dist/{types/styling → styling}/index.d.ts +0 -0
- /package/dist/{types/styling → styling}/themes.d.ts +0 -0
- /package/dist/{types/styling-module.d.ts → styling-module.d.ts} +0 -0
- /package/dist/types/{types/handlers.d.ts → handlers.d.ts} +0 -0
- /package/dist/{types/utils → utils}/environment.d.ts +0 -0
- /package/dist/{types/utils → utils}/opentui-detection.d.ts +0 -0
- /package/dist/{types/utils → utils}/output.d.ts +0 -0
- /package/dist/{types/utils → utils}/stackTrace.d.ts +0 -0
- /package/dist/{types/utils → utils}/timestamps.d.ts +0 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ANSI color utilities for terminal environments
|
|
3
|
+
* @since 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { LogLevel } from '../types/index.js';
|
|
7
|
+
import { supportsANSIColors } from './environment.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* ANSI color codes for terminal styling
|
|
11
|
+
*/
|
|
12
|
+
export const ANSI_CODES = {
|
|
13
|
+
// Colors
|
|
14
|
+
black: 30,
|
|
15
|
+
red: 31,
|
|
16
|
+
green: 32,
|
|
17
|
+
yellow: 33,
|
|
18
|
+
blue: 34,
|
|
19
|
+
magenta: 35,
|
|
20
|
+
cyan: 36,
|
|
21
|
+
white: 37,
|
|
22
|
+
|
|
23
|
+
// Bright colors
|
|
24
|
+
brightBlack: 90,
|
|
25
|
+
brightRed: 91,
|
|
26
|
+
brightGreen: 92,
|
|
27
|
+
brightYellow: 93,
|
|
28
|
+
brightBlue: 94,
|
|
29
|
+
brightMagenta: 95,
|
|
30
|
+
brightCyan: 96,
|
|
31
|
+
brightWhite: 97,
|
|
32
|
+
|
|
33
|
+
// Background colors
|
|
34
|
+
bgBlack: 40,
|
|
35
|
+
bgRed: 41,
|
|
36
|
+
bgGreen: 42,
|
|
37
|
+
bgYellow: 43,
|
|
38
|
+
bgBlue: 44,
|
|
39
|
+
bgMagenta: 45,
|
|
40
|
+
bgCyan: 46,
|
|
41
|
+
bgWhite: 47,
|
|
42
|
+
|
|
43
|
+
// Background bright colors
|
|
44
|
+
bgBrightBlack: 100,
|
|
45
|
+
bgBrightRed: 101,
|
|
46
|
+
bgBrightGreen: 102,
|
|
47
|
+
bgBrightYellow: 103,
|
|
48
|
+
bgBrightBlue: 104,
|
|
49
|
+
bgBrightMagenta: 105,
|
|
50
|
+
bgBrightCyan: 106,
|
|
51
|
+
bgBrightWhite: 107,
|
|
52
|
+
|
|
53
|
+
// Styles
|
|
54
|
+
reset: 0,
|
|
55
|
+
bold: 1,
|
|
56
|
+
dim: 2,
|
|
57
|
+
italic: 3,
|
|
58
|
+
underline: 4,
|
|
59
|
+
blink: 5,
|
|
60
|
+
inverse: 7,
|
|
61
|
+
hidden: 8,
|
|
62
|
+
strikethrough: 9,
|
|
63
|
+
|
|
64
|
+
// Reset specific
|
|
65
|
+
resetBold: 22,
|
|
66
|
+
resetDim: 22,
|
|
67
|
+
resetItalic: 23,
|
|
68
|
+
resetUnderline: 24,
|
|
69
|
+
resetBlink: 25,
|
|
70
|
+
resetInverse: 27,
|
|
71
|
+
resetHidden: 28,
|
|
72
|
+
resetStrikethrough: 29
|
|
73
|
+
} as const;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* ANSI color presets for different log levels
|
|
77
|
+
*/
|
|
78
|
+
export const ANSI_LEVEL_STYLES: Record<LogLevel | 'success', {
|
|
79
|
+
color: number;
|
|
80
|
+
background?: number;
|
|
81
|
+
styles: number[];
|
|
82
|
+
emoji: string;
|
|
83
|
+
}> = {
|
|
84
|
+
debug: {
|
|
85
|
+
color: ANSI_CODES.brightBlack,
|
|
86
|
+
styles: [ANSI_CODES.dim],
|
|
87
|
+
emoji: '🔍'
|
|
88
|
+
},
|
|
89
|
+
info: {
|
|
90
|
+
color: ANSI_CODES.blue,
|
|
91
|
+
styles: [ANSI_CODES.bold],
|
|
92
|
+
emoji: 'ℹ️'
|
|
93
|
+
},
|
|
94
|
+
warn: {
|
|
95
|
+
color: ANSI_CODES.yellow,
|
|
96
|
+
background: ANSI_CODES.bgYellow,
|
|
97
|
+
styles: [ANSI_CODES.bold, ANSI_CODES.black],
|
|
98
|
+
emoji: '⚠️'
|
|
99
|
+
},
|
|
100
|
+
error: {
|
|
101
|
+
color: ANSI_CODES.red,
|
|
102
|
+
background: ANSI_CODES.bgRed,
|
|
103
|
+
styles: [ANSI_CODES.bold],
|
|
104
|
+
emoji: '❌'
|
|
105
|
+
},
|
|
106
|
+
critical: {
|
|
107
|
+
color: ANSI_CODES.white,
|
|
108
|
+
background: ANSI_CODES.bgRed,
|
|
109
|
+
styles: [ANSI_CODES.bold, ANSI_CODES.blink],
|
|
110
|
+
emoji: '🚨'
|
|
111
|
+
},
|
|
112
|
+
success: {
|
|
113
|
+
color: ANSI_CODES.green,
|
|
114
|
+
background: ANSI_CODES.bgGreen,
|
|
115
|
+
styles: [ANSI_CODES.bold],
|
|
116
|
+
emoji: '✅'
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates an ANSI escape sequence
|
|
122
|
+
*/
|
|
123
|
+
function ansi(code: number | number[]): string {
|
|
124
|
+
const codes = Array.isArray(code) ? code : [code];
|
|
125
|
+
return `\x1b[${codes.join(';')}m`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Applies ANSI styling to text
|
|
130
|
+
*/
|
|
131
|
+
export function ansiStyle(text: string, codes: number[]): string {
|
|
132
|
+
if (!supportsANSIColors()) return text;
|
|
133
|
+
return `${ansi(codes)}${text}${ansi(ANSI_CODES.reset)}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Applies color to text
|
|
138
|
+
*/
|
|
139
|
+
export function ansiColor(text: string, color: number): string {
|
|
140
|
+
return ansiStyle(text, [color]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Applies background color to text
|
|
145
|
+
*/
|
|
146
|
+
export function ansiBackground(text: string, bg: number, color?: number): string {
|
|
147
|
+
if (color) {
|
|
148
|
+
return ansiStyle(text, [color, bg]);
|
|
149
|
+
}
|
|
150
|
+
return ansiStyle(text, [bg]);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Makes text bold
|
|
155
|
+
*/
|
|
156
|
+
export function ansiBold(text: string): string {
|
|
157
|
+
return ansiStyle(text, [ANSI_CODES.bold]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Makes text dim
|
|
162
|
+
*/
|
|
163
|
+
export function ansiDim(text: string): string {
|
|
164
|
+
return ansiStyle(text, [ANSI_CODES.dim]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Underlines text
|
|
169
|
+
*/
|
|
170
|
+
export function ansiUnderline(text: string): string {
|
|
171
|
+
return ansiStyle(text, [ANSI_CODES.underline]);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Specialized formatters for different contexts
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Format timestamp for terminal
|
|
180
|
+
*/
|
|
181
|
+
export function formatTimestampANSI(timestamp: string): string {
|
|
182
|
+
return ansiColor(timestamp, ANSI_CODES.brightBlack);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Format log level for terminal
|
|
187
|
+
*/
|
|
188
|
+
export function formatLogLevelANSI(level: LogLevel, useEmojis: boolean = true): string {
|
|
189
|
+
const style = ANSI_LEVEL_STYLES[level];
|
|
190
|
+
const emoji = useEmojis ? style.emoji : '';
|
|
191
|
+
const label = level.toUpperCase().padEnd(8);
|
|
192
|
+
|
|
193
|
+
if (!supportsANSIColors()) {
|
|
194
|
+
return `${emoji} ${label}`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let codes = [style.color, ...style.styles];
|
|
198
|
+
if (style.background) {
|
|
199
|
+
codes.push(style.background);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return ansiStyle(`${emoji} ${label}`, codes);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Format success message for terminal
|
|
207
|
+
*/
|
|
208
|
+
export function formatSuccessANSI(message: string, useEmojis: boolean = true): string {
|
|
209
|
+
const style = ANSI_LEVEL_STYLES.success;
|
|
210
|
+
const emoji = useEmojis ? style.emoji : '';
|
|
211
|
+
|
|
212
|
+
if (!supportsANSIColors()) {
|
|
213
|
+
return `${emoji} SUCCESS: ${message}`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const prefix = ansiStyle(`${emoji} SUCCESS:`, [style.color, ...style.styles]);
|
|
217
|
+
return `${prefix} ${message}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Format prefix for terminal
|
|
222
|
+
*/
|
|
223
|
+
export function formatPrefixANSI(prefix: string): string {
|
|
224
|
+
if (!supportsANSIColors()) {
|
|
225
|
+
return `[${prefix}]`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return ansiStyle(`[${prefix}]`, [ANSI_CODES.cyan, ANSI_CODES.bold]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Format file location for terminal
|
|
233
|
+
*/
|
|
234
|
+
export function formatLocationANSI(location: string): string {
|
|
235
|
+
if (!supportsANSIColors()) {
|
|
236
|
+
return `(${location})`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return ansiColor(`(${location})`, ANSI_CODES.brightBlack);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Format build-specific messages
|
|
244
|
+
*/
|
|
245
|
+
export const BUILD_FORMATTERS = {
|
|
246
|
+
/**
|
|
247
|
+
* Format compilation step
|
|
248
|
+
*/
|
|
249
|
+
compilation: (step: string, status: 'starting' | 'completed' | 'failed' = 'starting') => {
|
|
250
|
+
const stepText = ansiBold(step);
|
|
251
|
+
|
|
252
|
+
switch (status) {
|
|
253
|
+
case 'starting':
|
|
254
|
+
return `${ansiColor('⚙️', ANSI_CODES.blue)} ${stepText}...`;
|
|
255
|
+
case 'completed':
|
|
256
|
+
return `${ansiColor('✓', ANSI_CODES.green)} ${stepText} ${ansiColor('completed', ANSI_CODES.green)}`;
|
|
257
|
+
case 'failed':
|
|
258
|
+
return `${ansiColor('✗', ANSI_CODES.red)} ${stepText} ${ansiColor('failed', ANSI_CODES.red)}`;
|
|
259
|
+
default:
|
|
260
|
+
return stepText;
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Format warning message
|
|
266
|
+
*/
|
|
267
|
+
warning: (message: string) => {
|
|
268
|
+
return `${ansiColor('⚠', ANSI_CODES.yellow)} ${ansiStyle('Warning:', [ANSI_CODES.yellow, ANSI_CODES.bold])} ${message}`;
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Format error message
|
|
273
|
+
*/
|
|
274
|
+
error: (message: string) => {
|
|
275
|
+
return `${ansiColor('✗', ANSI_CODES.red)} ${ansiStyle('Error:', [ANSI_CODES.red, ANSI_CODES.bold])} ${message}`;
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Format success message
|
|
280
|
+
*/
|
|
281
|
+
success: (message: string) => {
|
|
282
|
+
return `${ansiColor('✓', ANSI_CODES.green)} ${ansiColor(message, ANSI_CODES.green)}`;
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Format info message
|
|
287
|
+
*/
|
|
288
|
+
info: (message: string) => {
|
|
289
|
+
return `${ansiColor('ℹ', ANSI_CODES.blue)} ${message}`;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Terminal-friendly emoji alternatives for environments that don't support them
|
|
295
|
+
*/
|
|
296
|
+
export const EMOJI_ALTERNATIVES = {
|
|
297
|
+
'🔍': '[DEBUG]',
|
|
298
|
+
'ℹ️': '[INFO]',
|
|
299
|
+
'⚠️': '[WARN]',
|
|
300
|
+
'❌': '[ERROR]',
|
|
301
|
+
'🚨': '[CRITICAL]',
|
|
302
|
+
'✅': '[OK]',
|
|
303
|
+
'✓': '[OK]',
|
|
304
|
+
'✗': '[FAIL]',
|
|
305
|
+
'⚙️': '[BUILD]',
|
|
306
|
+
'📦': '[PKG]'
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Replace emojis with text alternatives for non-emoji terminals
|
|
311
|
+
*/
|
|
312
|
+
export function sanitizeEmojis(text: string): string {
|
|
313
|
+
// Check if we're in a terminal that likely supports emojis
|
|
314
|
+
const isModernTerminal = process.env.TERM &&
|
|
315
|
+
(process.env.TERM.includes('xterm') ||
|
|
316
|
+
process.env.TERM.includes('screen') ||
|
|
317
|
+
process.env.TERM.includes('tmux'));
|
|
318
|
+
|
|
319
|
+
const isCI = process.env.CI || process.env.GITHUB_ACTIONS || process.env.JENKINS_URL;
|
|
320
|
+
|
|
321
|
+
// Use emojis if we have a modern terminal and not in CI
|
|
322
|
+
if (isModernTerminal && !isCI) {
|
|
323
|
+
return text;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Replace emojis with text alternatives
|
|
327
|
+
let result = text;
|
|
328
|
+
Object.entries(EMOJI_ALTERNATIVES).forEach(([emoji, alt]) => {
|
|
329
|
+
result = result.replace(new RegExp(emoji, 'g'), alt);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return result;
|
|
333
|
+
}
|
package/src/utils/formatting.ts
CHANGED
|
@@ -2,8 +2,45 @@
|
|
|
2
2
|
* @fileoverview Formatting utilities for Universal Logger
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { LogLevel, StackInfo } from '../types/index.js';
|
|
5
|
+
import type { LogLevel, StackInfo, OutputFormat } from '../types/index.js';
|
|
6
6
|
import { formatTimestamp } from './timestamps.js';
|
|
7
|
+
import { isNode, supportsANSIColors } from './environment.js';
|
|
8
|
+
import {
|
|
9
|
+
formatLogLevelANSI,
|
|
10
|
+
formatTimestampANSI,
|
|
11
|
+
formatPrefixANSI,
|
|
12
|
+
formatLocationANSI,
|
|
13
|
+
sanitizeEmojis,
|
|
14
|
+
BUILD_FORMATTERS
|
|
15
|
+
} from './ansi-colors.js';
|
|
16
|
+
|
|
17
|
+
// Re-export the type for convenience
|
|
18
|
+
export type { OutputFormat } from '../types/index.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates output based on environment and format preference
|
|
22
|
+
*/
|
|
23
|
+
export function createOutput(
|
|
24
|
+
level: LogLevel,
|
|
25
|
+
message: string,
|
|
26
|
+
prefix?: string,
|
|
27
|
+
stackInfo?: StackInfo | null,
|
|
28
|
+
format: OutputFormat = 'auto'
|
|
29
|
+
): string {
|
|
30
|
+
const detectedFormat = format === 'auto' ? detectOptimalFormat() : format;
|
|
31
|
+
|
|
32
|
+
switch (detectedFormat) {
|
|
33
|
+
case 'ansi':
|
|
34
|
+
return createANSIOutput(level, message, prefix, stackInfo);
|
|
35
|
+
case 'build':
|
|
36
|
+
return createBuildOutput(level, message, prefix, stackInfo);
|
|
37
|
+
case 'ci':
|
|
38
|
+
return createCIOutput(level, message, prefix, stackInfo);
|
|
39
|
+
case 'plain':
|
|
40
|
+
default:
|
|
41
|
+
return createPlainOutput(level, message, prefix, stackInfo);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
7
44
|
|
|
8
45
|
/**
|
|
9
46
|
* Creates plain text output for any environment
|
|
@@ -17,22 +54,175 @@ export function createPlainOutput(
|
|
|
17
54
|
): string {
|
|
18
55
|
const timestamp = formatTimestamp();
|
|
19
56
|
const timeStr = timestamp.slice(11, 23); // HH:MM:SS.mmm
|
|
20
|
-
|
|
57
|
+
|
|
21
58
|
let output = `[${timeStr}] [${level.toUpperCase()}]`;
|
|
22
|
-
|
|
59
|
+
|
|
23
60
|
if (prefix) {
|
|
24
61
|
output += ` [${prefix}]`;
|
|
25
62
|
}
|
|
26
|
-
|
|
63
|
+
|
|
27
64
|
output += ` ${message}`;
|
|
28
|
-
|
|
65
|
+
|
|
29
66
|
if (stackInfo) {
|
|
30
67
|
output += ` (${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`;
|
|
31
68
|
}
|
|
32
|
-
|
|
69
|
+
|
|
33
70
|
return output;
|
|
34
71
|
}
|
|
35
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Creates ANSI-colored output for terminals
|
|
75
|
+
*/
|
|
76
|
+
export function createANSIOutput(
|
|
77
|
+
level: LogLevel,
|
|
78
|
+
message: string,
|
|
79
|
+
prefix?: string,
|
|
80
|
+
stackInfo?: StackInfo | null
|
|
81
|
+
): string {
|
|
82
|
+
const timestamp = formatTimestamp();
|
|
83
|
+
const timeStr = timestamp.slice(11, 23);
|
|
84
|
+
|
|
85
|
+
let output = '';
|
|
86
|
+
|
|
87
|
+
// Timestamp
|
|
88
|
+
output += formatTimestampANSI(`[${timeStr}]`) + ' ';
|
|
89
|
+
|
|
90
|
+
// Log level with colors
|
|
91
|
+
output += formatLogLevelANSI(level) + ' ';
|
|
92
|
+
|
|
93
|
+
// Prefix if provided
|
|
94
|
+
if (prefix) {
|
|
95
|
+
output += formatPrefixANSI(prefix) + ' ';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Message
|
|
99
|
+
output += message;
|
|
100
|
+
|
|
101
|
+
// Stack info if provided
|
|
102
|
+
if (stackInfo) {
|
|
103
|
+
output += ' ' + formatLocationANSI(`(${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return sanitizeEmojis(output);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Creates build-friendly output (optimized for Next.js builds, webpack, etc.)
|
|
111
|
+
*/
|
|
112
|
+
export function createBuildOutput(
|
|
113
|
+
level: LogLevel,
|
|
114
|
+
message: string,
|
|
115
|
+
prefix?: string,
|
|
116
|
+
stackInfo?: StackInfo | null
|
|
117
|
+
): string {
|
|
118
|
+
const timestamp = formatTimestamp();
|
|
119
|
+
const timeStr = timestamp.slice(11, 23);
|
|
120
|
+
|
|
121
|
+
let output = '';
|
|
122
|
+
|
|
123
|
+
// Use ANSI colors if supported
|
|
124
|
+
if (supportsANSIColors()) {
|
|
125
|
+
output += formatTimestampANSI(`[${timeStr}]`) + ' ';
|
|
126
|
+
|
|
127
|
+
// Use build-specific formatters
|
|
128
|
+
switch (level) {
|
|
129
|
+
case 'info':
|
|
130
|
+
output += BUILD_FORMATTERS.info(message);
|
|
131
|
+
break;
|
|
132
|
+
case 'warn':
|
|
133
|
+
output += BUILD_FORMATTERS.warning(message);
|
|
134
|
+
break;
|
|
135
|
+
case 'error':
|
|
136
|
+
case 'critical':
|
|
137
|
+
output += BUILD_FORMATTERS.error(message);
|
|
138
|
+
break;
|
|
139
|
+
default:
|
|
140
|
+
output += `${formatLogLevelANSI(level)} ${message}`;
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// Fallback to plain text
|
|
144
|
+
output = `[${timeStr}] [${level.toUpperCase()}]`;
|
|
145
|
+
|
|
146
|
+
if (prefix) {
|
|
147
|
+
output += ` [${prefix}]`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
output += ` ${message}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (stackInfo) {
|
|
154
|
+
output += ` (${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return sanitizeEmojis(output);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Creates CI-friendly output (no emojis, simple formatting)
|
|
162
|
+
*/
|
|
163
|
+
export function createCIOutput(
|
|
164
|
+
level: LogLevel,
|
|
165
|
+
message: string,
|
|
166
|
+
prefix?: string,
|
|
167
|
+
stackInfo?: StackInfo | null
|
|
168
|
+
): string {
|
|
169
|
+
const timestamp = formatTimestamp();
|
|
170
|
+
const timeStr = timestamp.slice(11, 23);
|
|
171
|
+
|
|
172
|
+
let output = `[${timeStr}] [${level.toUpperCase()}]`;
|
|
173
|
+
|
|
174
|
+
if (prefix) {
|
|
175
|
+
output += ` [${prefix}]`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
output += ` ${message}`;
|
|
179
|
+
|
|
180
|
+
if (stackInfo) {
|
|
181
|
+
output += ` (${stackInfo.file}:${stackInfo.line}:${stackInfo.column})`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Always remove emojis for CI
|
|
185
|
+
return sanitizeEmojis(output);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Detects the optimal output format based on environment
|
|
190
|
+
*/
|
|
191
|
+
export function detectOptimalFormat(): OutputFormat {
|
|
192
|
+
// Check for specific environment variables
|
|
193
|
+
const isCI = process.env.CI ||
|
|
194
|
+
process.env.GITHUB_ACTIONS ||
|
|
195
|
+
process.env.JENKINS_URL ||
|
|
196
|
+
process.env.GITLAB_CI ||
|
|
197
|
+
process.env.TRAVIS ||
|
|
198
|
+
process.env.CIRCLECI;
|
|
199
|
+
|
|
200
|
+
const isBuild = process.env.NODE_ENV === 'production' ||
|
|
201
|
+
process.env.BUILD_MODE === 'production' ||
|
|
202
|
+
process.argv.some(arg => arg.includes('build') || arg.includes('webpack'));
|
|
203
|
+
|
|
204
|
+
const isNextJS = process.env.NEXT_RUNTIME ||
|
|
205
|
+
process.argv.some(arg => arg.includes('next'));
|
|
206
|
+
|
|
207
|
+
// CI environment - always use plain text
|
|
208
|
+
if (isCI) {
|
|
209
|
+
return 'ci';
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Next.js build environment
|
|
213
|
+
if (isNextJS || isBuild) {
|
|
214
|
+
return 'build';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Node.js with ANSI support
|
|
218
|
+
if (isNode && supportsANSIColors()) {
|
|
219
|
+
return 'ansi';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Default to plain text
|
|
223
|
+
return 'plain';
|
|
224
|
+
}
|
|
225
|
+
|
|
36
226
|
/**
|
|
37
227
|
* Gets the appropriate log method for the level
|
|
38
228
|
* Uses different console methods for better semantics
|
package/src/utils/index.ts
CHANGED
|
@@ -3,19 +3,31 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export { parseStackTrace } from './stackTrace.js';
|
|
6
|
-
export {
|
|
7
|
-
formatTimestamp,
|
|
8
|
-
parseRelativeTime,
|
|
9
|
-
parseTimeInput,
|
|
10
|
-
formatDisplayTime
|
|
6
|
+
export {
|
|
7
|
+
formatTimestamp,
|
|
8
|
+
parseRelativeTime,
|
|
9
|
+
parseTimeInput,
|
|
10
|
+
formatDisplayTime
|
|
11
11
|
} from './timestamps.js';
|
|
12
|
-
export {
|
|
13
|
-
createStyledOutput,
|
|
14
|
-
generateLogId,
|
|
15
|
-
escapeHtml,
|
|
12
|
+
export {
|
|
13
|
+
createStyledOutput,
|
|
14
|
+
generateLogId,
|
|
15
|
+
escapeHtml,
|
|
16
16
|
safeStringify,
|
|
17
17
|
detectDevToolsTheme,
|
|
18
18
|
getAdaptiveColor,
|
|
19
19
|
setupThemeChangeListener,
|
|
20
|
-
type LevelStyleConfig
|
|
21
|
-
} from './output.js';
|
|
20
|
+
type LevelStyleConfig
|
|
21
|
+
} from './output.js';
|
|
22
|
+
export {
|
|
23
|
+
createPlainOutput,
|
|
24
|
+
createOutput,
|
|
25
|
+
createANSIOutput,
|
|
26
|
+
createBuildOutput,
|
|
27
|
+
createCIOutput,
|
|
28
|
+
detectOptimalFormat,
|
|
29
|
+
getConsoleMethod,
|
|
30
|
+
createLogEntry,
|
|
31
|
+
formatTablePlain,
|
|
32
|
+
safeSerialize
|
|
33
|
+
} from './formatting.js';
|