@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.
Files changed (170) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/dist/Logger.d.ts.map +1 -0
  3. package/dist/ScopedLogger.d.ts.map +1 -0
  4. package/dist/chunks/{Logger-D8pK7XXt.js → Logger-C9zTFYBh.js} +2 -2
  5. package/dist/chunks/Logger-C9zTFYBh.js.map +1 -0
  6. package/dist/chunks/{Logger-CTAaDeZi.js → Logger-Th9SfADL.js} +3 -3
  7. package/dist/chunks/Logger-Th9SfADL.js.map +1 -0
  8. package/dist/chunks/{ScopedLogger-D-7q8uVP.js → ScopedLogger-HgV_J-ug.js} +2 -2
  9. package/dist/chunks/{ScopedLogger-D-7q8uVP.js.map → ScopedLogger-HgV_J-ug.js.map} +1 -1
  10. package/dist/chunks/{ScopedLogger-hS0qSkZD.js → ScopedLogger-uAAeJkfA.js} +2 -2
  11. package/dist/chunks/{ScopedLogger-hS0qSkZD.js.map → ScopedLogger-uAAeJkfA.js.map} +1 -1
  12. package/dist/chunks/environment-5I5unY89.js +4 -0
  13. package/dist/chunks/environment-5I5unY89.js.map +1 -0
  14. package/dist/chunks/{environment-Bxbnw4pd.js → environment-wXLQvk5g.js} +103 -11
  15. package/dist/chunks/environment-wXLQvk5g.js.map +1 -0
  16. package/dist/chunks/formatting-CiFnwe1I.js +2 -0
  17. package/dist/chunks/formatting-CiFnwe1I.js.map +1 -0
  18. package/dist/chunks/formatting-DIhpRCCk.js +380 -0
  19. package/dist/chunks/formatting-DIhpRCCk.js.map +1 -0
  20. package/dist/cli/CommandProcessor.d.ts.map +1 -0
  21. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
  22. package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
  23. package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
  24. package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
  25. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
  26. package/dist/cli/help.d.ts.map +1 -0
  27. package/dist/cli/index.d.ts.map +1 -0
  28. package/dist/{types/constants.d.ts → constants.d.ts} +108 -0
  29. package/dist/constants.d.ts.map +1 -0
  30. package/dist/core.cjs +1 -1
  31. package/dist/core.cjs.map +1 -1
  32. package/dist/core.d.ts +127 -0
  33. package/dist/core.d.ts.map +1 -0
  34. package/dist/core.js +6 -5
  35. package/dist/core.js.map +1 -1
  36. package/dist/example.d.ts.map +1 -0
  37. package/dist/exports-module.d.ts.map +1 -0
  38. package/dist/exports.cjs +1 -1
  39. package/dist/exports.js +2 -2
  40. package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
  41. package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
  42. package/dist/handlers/FileLogHandler.d.ts.map +1 -0
  43. package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
  44. package/dist/handlers/index.d.ts.map +1 -0
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.ts +124 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +25 -5
  50. package/dist/index.js.map +1 -1
  51. package/dist/main.d.ts.map +1 -0
  52. package/dist/styling/LogStyleBuilder.d.ts.map +1 -0
  53. package/dist/styling/SemanticStyles.d.ts.map +1 -0
  54. package/dist/styling/SmartPresets.d.ts.map +1 -0
  55. package/dist/styling/StyleBuilder.d.ts.map +1 -0
  56. package/dist/styling/banners.d.ts.map +1 -0
  57. package/dist/styling/index.d.ts.map +1 -0
  58. package/dist/styling/themes.d.ts.map +1 -0
  59. package/dist/styling-module.d.ts.map +1 -0
  60. package/dist/styling.cjs +1 -1
  61. package/dist/styling.js +3 -3
  62. package/dist/types/core.d.ts +229 -122
  63. package/dist/types/core.d.ts.map +1 -1
  64. package/dist/types/handlers.d.ts.map +1 -0
  65. package/dist/types/index.d.ts +4 -119
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/dist/utils/ansi-colors.d.ts +156 -0
  68. package/dist/utils/ansi-colors.d.ts.map +1 -0
  69. package/dist/utils/environment.d.ts.map +1 -0
  70. package/dist/{types/utils → utils}/formatting.d.ts +22 -1
  71. package/dist/utils/formatting.d.ts.map +1 -0
  72. package/dist/{types/utils → utils}/index.d.ts +1 -0
  73. package/dist/utils/index.d.ts.map +1 -0
  74. package/dist/utils/opentui-detection.d.ts.map +1 -0
  75. package/dist/utils/output.d.ts.map +1 -0
  76. package/dist/utils/stackTrace.d.ts.map +1 -0
  77. package/dist/utils/timestamps.d.ts.map +1 -0
  78. package/package.json +1 -1
  79. package/src/Logger.ts +3 -6
  80. package/src/constants.ts +131 -1
  81. package/src/core.ts +11 -7
  82. package/src/handlers/ExportLogHandler.ts +2 -1
  83. package/src/index.ts +30 -2
  84. package/src/styling/SemanticStyles.ts +1 -1
  85. package/src/types/core.ts +15 -1
  86. package/src/types/index.ts +1 -0
  87. package/src/utils/ansi-colors.ts +333 -0
  88. package/src/utils/formatting.ts +196 -6
  89. package/src/utils/index.ts +23 -11
  90. package/vite.config.ts +1 -1
  91. package/dist/chunks/Logger-CTAaDeZi.js.map +0 -1
  92. package/dist/chunks/Logger-D8pK7XXt.js.map +0 -1
  93. package/dist/chunks/environment-Bxbnw4pd.js.map +0 -1
  94. package/dist/chunks/environment-Dm66zOML.js +0 -4
  95. package/dist/chunks/environment-Dm66zOML.js.map +0 -1
  96. package/dist/chunks/formatting-C0riPC5_.js +0 -95
  97. package/dist/chunks/formatting-C0riPC5_.js.map +0 -1
  98. package/dist/chunks/formatting-DNCAV66-.js +0 -2
  99. package/dist/chunks/formatting-DNCAV66-.js.map +0 -1
  100. package/dist/types/Logger.d.ts.map +0 -1
  101. package/dist/types/ScopedLogger.d.ts.map +0 -1
  102. package/dist/types/cli/CommandProcessor.d.ts.map +0 -1
  103. package/dist/types/cli/commands/ConfigCommand.d.ts.map +0 -1
  104. package/dist/types/cli/commands/ExportCommand.d.ts.map +0 -1
  105. package/dist/types/cli/commands/HistoryCommand.d.ts.map +0 -1
  106. package/dist/types/cli/commands/StatusCommand.d.ts.map +0 -1
  107. package/dist/types/cli/commands/ThemeCommand.d.ts.map +0 -1
  108. package/dist/types/cli/help.d.ts.map +0 -1
  109. package/dist/types/cli/index.d.ts.map +0 -1
  110. package/dist/types/constants.d.ts.map +0 -1
  111. package/dist/types/example.d.ts.map +0 -1
  112. package/dist/types/exports-module.d.ts.map +0 -1
  113. package/dist/types/handlers/AnalyticsLogHandler.d.ts.map +0 -1
  114. package/dist/types/handlers/ExportLogHandler.d.ts.map +0 -1
  115. package/dist/types/handlers/FileLogHandler.d.ts.map +0 -1
  116. package/dist/types/handlers/RemoteLogHandler.d.ts.map +0 -1
  117. package/dist/types/handlers/index.d.ts.map +0 -1
  118. package/dist/types/main.d.ts.map +0 -1
  119. package/dist/types/styling/LogStyleBuilder.d.ts.map +0 -1
  120. package/dist/types/styling/SemanticStyles.d.ts.map +0 -1
  121. package/dist/types/styling/SmartPresets.d.ts.map +0 -1
  122. package/dist/types/styling/StyleBuilder.d.ts.map +0 -1
  123. package/dist/types/styling/banners.d.ts.map +0 -1
  124. package/dist/types/styling/index.d.ts.map +0 -1
  125. package/dist/types/styling/themes.d.ts.map +0 -1
  126. package/dist/types/styling-module.d.ts.map +0 -1
  127. package/dist/types/types/core.d.ts +0 -221
  128. package/dist/types/types/core.d.ts.map +0 -1
  129. package/dist/types/types/handlers.d.ts.map +0 -1
  130. package/dist/types/types/index.d.ts +0 -7
  131. package/dist/types/types/index.d.ts.map +0 -1
  132. package/dist/types/utils/environment.d.ts.map +0 -1
  133. package/dist/types/utils/formatting.d.ts.map +0 -1
  134. package/dist/types/utils/index.d.ts.map +0 -1
  135. package/dist/types/utils/opentui-detection.d.ts.map +0 -1
  136. package/dist/types/utils/output.d.ts.map +0 -1
  137. package/dist/types/utils/stackTrace.d.ts.map +0 -1
  138. package/dist/types/utils/timestamps.d.ts.map +0 -1
  139. /package/dist/{types/Logger.d.ts → Logger.d.ts} +0 -0
  140. /package/dist/{types/ScopedLogger.d.ts → ScopedLogger.d.ts} +0 -0
  141. /package/dist/{types/cli → cli}/CommandProcessor.d.ts +0 -0
  142. /package/dist/{types/cli → cli}/commands/ConfigCommand.d.ts +0 -0
  143. /package/dist/{types/cli → cli}/commands/ExportCommand.d.ts +0 -0
  144. /package/dist/{types/cli → cli}/commands/HistoryCommand.d.ts +0 -0
  145. /package/dist/{types/cli → cli}/commands/StatusCommand.d.ts +0 -0
  146. /package/dist/{types/cli → cli}/commands/ThemeCommand.d.ts +0 -0
  147. /package/dist/{types/cli → cli}/help.d.ts +0 -0
  148. /package/dist/{types/cli → cli}/index.d.ts +0 -0
  149. /package/dist/{types/example.d.ts → example.d.ts} +0 -0
  150. /package/dist/{types/exports-module.d.ts → exports-module.d.ts} +0 -0
  151. /package/dist/{types/handlers → handlers}/AnalyticsLogHandler.d.ts +0 -0
  152. /package/dist/{types/handlers → handlers}/ExportLogHandler.d.ts +0 -0
  153. /package/dist/{types/handlers → handlers}/FileLogHandler.d.ts +0 -0
  154. /package/dist/{types/handlers → handlers}/RemoteLogHandler.d.ts +0 -0
  155. /package/dist/{types/handlers → handlers}/index.d.ts +0 -0
  156. /package/dist/{types/main.d.ts → main.d.ts} +0 -0
  157. /package/dist/{types/styling → styling}/LogStyleBuilder.d.ts +0 -0
  158. /package/dist/{types/styling → styling}/SemanticStyles.d.ts +0 -0
  159. /package/dist/{types/styling → styling}/SmartPresets.d.ts +0 -0
  160. /package/dist/{types/styling → styling}/StyleBuilder.d.ts +0 -0
  161. /package/dist/{types/styling → styling}/banners.d.ts +0 -0
  162. /package/dist/{types/styling → styling}/index.d.ts +0 -0
  163. /package/dist/{types/styling → styling}/themes.d.ts +0 -0
  164. /package/dist/{types/styling-module.d.ts → styling-module.d.ts} +0 -0
  165. /package/dist/types/{types/handlers.d.ts → handlers.d.ts} +0 -0
  166. /package/dist/{types/utils → utils}/environment.d.ts +0 -0
  167. /package/dist/{types/utils → utils}/opentui-detection.d.ts +0 -0
  168. /package/dist/{types/utils → utils}/output.d.ts +0 -0
  169. /package/dist/{types/utils → utils}/stackTrace.d.ts +0 -0
  170. /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
+ }
@@ -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
@@ -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';
package/vite.config.ts CHANGED
@@ -47,7 +47,7 @@ const buildConfigs = {
47
47
  plugins: [
48
48
  dts({
49
49
  ...baseConfig.plugins[0].options,
50
- outDir: 'dist/types',
50
+ outDir: 'dist',
51
51
  })
52
52
  ],
53
53
  build: {