@mks2508/better-logger 2.0.1 → 2.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/bun.lock +333 -0
- package/dist/Logger.d.ts +704 -0
- package/dist/Logger.d.ts.map +1 -0
- package/dist/ScopedLogger.d.ts +310 -0
- package/dist/ScopedLogger.d.ts.map +1 -0
- package/dist/chunks/Logger-B7L-ujY4.js +3503 -0
- package/dist/chunks/Logger-B7L-ujY4.js.map +1 -0
- package/dist/chunks/Logger-DzU_c5sX.js +2 -0
- package/dist/chunks/Logger-DzU_c5sX.js.map +1 -0
- package/dist/chunks/RemoteLogHandler-CjWpWZGl.js +33 -0
- package/dist/chunks/RemoteLogHandler-CjWpWZGl.js.map +1 -0
- package/dist/chunks/RemoteLogHandler-ymkQ97xl.js +2 -0
- package/dist/chunks/RemoteLogHandler-ymkQ97xl.js.map +1 -0
- package/dist/chunks/ScopedLogger-BY3-E8Ov.js +2 -0
- package/dist/chunks/ScopedLogger-BY3-E8Ov.js.map +1 -0
- package/dist/chunks/ScopedLogger-D-RbiFZn.js +361 -0
- package/dist/chunks/ScopedLogger-D-RbiFZn.js.map +1 -0
- package/dist/chunks/environment-Ba5kShbx.js +4 -0
- package/dist/chunks/environment-Ba5kShbx.js.map +1 -0
- package/dist/chunks/environment-TI2ByCPT.js +1209 -0
- package/dist/chunks/environment-TI2ByCPT.js.map +1 -0
- package/dist/chunks/formatting-Blwy-f0W.js +2 -0
- package/dist/chunks/formatting-Blwy-f0W.js.map +1 -0
- package/dist/chunks/formatting-CuNUqGks.js +380 -0
- package/dist/chunks/formatting-CuNUqGks.js.map +1 -0
- package/dist/cli/CommandProcessor.d.ts +100 -0
- package/dist/cli/CommandProcessor.d.ts.map +1 -0
- package/dist/cli/commands/ConfigCommand.d.ts +14 -0
- package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
- package/dist/cli/commands/ExportCommand.d.ts +48 -0
- package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
- package/dist/cli/commands/HistoryCommand.d.ts +47 -0
- package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
- package/dist/cli/commands/StatusCommand.d.ts +30 -0
- package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
- package/dist/cli/commands/ThemeCommand.d.ts +30 -0
- package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
- package/dist/cli/help.d.ts +12 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/constants.d.ts +227 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/core.cjs +2 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.ts +127 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +291 -0
- package/dist/core.js.map +1 -0
- package/dist/example.d.ts +18 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/exports-module.d.ts +196 -0
- package/dist/exports-module.d.ts.map +1 -0
- package/dist/exports.cjs +2 -0
- package/dist/exports.cjs.map +1 -0
- package/dist/exports.js +238 -0
- package/dist/exports.js.map +1 -0
- package/dist/handlers/AnalyticsLogHandler.d.ts +8 -0
- package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
- package/dist/handlers/ExportLogHandler.d.ts +100 -0
- package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
- package/dist/handlers/FileLogHandler.d.ts +33 -0
- package/dist/handlers/FileLogHandler.d.ts.map +1 -0
- package/dist/handlers/RemoteLogHandler.d.ts +11 -0
- package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
- package/dist/handlers/index.d.ts +8 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/styling/LogStyleBuilder.d.ts +146 -0
- package/dist/styling/LogStyleBuilder.d.ts.map +1 -0
- package/dist/styling/SemanticStyles.d.ts +178 -0
- package/dist/styling/SemanticStyles.d.ts.map +1 -0
- package/dist/styling/SmartPresets.d.ts +22 -0
- package/dist/styling/SmartPresets.d.ts.map +1 -0
- package/dist/styling/StyleBuilder.d.ts +140 -0
- package/dist/styling/StyleBuilder.d.ts.map +1 -0
- package/dist/styling/banners.d.ts +42 -0
- package/dist/styling/banners.d.ts.map +1 -0
- package/dist/styling/index.d.ts +10 -0
- package/dist/styling/index.d.ts.map +1 -0
- package/dist/styling/themes.d.ts +7 -0
- package/dist/styling/themes.d.ts.map +1 -0
- package/dist/styling-module.d.ts +178 -0
- package/dist/styling-module.d.ts.map +1 -0
- package/dist/styling.cjs +2 -0
- package/dist/styling.cjs.map +1 -0
- package/dist/styling.js +146 -0
- package/dist/styling.js.map +1 -0
- package/dist/terminal/terminal-renderer.d.ts +63 -0
- package/dist/terminal/terminal-renderer.d.ts.map +1 -0
- package/dist/types/core.d.ts +234 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/handlers.d.ts +85 -0
- package/dist/types/handlers.d.ts.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/adapter.d.ts +48 -0
- package/dist/utils/adapter.d.ts.map +1 -0
- package/dist/utils/ansi-colors.d.ts +156 -0
- package/dist/utils/ansi-colors.d.ts.map +1 -0
- package/dist/utils/environment-detector.d.ts +35 -0
- package/dist/utils/environment-detector.d.ts.map +1 -0
- package/dist/utils/environment.d.ts +47 -0
- package/dist/utils/environment.d.ts.map +1 -0
- package/dist/utils/formatting.d.ts +58 -0
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/opentui-detection.d.ts +34 -0
- package/dist/utils/opentui-detection.d.ts.map +1 -0
- package/dist/utils/output.d.ts +46 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/stackTrace.d.ts +6 -0
- package/dist/utils/stackTrace.d.ts.map +1 -0
- package/dist/utils/timestamps.d.ts +20 -0
- package/dist/utils/timestamps.d.ts.map +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,3503 @@
|
|
|
1
|
+
import { h as getAdaptiveColor, A as ADAPTIVE_COLORS, b as StyleBuilder, j as BUFFER_LIMITS, k as generateLogId, l as parseTimeInput, m as formatDisplayTime, n as safeStringify, o as escapeHtml, q as EXPORT_FORMATS, D as DEFAULT_CONFIG, r as setupThemeChangeListener, t as getEnvironment, p as parseStackTrace, c as createStyledOutput, f as formatTimestamp, S as StylePresets } from "./environment-TI2ByCPT.js";
|
|
2
|
+
const THEME_PRESETS = {
|
|
3
|
+
default: {
|
|
4
|
+
debug: {
|
|
5
|
+
emoji: "🐞",
|
|
6
|
+
label: "DEBUG",
|
|
7
|
+
background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
|
|
8
|
+
color: "#ffffff",
|
|
9
|
+
border: "1px solid #667eea",
|
|
10
|
+
shadow: "0 2px 4px rgba(102, 126, 234, 0.3)"
|
|
11
|
+
},
|
|
12
|
+
info: {
|
|
13
|
+
emoji: "ℹ️",
|
|
14
|
+
label: "INFO",
|
|
15
|
+
background: "linear-gradient(135deg, #74b9ff 0%, #0984e3 100%)",
|
|
16
|
+
color: "#ffffff",
|
|
17
|
+
border: "1px solid #74b9ff",
|
|
18
|
+
shadow: "0 2px 4px rgba(116, 185, 255, 0.3)"
|
|
19
|
+
},
|
|
20
|
+
warn: {
|
|
21
|
+
emoji: "⚠️",
|
|
22
|
+
label: "WARN",
|
|
23
|
+
background: "linear-gradient(135deg, #fdcb6e 0%, #e17055 100%)",
|
|
24
|
+
color: "#2d3436",
|
|
25
|
+
border: "1px solid #fdcb6e",
|
|
26
|
+
shadow: "0 2px 4px rgba(253, 203, 110, 0.3)"
|
|
27
|
+
},
|
|
28
|
+
error: {
|
|
29
|
+
emoji: "❌",
|
|
30
|
+
label: "ERROR",
|
|
31
|
+
background: "linear-gradient(135deg, #e84393 0%, #d63031 100%)",
|
|
32
|
+
color: "#ffffff",
|
|
33
|
+
border: "1px solid #e84393",
|
|
34
|
+
shadow: "0 2px 4px rgba(232, 67, 147, 0.3)"
|
|
35
|
+
},
|
|
36
|
+
success: {
|
|
37
|
+
emoji: "✅",
|
|
38
|
+
label: "SUCCESS",
|
|
39
|
+
background: "linear-gradient(135deg, #00b894 0%, #00a085 100%)",
|
|
40
|
+
color: "#ffffff",
|
|
41
|
+
border: "1px solid #00b894",
|
|
42
|
+
shadow: "0 2px 4px rgba(0, 184, 148, 0.3)"
|
|
43
|
+
},
|
|
44
|
+
critical: {
|
|
45
|
+
emoji: "🔥",
|
|
46
|
+
label: "CRITICAL",
|
|
47
|
+
background: "linear-gradient(135deg, #ff3838 0%, #ff1744 100%)",
|
|
48
|
+
color: "#ffffff",
|
|
49
|
+
border: "2px solid #ff3838",
|
|
50
|
+
shadow: "0 4px 8px rgba(255, 56, 56, 0.5)"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
dark: {
|
|
54
|
+
debug: {
|
|
55
|
+
emoji: "🌙",
|
|
56
|
+
label: "DEBUG",
|
|
57
|
+
background: "linear-gradient(135deg, #2d3748 0%, #4a5568 100%)",
|
|
58
|
+
color: "#e2e8f0",
|
|
59
|
+
border: "1px solid #4a5568",
|
|
60
|
+
shadow: "0 2px 4px rgba(45, 55, 72, 0.8)"
|
|
61
|
+
},
|
|
62
|
+
info: {
|
|
63
|
+
emoji: "💡",
|
|
64
|
+
label: "INFO",
|
|
65
|
+
background: "linear-gradient(135deg, #1a202c 0%, #2d3748 100%)",
|
|
66
|
+
color: "#90cdf4",
|
|
67
|
+
border: "1px solid #3182ce",
|
|
68
|
+
shadow: "0 2px 4px rgba(26, 32, 44, 0.8)"
|
|
69
|
+
},
|
|
70
|
+
warn: {
|
|
71
|
+
emoji: "⚡",
|
|
72
|
+
label: "WARN",
|
|
73
|
+
background: "linear-gradient(135deg, #744210 0%, #975a16 100%)",
|
|
74
|
+
color: "#faf089",
|
|
75
|
+
border: "1px solid #d69e2e",
|
|
76
|
+
shadow: "0 2px 4px rgba(116, 66, 16, 0.8)"
|
|
77
|
+
},
|
|
78
|
+
error: {
|
|
79
|
+
emoji: "💀",
|
|
80
|
+
label: "ERROR",
|
|
81
|
+
background: "linear-gradient(135deg, #742a2a 0%, #9b2c2c 100%)",
|
|
82
|
+
color: "#feb2b2",
|
|
83
|
+
border: "1px solid #e53e3e",
|
|
84
|
+
shadow: "0 2px 4px rgba(116, 42, 42, 0.8)"
|
|
85
|
+
},
|
|
86
|
+
success: {
|
|
87
|
+
emoji: "🎯",
|
|
88
|
+
label: "SUCCESS",
|
|
89
|
+
background: "linear-gradient(135deg, #276749 0%, #2f855a 100%)",
|
|
90
|
+
color: "#9ae6b4",
|
|
91
|
+
border: "1px solid #38a169",
|
|
92
|
+
shadow: "0 2px 4px rgba(39, 103, 73, 0.8)"
|
|
93
|
+
},
|
|
94
|
+
critical: {
|
|
95
|
+
emoji: "💥",
|
|
96
|
+
label: "CRITICAL",
|
|
97
|
+
background: "linear-gradient(135deg, #1a1a1a 0%, #ff0000 100%)",
|
|
98
|
+
color: "#ffffff",
|
|
99
|
+
border: "2px solid #ff0000",
|
|
100
|
+
shadow: "0 4px 8px rgba(255, 0, 0, 0.9)"
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
neon: {
|
|
104
|
+
debug: {
|
|
105
|
+
emoji: "⚡",
|
|
106
|
+
label: "DEBUG",
|
|
107
|
+
background: "linear-gradient(135deg, #0f3460 0%, #e94560 100%)",
|
|
108
|
+
color: "#00ffff",
|
|
109
|
+
border: "1px solid #00ffff",
|
|
110
|
+
shadow: "0 0 10px rgba(0, 255, 255, 0.5)"
|
|
111
|
+
},
|
|
112
|
+
info: {
|
|
113
|
+
emoji: "🔮",
|
|
114
|
+
label: "INFO",
|
|
115
|
+
background: "linear-gradient(135deg, #16213e 0%, #0f3460 100%)",
|
|
116
|
+
color: "#00ff41",
|
|
117
|
+
border: "1px solid #00ff41",
|
|
118
|
+
shadow: "0 0 10px rgba(0, 255, 65, 0.5)"
|
|
119
|
+
},
|
|
120
|
+
warn: {
|
|
121
|
+
emoji: "⚠️",
|
|
122
|
+
label: "WARN",
|
|
123
|
+
background: "linear-gradient(135deg, #533a03 0%, #e94560 100%)",
|
|
124
|
+
color: "#ffff00",
|
|
125
|
+
border: "1px solid #ffff00",
|
|
126
|
+
shadow: "0 0 10px rgba(255, 255, 0, 0.5)"
|
|
127
|
+
},
|
|
128
|
+
error: {
|
|
129
|
+
emoji: "💥",
|
|
130
|
+
label: "ERROR",
|
|
131
|
+
background: "linear-gradient(135deg, #5c0a0a 0%, #ff073a 100%)",
|
|
132
|
+
color: "#ff073a",
|
|
133
|
+
border: "1px solid #ff073a",
|
|
134
|
+
shadow: "0 0 10px rgba(255, 7, 58, 0.8)"
|
|
135
|
+
},
|
|
136
|
+
success: {
|
|
137
|
+
emoji: "✨",
|
|
138
|
+
label: "SUCCESS",
|
|
139
|
+
background: "linear-gradient(135deg, #0a5c0a 0%, #39ff14 100%)",
|
|
140
|
+
color: "#39ff14",
|
|
141
|
+
border: "1px solid #39ff14",
|
|
142
|
+
shadow: "0 0 10px rgba(57, 255, 20, 0.8)"
|
|
143
|
+
},
|
|
144
|
+
critical: {
|
|
145
|
+
emoji: "🌟",
|
|
146
|
+
label: "CRITICAL",
|
|
147
|
+
background: "linear-gradient(135deg, #000000 0%, #ff0080 100%)",
|
|
148
|
+
color: "#ff0080",
|
|
149
|
+
border: "2px solid #ff0080",
|
|
150
|
+
shadow: "0 0 20px rgba(255, 0, 128, 1)"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
minimal: {
|
|
154
|
+
debug: {
|
|
155
|
+
emoji: "",
|
|
156
|
+
label: "DEBUG",
|
|
157
|
+
background: "#f7fafc",
|
|
158
|
+
color: "#4a5568",
|
|
159
|
+
border: "1px solid #e2e8f0",
|
|
160
|
+
shadow: "none"
|
|
161
|
+
},
|
|
162
|
+
info: {
|
|
163
|
+
emoji: "",
|
|
164
|
+
label: "INFO",
|
|
165
|
+
background: "#ebf8ff",
|
|
166
|
+
color: "#2b6cb0",
|
|
167
|
+
border: "1px solid #bee3f8",
|
|
168
|
+
shadow: "none"
|
|
169
|
+
},
|
|
170
|
+
warn: {
|
|
171
|
+
emoji: "",
|
|
172
|
+
label: "WARN",
|
|
173
|
+
background: "#fffbf0",
|
|
174
|
+
color: "#c05621",
|
|
175
|
+
border: "1px solid #fed7aa",
|
|
176
|
+
shadow: "none"
|
|
177
|
+
},
|
|
178
|
+
error: {
|
|
179
|
+
emoji: "",
|
|
180
|
+
label: "ERROR",
|
|
181
|
+
background: "#fef5f5",
|
|
182
|
+
color: "#c53030",
|
|
183
|
+
border: "1px solid #fca5a5",
|
|
184
|
+
shadow: "none"
|
|
185
|
+
},
|
|
186
|
+
success: {
|
|
187
|
+
emoji: "",
|
|
188
|
+
label: "SUCCESS",
|
|
189
|
+
background: "#f0fff4",
|
|
190
|
+
color: "#2f855a",
|
|
191
|
+
border: "1px solid #9ae6b4",
|
|
192
|
+
shadow: "none"
|
|
193
|
+
},
|
|
194
|
+
critical: {
|
|
195
|
+
emoji: "",
|
|
196
|
+
label: "CRITICAL",
|
|
197
|
+
background: "#fef5f5",
|
|
198
|
+
color: "#e53e3e",
|
|
199
|
+
border: "2px solid #f56565",
|
|
200
|
+
shadow: "none"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
// Additional theme variants can be added here
|
|
204
|
+
light: {
|
|
205
|
+
debug: {
|
|
206
|
+
emoji: "🔍",
|
|
207
|
+
label: "DEBUG",
|
|
208
|
+
background: "linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)",
|
|
209
|
+
color: "#1565c0",
|
|
210
|
+
border: "1px solid #90caf9",
|
|
211
|
+
shadow: "0 1px 3px rgba(33, 150, 243, 0.2)"
|
|
212
|
+
},
|
|
213
|
+
info: {
|
|
214
|
+
emoji: "ℹ️",
|
|
215
|
+
label: "INFO",
|
|
216
|
+
background: "linear-gradient(135deg, #f3e5f5 0%, #e1bee7 100%)",
|
|
217
|
+
color: "#7b1fa2",
|
|
218
|
+
border: "1px solid #ce93d8",
|
|
219
|
+
shadow: "0 1px 3px rgba(156, 39, 176, 0.2)"
|
|
220
|
+
},
|
|
221
|
+
warn: {
|
|
222
|
+
emoji: "⚠️",
|
|
223
|
+
label: "WARN",
|
|
224
|
+
background: "linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%)",
|
|
225
|
+
color: "#f57c00",
|
|
226
|
+
border: "1px solid #ffcc02",
|
|
227
|
+
shadow: "0 1px 3px rgba(255, 152, 0, 0.2)"
|
|
228
|
+
},
|
|
229
|
+
error: {
|
|
230
|
+
emoji: "❌",
|
|
231
|
+
label: "ERROR",
|
|
232
|
+
background: "linear-gradient(135deg, #ffebee 0%, #ffcdd2 100%)",
|
|
233
|
+
color: "#d32f2f",
|
|
234
|
+
border: "1px solid #f44336",
|
|
235
|
+
shadow: "0 1px 3px rgba(244, 67, 54, 0.2)"
|
|
236
|
+
},
|
|
237
|
+
success: {
|
|
238
|
+
emoji: "✅",
|
|
239
|
+
label: "SUCCESS",
|
|
240
|
+
background: "linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%)",
|
|
241
|
+
color: "#388e3c",
|
|
242
|
+
border: "1px solid #4caf50",
|
|
243
|
+
shadow: "0 1px 3px rgba(76, 175, 80, 0.2)"
|
|
244
|
+
},
|
|
245
|
+
critical: {
|
|
246
|
+
emoji: "🚨",
|
|
247
|
+
label: "CRITICAL",
|
|
248
|
+
background: "linear-gradient(135deg, #fce4ec 0%, #f8bbd9 100%)",
|
|
249
|
+
color: "#c2185b",
|
|
250
|
+
border: "2px solid #e91e63",
|
|
251
|
+
shadow: "0 2px 6px rgba(233, 30, 99, 0.3)"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
cyberpunk: {
|
|
255
|
+
debug: {
|
|
256
|
+
emoji: "🤖",
|
|
257
|
+
label: "DEBUG",
|
|
258
|
+
background: "linear-gradient(135deg, #0d1b2a 0%, #415a77 100%)",
|
|
259
|
+
color: "#00d4aa",
|
|
260
|
+
border: "1px solid #00d4aa",
|
|
261
|
+
shadow: "0 0 15px rgba(0, 212, 170, 0.4)"
|
|
262
|
+
},
|
|
263
|
+
info: {
|
|
264
|
+
emoji: "🔗",
|
|
265
|
+
label: "INFO",
|
|
266
|
+
background: "linear-gradient(135deg, #1b263b 0%, #0d1b2a 100%)",
|
|
267
|
+
color: "#00b4d8",
|
|
268
|
+
border: "1px solid #00b4d8",
|
|
269
|
+
shadow: "0 0 15px rgba(0, 180, 216, 0.4)"
|
|
270
|
+
},
|
|
271
|
+
warn: {
|
|
272
|
+
emoji: "⚡",
|
|
273
|
+
label: "WARN",
|
|
274
|
+
background: "linear-gradient(135deg, #f72585 0%, #b5179e 100%)",
|
|
275
|
+
color: "#ffff3f",
|
|
276
|
+
border: "1px solid #ffff3f",
|
|
277
|
+
shadow: "0 0 15px rgba(255, 255, 63, 0.4)"
|
|
278
|
+
},
|
|
279
|
+
error: {
|
|
280
|
+
emoji: "💀",
|
|
281
|
+
label: "ERROR",
|
|
282
|
+
background: "linear-gradient(135deg, #7209b7 0%, #480ca8 100%)",
|
|
283
|
+
color: "#ff006e",
|
|
284
|
+
border: "1px solid #ff006e",
|
|
285
|
+
shadow: "0 0 15px rgba(255, 0, 110, 0.6)"
|
|
286
|
+
},
|
|
287
|
+
success: {
|
|
288
|
+
emoji: "⚡",
|
|
289
|
+
label: "SUCCESS",
|
|
290
|
+
background: "linear-gradient(135deg, #003566 0%, #001d3d 100%)",
|
|
291
|
+
color: "#00f5ff",
|
|
292
|
+
border: "1px solid #00f5ff",
|
|
293
|
+
shadow: "0 0 15px rgba(0, 245, 255, 0.4)"
|
|
294
|
+
},
|
|
295
|
+
critical: {
|
|
296
|
+
emoji: "💥",
|
|
297
|
+
label: "CRITICAL",
|
|
298
|
+
background: "linear-gradient(135deg, #000000 0%, #ff0040 100%)",
|
|
299
|
+
color: "#ff0040",
|
|
300
|
+
border: "2px solid #ff0040",
|
|
301
|
+
shadow: "0 0 25px rgba(255, 0, 64, 0.8)"
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
const BANNER_VARIANTS = {
|
|
306
|
+
simple: {
|
|
307
|
+
text: "🚀 ADVANCED LOGGER v2.0.0 - State-of-the-art Console Styling 🚀",
|
|
308
|
+
style: "background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 12px 20px; border-radius: 8px; font-weight: bold; font-size: 14px;"
|
|
309
|
+
},
|
|
310
|
+
ascii: {
|
|
311
|
+
text: `
|
|
312
|
+
___ ____ _ __ ___ _ __ _____ _____ ____ __ ___ _____ _____ _____ ____
|
|
313
|
+
/ _ \\ / __ \\| | / / / _ \\ | \\ | |/ ____| ____| _ \\ | | / _ \\ / ____| ___| _ | _ \\
|
|
314
|
+
/ /_\\ \\ / / _\` | |/ / / /_\\ \\ | \\| | | | |__ | | | | | | / / \\ \\| | __| |_ | |_| | |_) |
|
|
315
|
+
| _ || | (_| | < | _ | | . \` | | | __| | | | | | | | | | | | |_ | _| | /| _ <
|
|
316
|
+
| | | |\\ \\__,_|_|\\_\\ | | | | | |\\ | |___| |____| |_| | | |__\\ \\_/ /| |__| | |___| |\\ \\| |_) |
|
|
317
|
+
\\_| |_/ \\____/ \\_| |_/ |_| \\_|\\_____|______|____/ |_____/\\___/ \\_____|_____|_| \\_|____/
|
|
318
|
+
|
|
319
|
+
Advanced Logger v2.0.0 - Console Excellence`,
|
|
320
|
+
style: 'font-family: "Courier New", Consolas, Monaco, monospace; color: #667eea; font-size: 11px; line-height: 1.2;'
|
|
321
|
+
},
|
|
322
|
+
unicode: {
|
|
323
|
+
text: `
|
|
324
|
+
╔══════════════════════════════════════════════════════════════════════════╗
|
|
325
|
+
║ 🚀 ADVANCED LOGGER v2.0.0 ║
|
|
326
|
+
║ State-of-the-art Console Styling ║
|
|
327
|
+
╚══════════════════════════════════════════════════════════════════════════╝`,
|
|
328
|
+
style: 'font-family: "Courier New", Consolas, Monaco, monospace; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px; border-radius: 8px; font-size: 12px; line-height: 1.3;'
|
|
329
|
+
},
|
|
330
|
+
svg: {
|
|
331
|
+
text: " ",
|
|
332
|
+
style: `
|
|
333
|
+
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 80'><defs><linearGradient id='grad' x1='0%' y1='0%' x2='100%' y2='0%'><stop offset='0%' style='stop-color:%23667eea'/><stop offset='100%' style='stop-color:%23764ba2'/></linearGradient></defs><rect width='100%' height='100%' fill='url(%23grad)' rx='8'/><text x='200' y='30' text-anchor='middle' fill='white' font-family='monospace' font-size='14' font-weight='bold'>🚀 ADVANCED LOGGER</text><text x='200' y='50' text-anchor='middle' fill='white' font-family='monospace' font-size='12'>State-of-the-art Console Styling</text><text x='200' y='65' text-anchor='middle' fill='white' font-family='monospace' font-size='10'>v2.0.0</text></svg>");
|
|
334
|
+
background-repeat: no-repeat;
|
|
335
|
+
background-size: 400px 80px;
|
|
336
|
+
padding: 40px 200px;
|
|
337
|
+
color: transparent;
|
|
338
|
+
display: inline-block;
|
|
339
|
+
border-radius: 8px;
|
|
340
|
+
`
|
|
341
|
+
},
|
|
342
|
+
animated: {
|
|
343
|
+
text: " 🚀 ADVANCED LOGGER v2.0.0 ",
|
|
344
|
+
style: `
|
|
345
|
+
background: linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2);
|
|
346
|
+
background-size: 400% 400%;
|
|
347
|
+
color: white;
|
|
348
|
+
padding: 15px 25px;
|
|
349
|
+
border-radius: 10px;
|
|
350
|
+
font-weight: bold;
|
|
351
|
+
font-size: 14px;
|
|
352
|
+
font-family: monospace;
|
|
353
|
+
animation: gradientShift 3s ease infinite;
|
|
354
|
+
display: inline-block;
|
|
355
|
+
`
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
const THEME_BANNERS = {
|
|
359
|
+
default: {
|
|
360
|
+
simple: "🚀 ADVANCED LOGGER v2.0.0 - State-of-the-art Console Styling 🚀",
|
|
361
|
+
style: "background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 12px 20px; border-radius: 8px; font-weight: bold;"
|
|
362
|
+
},
|
|
363
|
+
dark: {
|
|
364
|
+
simple: "🌙 ADVANCED LOGGER v2.0.0 - Dark Mode Console Excellence 🌙",
|
|
365
|
+
style: "background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%); color: #e2e8f0; padding: 12px 20px; border-radius: 8px; font-weight: bold; border: 1px solid #4a5568;"
|
|
366
|
+
},
|
|
367
|
+
neon: {
|
|
368
|
+
simple: "⚡ ADVANCED LOGGER v2.0.0 - Cyberpunk Console Experience ⚡",
|
|
369
|
+
style: "background: linear-gradient(135deg, #0f3460 0%, #e94560 100%); color: #00ffff; padding: 12px 20px; border-radius: 8px; font-weight: bold; text-shadow: 0 0 10px #00ffff;"
|
|
370
|
+
},
|
|
371
|
+
minimal: {
|
|
372
|
+
simple: "ADVANCED LOGGER v2.0.0 - Clean Console Styling",
|
|
373
|
+
style: "background: #f7fafc; color: #2d3748; padding: 8px 16px; border: 1px solid #e2e8f0; border-radius: 4px; font-weight: 500;"
|
|
374
|
+
},
|
|
375
|
+
light: {
|
|
376
|
+
simple: "☀️ ADVANCED LOGGER v2.0.0 - Bright Console Styling ☀️",
|
|
377
|
+
style: "background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); color: #495057; padding: 12px 20px; border-radius: 8px; font-weight: bold; border: 1px solid #dee2e6;"
|
|
378
|
+
},
|
|
379
|
+
cyberpunk: {
|
|
380
|
+
simple: "🤖 ADVANCED LOGGER v2.0.0 - Neural Console Interface 🤖",
|
|
381
|
+
style: "background: linear-gradient(135deg, #0d1b2a 0%, #415a77 100%); color: #00d4aa; padding: 12px 20px; border-radius: 8px; font-weight: bold; text-shadow: 0 0 10px #00d4aa; border: 1px solid #00d4aa;"
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
function detectBannerCapabilities() {
|
|
385
|
+
const userAgent = navigator.userAgent;
|
|
386
|
+
const isChrome = /Chrome/.test(userAgent);
|
|
387
|
+
const isFirefox = /Firefox/.test(userAgent);
|
|
388
|
+
const isSafari = /Safari/.test(userAgent) && !/Chrome/.test(userAgent);
|
|
389
|
+
const supportsSVG = !!document.createElementNS && !!document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect;
|
|
390
|
+
const supportsAnimations = typeof document !== "undefined" && "animationName" in document.createElement("div").style;
|
|
391
|
+
if (supportsAnimations && isChrome) {
|
|
392
|
+
return "animated";
|
|
393
|
+
} else if (supportsSVG && (isChrome || isFirefox)) {
|
|
394
|
+
return "svg";
|
|
395
|
+
} else if (isChrome || isFirefox) {
|
|
396
|
+
return "unicode";
|
|
397
|
+
} else if (isSafari) {
|
|
398
|
+
return "ascii";
|
|
399
|
+
}
|
|
400
|
+
return "simple";
|
|
401
|
+
}
|
|
402
|
+
function displayInitBanner(bannerType) {
|
|
403
|
+
const selectedType = bannerType || detectBannerCapabilities();
|
|
404
|
+
const banner = BANNER_VARIANTS[selectedType];
|
|
405
|
+
if (selectedType === "animated") {
|
|
406
|
+
const style = document.createElement("style");
|
|
407
|
+
style.textContent = `
|
|
408
|
+
@keyframes gradientShift {
|
|
409
|
+
0% { background-position: 0% 50%; }
|
|
410
|
+
50% { background-position: 100% 50%; }
|
|
411
|
+
100% { background-position: 0% 50%; }
|
|
412
|
+
}
|
|
413
|
+
`;
|
|
414
|
+
document.head.appendChild(style);
|
|
415
|
+
}
|
|
416
|
+
console.log(`%c${banner.text}`, banner.style);
|
|
417
|
+
const features = [
|
|
418
|
+
"🎨 Advanced CSS Console Styling",
|
|
419
|
+
"📍 Automatic Stack Trace Parsing",
|
|
420
|
+
"🔧 Scoped Loggers & Prefixes",
|
|
421
|
+
"⚡ Performance Timers",
|
|
422
|
+
"🎯 Verbosity Filtering",
|
|
423
|
+
"🔌 Extensible Handlers",
|
|
424
|
+
"📱 Modern TypeScript Patterns",
|
|
425
|
+
"📤 Export & Clipboard Support"
|
|
426
|
+
];
|
|
427
|
+
console.group(`%c✨ Features`, "background: #f8f9fa; color: #495057; padding: 4px 8px; border-radius: 4px; font-weight: bold;");
|
|
428
|
+
features.forEach((feature) => {
|
|
429
|
+
console.log(`%c${feature}`, "color: #6c757d; font-size: 13px;");
|
|
430
|
+
});
|
|
431
|
+
console.groupEnd();
|
|
432
|
+
console.log("");
|
|
433
|
+
}
|
|
434
|
+
class BaseStyler {
|
|
435
|
+
builder;
|
|
436
|
+
constructor(builder = new StyleBuilder()) {
|
|
437
|
+
this.builder = builder;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Primary brand color (typically blue)
|
|
441
|
+
*/
|
|
442
|
+
primary() {
|
|
443
|
+
return this.color("#007bff");
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Secondary color (typically gray)
|
|
447
|
+
*/
|
|
448
|
+
secondary() {
|
|
449
|
+
return this.color("#6c757d");
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Accent color for highlights
|
|
453
|
+
*/
|
|
454
|
+
accent() {
|
|
455
|
+
return this.color("#17a2b8");
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Muted/subtle color - automatically adaptive
|
|
459
|
+
*/
|
|
460
|
+
muted() {
|
|
461
|
+
const mutedColors = { light: "#6c757d", dark: "#a0aec0" };
|
|
462
|
+
return this.color(getAdaptiveColor(mutedColors));
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Success color (green)
|
|
466
|
+
*/
|
|
467
|
+
success() {
|
|
468
|
+
return this.color("#28a745");
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Warning color (yellow/orange)
|
|
472
|
+
*/
|
|
473
|
+
warning() {
|
|
474
|
+
return this.color("#ffc107");
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Danger/error color (red)
|
|
478
|
+
*/
|
|
479
|
+
danger() {
|
|
480
|
+
return this.color("#dc3545");
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Monospace font family
|
|
484
|
+
*/
|
|
485
|
+
mono() {
|
|
486
|
+
this.builder.font('Monaco, Consolas, "Courier New", monospace');
|
|
487
|
+
return this;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* System font family
|
|
491
|
+
*/
|
|
492
|
+
system() {
|
|
493
|
+
this.builder.font('system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif');
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Readable font optimized for text
|
|
498
|
+
*/
|
|
499
|
+
readable() {
|
|
500
|
+
this.builder.font('Georgia, "Times New Roman", serif');
|
|
501
|
+
return this;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Compact spacing
|
|
505
|
+
*/
|
|
506
|
+
compact() {
|
|
507
|
+
this.builder.padding("1px 4px").margin("0 1px");
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Spacious layout
|
|
512
|
+
*/
|
|
513
|
+
spacious() {
|
|
514
|
+
this.builder.padding("6px 12px").margin("2px 4px");
|
|
515
|
+
return this;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Inline display
|
|
519
|
+
*/
|
|
520
|
+
inline() {
|
|
521
|
+
this.builder.display("inline-block");
|
|
522
|
+
return this;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Glass morphism effect
|
|
526
|
+
*/
|
|
527
|
+
glassmorphic() {
|
|
528
|
+
this.builder.css("backdrop-filter", "blur(10px)").css("background", "rgba(255, 255, 255, 0.1)").border("1px solid rgba(255, 255, 255, 0.2)").rounded("8px");
|
|
529
|
+
return this;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Neon glow effect
|
|
533
|
+
*/
|
|
534
|
+
neon() {
|
|
535
|
+
const neonColor = "#00ffff";
|
|
536
|
+
this.builder.color(neonColor).border(`1px solid ${neonColor}`).shadow(`0 0 10px ${neonColor}, 0 0 20px ${neonColor}`).css("text-shadow", `0 0 5px ${neonColor}`);
|
|
537
|
+
return this;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Gradient background
|
|
541
|
+
*/
|
|
542
|
+
gradient(from = "#667eea", to = "#764ba2") {
|
|
543
|
+
this.builder.bg(`linear-gradient(135deg, ${from} 0%, ${to} 100%)`);
|
|
544
|
+
return this;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Bold text
|
|
548
|
+
*/
|
|
549
|
+
bold() {
|
|
550
|
+
this.builder.bold();
|
|
551
|
+
return this;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Set color with automatic adaptation
|
|
555
|
+
*/
|
|
556
|
+
color(color) {
|
|
557
|
+
this.builder.color(color);
|
|
558
|
+
return this;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Build the final CSS string
|
|
562
|
+
*/
|
|
563
|
+
build() {
|
|
564
|
+
return this.builder.build();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
class TimestampStyler extends BaseStyler {
|
|
568
|
+
/**
|
|
569
|
+
* Default timestamp style - subtle and informative
|
|
570
|
+
*/
|
|
571
|
+
default() {
|
|
572
|
+
this.muted().mono();
|
|
573
|
+
this.builder.size("11px");
|
|
574
|
+
return this;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Hide timestamp
|
|
578
|
+
*/
|
|
579
|
+
hidden() {
|
|
580
|
+
this.builder.display("none");
|
|
581
|
+
return this;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Minimal timestamp (just time, no date)
|
|
585
|
+
*/
|
|
586
|
+
minimal() {
|
|
587
|
+
this.muted().mono();
|
|
588
|
+
this.builder.size("10px").opacity(0.7);
|
|
589
|
+
return this;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Set font size
|
|
593
|
+
*/
|
|
594
|
+
size(size) {
|
|
595
|
+
this.builder.size(size);
|
|
596
|
+
return this;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
class LevelStyler extends BaseStyler {
|
|
600
|
+
/**
|
|
601
|
+
* Colorful gradient badge
|
|
602
|
+
*/
|
|
603
|
+
badge() {
|
|
604
|
+
this.builder.padding("2px 8px").rounded("4px").bold().color("#ffffff");
|
|
605
|
+
return this;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Glowing effect for dark themes
|
|
609
|
+
*/
|
|
610
|
+
glowing() {
|
|
611
|
+
return this.neon().badge();
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Minimal flat style
|
|
615
|
+
*/
|
|
616
|
+
flat() {
|
|
617
|
+
this.builder.padding("1px 6px").rounded("2px").border("1px solid currentColor").css("background", "transparent");
|
|
618
|
+
return this;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Uppercase text
|
|
622
|
+
*/
|
|
623
|
+
uppercase() {
|
|
624
|
+
this.builder.uppercase();
|
|
625
|
+
return this;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
class PrefixStyler extends BaseStyler {
|
|
629
|
+
/**
|
|
630
|
+
* Dark theme prefix
|
|
631
|
+
*/
|
|
632
|
+
dark() {
|
|
633
|
+
const prefixColors = { light: "#2d3748", dark: "#4a5568" };
|
|
634
|
+
const textColors = { light: "#e2e8f0", dark: "#f7fafc" };
|
|
635
|
+
this.builder.bg(getAdaptiveColor(prefixColors)).color(getAdaptiveColor(textColors)).padding("2px 6px").rounded("3px").bold().mono().size("11px");
|
|
636
|
+
return this;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Light theme prefix
|
|
640
|
+
*/
|
|
641
|
+
light() {
|
|
642
|
+
this.builder.bg("#f8f9fa").color("#495057").padding("2px 6px").rounded("3px").bold().mono().size("11px").border("1px solid #dee2e6");
|
|
643
|
+
return this;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Compact prefix
|
|
647
|
+
*/
|
|
648
|
+
compact() {
|
|
649
|
+
this.builder.padding("1px 4px").size("10px").rounded("2px");
|
|
650
|
+
return this;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
class MessageStyler extends BaseStyler {
|
|
654
|
+
/**
|
|
655
|
+
* Readable message text - automatically adaptive
|
|
656
|
+
*/
|
|
657
|
+
readable() {
|
|
658
|
+
this.builder.color(getAdaptiveColor(ADAPTIVE_COLORS.messageText)).system().size("14px");
|
|
659
|
+
return this;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Code-style monospace text
|
|
663
|
+
*/
|
|
664
|
+
code() {
|
|
665
|
+
this.builder.mono().size("13px").color(getAdaptiveColor(ADAPTIVE_COLORS.messageText)).bg("rgba(0, 0, 0, 0.05)").padding("1px 4px").rounded("3px");
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Large, prominent text
|
|
670
|
+
*/
|
|
671
|
+
large() {
|
|
672
|
+
this.builder.size("16px").color(getAdaptiveColor(ADAPTIVE_COLORS.messageText));
|
|
673
|
+
return this;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
class LocationStyler extends BaseStyler {
|
|
677
|
+
/**
|
|
678
|
+
* Subtle location info - automatically adaptive
|
|
679
|
+
*/
|
|
680
|
+
subtle() {
|
|
681
|
+
this.builder.color(getAdaptiveColor(ADAPTIVE_COLORS.location)).mono().size("11px").opacity(0.7);
|
|
682
|
+
return this;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Hide location info
|
|
686
|
+
*/
|
|
687
|
+
hidden() {
|
|
688
|
+
this.builder.display("none");
|
|
689
|
+
return this;
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Clickable style (for IDE integration)
|
|
693
|
+
*/
|
|
694
|
+
clickable() {
|
|
695
|
+
this.subtle();
|
|
696
|
+
this.builder.css("text-decoration", "underline").cursor("pointer");
|
|
697
|
+
return this;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
class LogStyleBuilder {
|
|
701
|
+
logStyles = {};
|
|
702
|
+
logger;
|
|
703
|
+
constructor(logger) {
|
|
704
|
+
this.logger = logger;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Configure timestamp styling
|
|
708
|
+
*/
|
|
709
|
+
timestamp() {
|
|
710
|
+
return new TimestampStyleBuilderProxy(this);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Configure level badge styling
|
|
714
|
+
*/
|
|
715
|
+
level() {
|
|
716
|
+
return new LevelStyleBuilderProxy(this);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Configure prefix styling
|
|
720
|
+
*/
|
|
721
|
+
prefix() {
|
|
722
|
+
return new PrefixStyleBuilderProxy(this);
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Configure message text styling
|
|
726
|
+
*/
|
|
727
|
+
message() {
|
|
728
|
+
return new MessageStyleBuilderProxy(this);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Configure location info styling
|
|
732
|
+
*/
|
|
733
|
+
location() {
|
|
734
|
+
return new LocationStyleBuilderProxy(this);
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Use a predefined preset
|
|
738
|
+
*/
|
|
739
|
+
usePreset(presetName) {
|
|
740
|
+
console.warn(`Preset '${presetName}' will be available in next implementation phase`);
|
|
741
|
+
return this;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Customize with partial configuration
|
|
745
|
+
*/
|
|
746
|
+
customize(overrides) {
|
|
747
|
+
this.logStyles = { ...this.logStyles, ...overrides };
|
|
748
|
+
return this;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Set layout spacing
|
|
752
|
+
*/
|
|
753
|
+
spacing(type) {
|
|
754
|
+
if (!this.logStyles.layout) {
|
|
755
|
+
this.logStyles.layout = { spacing: type };
|
|
756
|
+
} else {
|
|
757
|
+
this.logStyles.layout.spacing = type;
|
|
758
|
+
}
|
|
759
|
+
switch (type) {
|
|
760
|
+
case "compact":
|
|
761
|
+
this.logStyles.layout.innerPadding = "1px";
|
|
762
|
+
this.logStyles.layout.outerMargin = "0px";
|
|
763
|
+
break;
|
|
764
|
+
case "spacious":
|
|
765
|
+
this.logStyles.layout.innerPadding = "4px";
|
|
766
|
+
this.logStyles.layout.outerMargin = "2px";
|
|
767
|
+
break;
|
|
768
|
+
default:
|
|
769
|
+
this.logStyles.layout.innerPadding = "2px";
|
|
770
|
+
this.logStyles.layout.outerMargin = "1px";
|
|
771
|
+
}
|
|
772
|
+
return this;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Set backdrop filter for glassmorphism effects
|
|
776
|
+
*/
|
|
777
|
+
backdrop(filter) {
|
|
778
|
+
this.logStyles.backdrop = filter;
|
|
779
|
+
return this;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Set overall transparency
|
|
783
|
+
*/
|
|
784
|
+
transparency(value) {
|
|
785
|
+
this.logStyles.transparency = Math.max(0, Math.min(1, value));
|
|
786
|
+
return this;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Apply the configured styles to the logger
|
|
790
|
+
*/
|
|
791
|
+
apply() {
|
|
792
|
+
this.logger._customLogStyles = this.logStyles;
|
|
793
|
+
console.log("Applied log styles:", this.logStyles);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Get current configuration (for debugging)
|
|
797
|
+
*/
|
|
798
|
+
getConfig() {
|
|
799
|
+
return { ...this.logStyles };
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Internal method to update part configuration
|
|
803
|
+
*/
|
|
804
|
+
_updatePartConfig(part, styles) {
|
|
805
|
+
if (part === "layout" || part === "backdrop" || part === "transparency") {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (!this.logStyles[part]) {
|
|
809
|
+
this.logStyles[part] = {};
|
|
810
|
+
}
|
|
811
|
+
this.logStyles[part].style = styles;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
class PartStyleBuilderProxy {
|
|
815
|
+
parentBuilder;
|
|
816
|
+
partName;
|
|
817
|
+
constructor(parentBuilder, partName) {
|
|
818
|
+
this.parentBuilder = parentBuilder;
|
|
819
|
+
this.partName = partName;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Return to the main builder for chaining other parts
|
|
823
|
+
*/
|
|
824
|
+
and() {
|
|
825
|
+
return this.parentBuilder;
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Apply styles and finish configuration
|
|
829
|
+
*/
|
|
830
|
+
apply() {
|
|
831
|
+
this.parentBuilder.apply();
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Helper to apply styles to the parent builder
|
|
835
|
+
*/
|
|
836
|
+
applyStyles(styler) {
|
|
837
|
+
const styles = styler.build();
|
|
838
|
+
this.parentBuilder._updatePartConfig(this.partName, styles);
|
|
839
|
+
return this;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
class TimestampStyleBuilderProxy extends PartStyleBuilderProxy {
|
|
843
|
+
constructor(parentBuilder) {
|
|
844
|
+
super(parentBuilder, "timestamp");
|
|
845
|
+
}
|
|
846
|
+
default() {
|
|
847
|
+
return this.applyStyles(new TimestampStyler().default());
|
|
848
|
+
}
|
|
849
|
+
hidden() {
|
|
850
|
+
return this.applyStyles(new TimestampStyler().hidden());
|
|
851
|
+
}
|
|
852
|
+
minimal() {
|
|
853
|
+
return this.applyStyles(new TimestampStyler().minimal());
|
|
854
|
+
}
|
|
855
|
+
muted() {
|
|
856
|
+
return this.applyStyles(new TimestampStyler().muted());
|
|
857
|
+
}
|
|
858
|
+
mono() {
|
|
859
|
+
return this.applyStyles(new TimestampStyler().mono());
|
|
860
|
+
}
|
|
861
|
+
compact() {
|
|
862
|
+
return this.applyStyles(new TimestampStyler().compact());
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
class LevelStyleBuilderProxy extends PartStyleBuilderProxy {
|
|
866
|
+
constructor(parentBuilder) {
|
|
867
|
+
super(parentBuilder, "level");
|
|
868
|
+
}
|
|
869
|
+
badge() {
|
|
870
|
+
return this.applyStyles(new LevelStyler().badge());
|
|
871
|
+
}
|
|
872
|
+
gradient(from, to) {
|
|
873
|
+
return this.applyStyles(new LevelStyler().gradient(from, to));
|
|
874
|
+
}
|
|
875
|
+
glowing() {
|
|
876
|
+
return this.applyStyles(new LevelStyler().glowing());
|
|
877
|
+
}
|
|
878
|
+
flat() {
|
|
879
|
+
return this.applyStyles(new LevelStyler().flat());
|
|
880
|
+
}
|
|
881
|
+
bold() {
|
|
882
|
+
return this.applyStyles(new LevelStyler().bold());
|
|
883
|
+
}
|
|
884
|
+
uppercase() {
|
|
885
|
+
return this.applyStyles(new LevelStyler().uppercase());
|
|
886
|
+
}
|
|
887
|
+
neon() {
|
|
888
|
+
return this.applyStyles(new LevelStyler().neon());
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
class PrefixStyleBuilderProxy extends PartStyleBuilderProxy {
|
|
892
|
+
constructor(parentBuilder) {
|
|
893
|
+
super(parentBuilder, "prefix");
|
|
894
|
+
}
|
|
895
|
+
dark() {
|
|
896
|
+
return this.applyStyles(new PrefixStyler().dark());
|
|
897
|
+
}
|
|
898
|
+
light() {
|
|
899
|
+
return this.applyStyles(new PrefixStyler().light());
|
|
900
|
+
}
|
|
901
|
+
compact() {
|
|
902
|
+
return this.applyStyles(new PrefixStyler().compact());
|
|
903
|
+
}
|
|
904
|
+
muted() {
|
|
905
|
+
return this.applyStyles(new PrefixStyler().muted());
|
|
906
|
+
}
|
|
907
|
+
mono() {
|
|
908
|
+
return this.applyStyles(new PrefixStyler().mono());
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
class MessageStyleBuilderProxy extends PartStyleBuilderProxy {
|
|
912
|
+
constructor(parentBuilder) {
|
|
913
|
+
super(parentBuilder, "message");
|
|
914
|
+
}
|
|
915
|
+
readable() {
|
|
916
|
+
return this.applyStyles(new MessageStyler().readable());
|
|
917
|
+
}
|
|
918
|
+
code() {
|
|
919
|
+
return this.applyStyles(new MessageStyler().code());
|
|
920
|
+
}
|
|
921
|
+
large() {
|
|
922
|
+
return this.applyStyles(new MessageStyler().large());
|
|
923
|
+
}
|
|
924
|
+
system() {
|
|
925
|
+
return this.applyStyles(new MessageStyler().system());
|
|
926
|
+
}
|
|
927
|
+
mono() {
|
|
928
|
+
return this.applyStyles(new MessageStyler().mono());
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
class LocationStyleBuilderProxy extends PartStyleBuilderProxy {
|
|
932
|
+
constructor(parentBuilder) {
|
|
933
|
+
super(parentBuilder, "location");
|
|
934
|
+
}
|
|
935
|
+
subtle() {
|
|
936
|
+
return this.applyStyles(new LocationStyler().subtle());
|
|
937
|
+
}
|
|
938
|
+
hidden() {
|
|
939
|
+
return this.applyStyles(new LocationStyler().hidden());
|
|
940
|
+
}
|
|
941
|
+
clickable() {
|
|
942
|
+
return this.applyStyles(new LocationStyler().clickable());
|
|
943
|
+
}
|
|
944
|
+
muted() {
|
|
945
|
+
return this.applyStyles(new LocationStyler().muted());
|
|
946
|
+
}
|
|
947
|
+
mono() {
|
|
948
|
+
return this.applyStyles(new LocationStyler().mono());
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
function createLogStyleBuilder(logger) {
|
|
952
|
+
return new LogStyleBuilder(logger);
|
|
953
|
+
}
|
|
954
|
+
const SMART_PRESETS = {
|
|
955
|
+
/**
|
|
956
|
+
* Default preset - works perfectly out-of-the-box
|
|
957
|
+
* Clean, readable, automatically adaptive to dark/light themes
|
|
958
|
+
*/
|
|
959
|
+
default: {
|
|
960
|
+
layout: {
|
|
961
|
+
spacing: "normal",
|
|
962
|
+
innerPadding: "2px",
|
|
963
|
+
outerMargin: "1px"
|
|
964
|
+
},
|
|
965
|
+
timestamp: {
|
|
966
|
+
show: true,
|
|
967
|
+
color: "auto",
|
|
968
|
+
// Automatically adaptive
|
|
969
|
+
font: "Monaco, Consolas, monospace",
|
|
970
|
+
size: "11px"
|
|
971
|
+
},
|
|
972
|
+
level: {
|
|
973
|
+
show: true,
|
|
974
|
+
style: "badge",
|
|
975
|
+
uppercase: false,
|
|
976
|
+
padding: "2px 8px"
|
|
977
|
+
},
|
|
978
|
+
prefix: {
|
|
979
|
+
show: true,
|
|
980
|
+
style: "dark",
|
|
981
|
+
// Automatically adaptive
|
|
982
|
+
padding: "2px 6px"
|
|
983
|
+
},
|
|
984
|
+
message: {
|
|
985
|
+
show: true,
|
|
986
|
+
color: "auto",
|
|
987
|
+
// Automatically adaptive
|
|
988
|
+
font: "system-ui, -apple-system, sans-serif",
|
|
989
|
+
size: "14px"
|
|
990
|
+
},
|
|
991
|
+
location: {
|
|
992
|
+
show: true,
|
|
993
|
+
color: "auto",
|
|
994
|
+
// Automatically adaptive
|
|
995
|
+
font: "Monaco, Consolas, monospace",
|
|
996
|
+
size: "11px"
|
|
997
|
+
}
|
|
998
|
+
},
|
|
999
|
+
/**
|
|
1000
|
+
* Cyberpunk preset - neon colors, glowing effects, dark theme
|
|
1001
|
+
*/
|
|
1002
|
+
cyberpunk: {
|
|
1003
|
+
layout: {
|
|
1004
|
+
spacing: "compact",
|
|
1005
|
+
innerPadding: "1px",
|
|
1006
|
+
outerMargin: "0px"
|
|
1007
|
+
},
|
|
1008
|
+
timestamp: {
|
|
1009
|
+
show: true,
|
|
1010
|
+
color: "#00ffff",
|
|
1011
|
+
font: "Monaco, Consolas, monospace",
|
|
1012
|
+
size: "10px",
|
|
1013
|
+
style: "neon"
|
|
1014
|
+
},
|
|
1015
|
+
level: {
|
|
1016
|
+
show: true,
|
|
1017
|
+
style: "glowing",
|
|
1018
|
+
uppercase: true,
|
|
1019
|
+
padding: "2px 8px"
|
|
1020
|
+
},
|
|
1021
|
+
prefix: {
|
|
1022
|
+
show: true,
|
|
1023
|
+
color: "#ff0080",
|
|
1024
|
+
background: "rgba(255, 0, 128, 0.1)",
|
|
1025
|
+
border: "1px solid #ff0080",
|
|
1026
|
+
style: "neon"
|
|
1027
|
+
},
|
|
1028
|
+
message: {
|
|
1029
|
+
show: true,
|
|
1030
|
+
color: "#00ff41",
|
|
1031
|
+
font: "Monaco, Consolas, monospace",
|
|
1032
|
+
size: "13px"
|
|
1033
|
+
},
|
|
1034
|
+
location: {
|
|
1035
|
+
show: false
|
|
1036
|
+
// Hidden for cleaner look
|
|
1037
|
+
},
|
|
1038
|
+
backdrop: "blur(2px)",
|
|
1039
|
+
transparency: 0.9
|
|
1040
|
+
},
|
|
1041
|
+
/**
|
|
1042
|
+
* Glassmorphism preset - modern blur effects, transparency
|
|
1043
|
+
*/
|
|
1044
|
+
glassmorphism: {
|
|
1045
|
+
layout: {
|
|
1046
|
+
spacing: "spacious",
|
|
1047
|
+
innerPadding: "4px",
|
|
1048
|
+
outerMargin: "2px"
|
|
1049
|
+
},
|
|
1050
|
+
timestamp: {
|
|
1051
|
+
show: true,
|
|
1052
|
+
color: "auto",
|
|
1053
|
+
font: "system-ui, sans-serif",
|
|
1054
|
+
size: "11px",
|
|
1055
|
+
style: "glassmorphic"
|
|
1056
|
+
},
|
|
1057
|
+
level: {
|
|
1058
|
+
show: true,
|
|
1059
|
+
style: "glassmorphic",
|
|
1060
|
+
uppercase: false,
|
|
1061
|
+
padding: "4px 12px"
|
|
1062
|
+
},
|
|
1063
|
+
prefix: {
|
|
1064
|
+
show: true,
|
|
1065
|
+
style: "glassmorphic",
|
|
1066
|
+
padding: "3px 8px"
|
|
1067
|
+
},
|
|
1068
|
+
message: {
|
|
1069
|
+
show: true,
|
|
1070
|
+
color: "auto",
|
|
1071
|
+
font: "system-ui, sans-serif",
|
|
1072
|
+
size: "14px"
|
|
1073
|
+
},
|
|
1074
|
+
location: {
|
|
1075
|
+
show: true,
|
|
1076
|
+
color: "auto",
|
|
1077
|
+
font: "system-ui, sans-serif",
|
|
1078
|
+
size: "11px",
|
|
1079
|
+
style: "glassmorphic"
|
|
1080
|
+
},
|
|
1081
|
+
backdrop: "blur(10px)",
|
|
1082
|
+
transparency: 0.8
|
|
1083
|
+
},
|
|
1084
|
+
/**
|
|
1085
|
+
* Minimal preset - clean, no decorations, maximum readability
|
|
1086
|
+
*/
|
|
1087
|
+
minimal: {
|
|
1088
|
+
layout: {
|
|
1089
|
+
spacing: "compact",
|
|
1090
|
+
innerPadding: "0px",
|
|
1091
|
+
outerMargin: "0px"
|
|
1092
|
+
},
|
|
1093
|
+
timestamp: {
|
|
1094
|
+
show: false
|
|
1095
|
+
// Hidden for minimal look
|
|
1096
|
+
},
|
|
1097
|
+
level: {
|
|
1098
|
+
show: true,
|
|
1099
|
+
style: "flat",
|
|
1100
|
+
uppercase: true,
|
|
1101
|
+
padding: "0px 4px",
|
|
1102
|
+
border: "none",
|
|
1103
|
+
background: "transparent"
|
|
1104
|
+
},
|
|
1105
|
+
prefix: {
|
|
1106
|
+
show: true,
|
|
1107
|
+
style: "flat",
|
|
1108
|
+
padding: "0px 4px",
|
|
1109
|
+
border: "none",
|
|
1110
|
+
background: "transparent"
|
|
1111
|
+
},
|
|
1112
|
+
message: {
|
|
1113
|
+
show: true,
|
|
1114
|
+
color: "auto",
|
|
1115
|
+
font: "system-ui, sans-serif",
|
|
1116
|
+
size: "14px"
|
|
1117
|
+
},
|
|
1118
|
+
location: {
|
|
1119
|
+
show: false
|
|
1120
|
+
// Hidden for minimal look
|
|
1121
|
+
}
|
|
1122
|
+
},
|
|
1123
|
+
/**
|
|
1124
|
+
* Debug preset - monospace, detailed, compact for development
|
|
1125
|
+
*/
|
|
1126
|
+
debug: {
|
|
1127
|
+
layout: {
|
|
1128
|
+
spacing: "compact",
|
|
1129
|
+
innerPadding: "1px",
|
|
1130
|
+
outerMargin: "0px"
|
|
1131
|
+
},
|
|
1132
|
+
timestamp: {
|
|
1133
|
+
show: true,
|
|
1134
|
+
color: "auto",
|
|
1135
|
+
font: "Monaco, Consolas, monospace",
|
|
1136
|
+
size: "10px"
|
|
1137
|
+
},
|
|
1138
|
+
level: {
|
|
1139
|
+
show: true,
|
|
1140
|
+
style: "compact",
|
|
1141
|
+
uppercase: true,
|
|
1142
|
+
padding: "1px 4px",
|
|
1143
|
+
font: "Monaco, Consolas, monospace",
|
|
1144
|
+
size: "10px"
|
|
1145
|
+
},
|
|
1146
|
+
prefix: {
|
|
1147
|
+
show: true,
|
|
1148
|
+
style: "compact",
|
|
1149
|
+
padding: "1px 4px",
|
|
1150
|
+
font: "Monaco, Consolas, monospace",
|
|
1151
|
+
size: "10px"
|
|
1152
|
+
},
|
|
1153
|
+
message: {
|
|
1154
|
+
show: true,
|
|
1155
|
+
color: "auto",
|
|
1156
|
+
font: "Monaco, Consolas, monospace",
|
|
1157
|
+
size: "12px"
|
|
1158
|
+
},
|
|
1159
|
+
location: {
|
|
1160
|
+
show: true,
|
|
1161
|
+
color: "auto",
|
|
1162
|
+
font: "Monaco, Consolas, monospace",
|
|
1163
|
+
size: "10px",
|
|
1164
|
+
style: "clickable"
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
/**
|
|
1168
|
+
* Production preset - clean, essential info only
|
|
1169
|
+
*/
|
|
1170
|
+
production: {
|
|
1171
|
+
layout: {
|
|
1172
|
+
spacing: "normal",
|
|
1173
|
+
innerPadding: "2px",
|
|
1174
|
+
outerMargin: "1px"
|
|
1175
|
+
},
|
|
1176
|
+
timestamp: {
|
|
1177
|
+
show: true,
|
|
1178
|
+
color: "auto",
|
|
1179
|
+
font: "system-ui, sans-serif",
|
|
1180
|
+
size: "11px"
|
|
1181
|
+
},
|
|
1182
|
+
level: {
|
|
1183
|
+
show: true,
|
|
1184
|
+
style: "badge",
|
|
1185
|
+
uppercase: false,
|
|
1186
|
+
padding: "2px 6px"
|
|
1187
|
+
},
|
|
1188
|
+
prefix: {
|
|
1189
|
+
show: false
|
|
1190
|
+
// Hidden in production
|
|
1191
|
+
},
|
|
1192
|
+
message: {
|
|
1193
|
+
show: true,
|
|
1194
|
+
color: "auto",
|
|
1195
|
+
font: "system-ui, sans-serif",
|
|
1196
|
+
size: "14px"
|
|
1197
|
+
},
|
|
1198
|
+
location: {
|
|
1199
|
+
show: false
|
|
1200
|
+
// Hidden in production
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
function getSmartPreset(name) {
|
|
1205
|
+
return SMART_PRESETS[name] || null;
|
|
1206
|
+
}
|
|
1207
|
+
function getAvailablePresets() {
|
|
1208
|
+
return Object.keys(SMART_PRESETS);
|
|
1209
|
+
}
|
|
1210
|
+
function hasPreset(name) {
|
|
1211
|
+
return name in SMART_PRESETS;
|
|
1212
|
+
}
|
|
1213
|
+
class ExportLogHandler {
|
|
1214
|
+
buffer = [];
|
|
1215
|
+
maxSize;
|
|
1216
|
+
groupDepth = 0;
|
|
1217
|
+
currentGroup;
|
|
1218
|
+
constructor(maxSize = BUFFER_LIMITS.DEFAULT_SIZE) {
|
|
1219
|
+
this.maxSize = Math.min(Math.max(maxSize, BUFFER_LIMITS.MIN_SIZE), BUFFER_LIMITS.MAX_SIZE);
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Handle incoming log and store in buffer
|
|
1223
|
+
*/
|
|
1224
|
+
handle(level, message, args, metadata) {
|
|
1225
|
+
const entry = {
|
|
1226
|
+
id: generateLogId(),
|
|
1227
|
+
timestamp: metadata.timestamp,
|
|
1228
|
+
level,
|
|
1229
|
+
prefix: metadata.prefix,
|
|
1230
|
+
message,
|
|
1231
|
+
args,
|
|
1232
|
+
location: metadata.stackInfo,
|
|
1233
|
+
groupInfo: this.groupDepth > 0 ? {
|
|
1234
|
+
depth: this.groupDepth,
|
|
1235
|
+
groupName: this.currentGroup
|
|
1236
|
+
} : void 0
|
|
1237
|
+
};
|
|
1238
|
+
this.buffer.push(entry);
|
|
1239
|
+
if (this.buffer.length > this.maxSize) {
|
|
1240
|
+
this.buffer.shift();
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Set group tracking for nested logs
|
|
1245
|
+
*/
|
|
1246
|
+
setGroupInfo(depth, groupName) {
|
|
1247
|
+
this.groupDepth = depth;
|
|
1248
|
+
this.currentGroup = groupName;
|
|
1249
|
+
}
|
|
1250
|
+
/**
|
|
1251
|
+
* Get buffer statistics
|
|
1252
|
+
*/
|
|
1253
|
+
getBufferStats() {
|
|
1254
|
+
const levelCounts = this.buffer.reduce((acc, entry) => {
|
|
1255
|
+
const currentCount = acc[entry.level] ? acc[entry.level] : 0;
|
|
1256
|
+
acc[entry.level] = currentCount + 1;
|
|
1257
|
+
return acc;
|
|
1258
|
+
}, {});
|
|
1259
|
+
let oldestLog;
|
|
1260
|
+
let newestLog;
|
|
1261
|
+
if (this.buffer.length > 0) {
|
|
1262
|
+
const firstEntry = this.buffer[0];
|
|
1263
|
+
const lastEntry = this.buffer[this.buffer.length - 1];
|
|
1264
|
+
if (firstEntry && firstEntry.timestamp) {
|
|
1265
|
+
oldestLog = new Date(firstEntry.timestamp);
|
|
1266
|
+
}
|
|
1267
|
+
if (lastEntry && lastEntry.timestamp) {
|
|
1268
|
+
newestLog = new Date(lastEntry.timestamp);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return {
|
|
1272
|
+
size: this.buffer.length,
|
|
1273
|
+
maxSize: this.maxSize,
|
|
1274
|
+
usage: this.buffer.length / this.maxSize * 100,
|
|
1275
|
+
oldestLog,
|
|
1276
|
+
newestLog,
|
|
1277
|
+
levelCounts: {
|
|
1278
|
+
debug: levelCounts.debug ? levelCounts.debug : 0,
|
|
1279
|
+
info: levelCounts.info ? levelCounts.info : 0,
|
|
1280
|
+
warn: levelCounts.warn ? levelCounts.warn : 0,
|
|
1281
|
+
error: levelCounts.error ? levelCounts.error : 0,
|
|
1282
|
+
critical: levelCounts.critical ? levelCounts.critical : 0
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Clear the buffer
|
|
1288
|
+
*/
|
|
1289
|
+
clearBuffer() {
|
|
1290
|
+
this.buffer = [];
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Set buffer size (with limits)
|
|
1294
|
+
*/
|
|
1295
|
+
setBufferSize(size) {
|
|
1296
|
+
this.maxSize = Math.min(Math.max(size, BUFFER_LIMITS.MIN_SIZE), BUFFER_LIMITS.MAX_SIZE);
|
|
1297
|
+
if (this.buffer.length > this.maxSize) {
|
|
1298
|
+
this.buffer = this.buffer.slice(-this.maxSize);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Filter logs based on criteria
|
|
1303
|
+
*/
|
|
1304
|
+
filterLogs(filters = {}) {
|
|
1305
|
+
let filtered = [...this.buffer];
|
|
1306
|
+
if (filters.levels?.length) {
|
|
1307
|
+
filtered = filtered.filter((entry) => filters.levels.includes(entry.level));
|
|
1308
|
+
}
|
|
1309
|
+
if (filters.prefixes?.length) {
|
|
1310
|
+
filtered = filtered.filter(
|
|
1311
|
+
(entry) => entry.prefix && filters.prefixes.includes(entry.prefix)
|
|
1312
|
+
);
|
|
1313
|
+
}
|
|
1314
|
+
if (filters.excludePrefixes?.length) {
|
|
1315
|
+
filtered = filtered.filter(
|
|
1316
|
+
(entry) => !entry.prefix || !filters.excludePrefixes.includes(entry.prefix)
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
if (filters.since) {
|
|
1320
|
+
const sinceDate = parseTimeInput(filters.since);
|
|
1321
|
+
filtered = filtered.filter((entry) => new Date(entry.timestamp) >= sinceDate);
|
|
1322
|
+
}
|
|
1323
|
+
if (filters.until) {
|
|
1324
|
+
const untilDate = parseTimeInput(filters.until);
|
|
1325
|
+
filtered = filtered.filter((entry) => new Date(entry.timestamp) <= untilDate);
|
|
1326
|
+
}
|
|
1327
|
+
if (filters.withStackTrace) {
|
|
1328
|
+
filtered = filtered.filter((entry) => entry.location);
|
|
1329
|
+
}
|
|
1330
|
+
if (filters.errorsOnly) {
|
|
1331
|
+
filtered = filtered.filter((entry) => entry.level === "error" || entry.level === "critical");
|
|
1332
|
+
}
|
|
1333
|
+
if (filters.search) {
|
|
1334
|
+
const searchTerm = filters.search.toLowerCase();
|
|
1335
|
+
filtered = filtered.filter(
|
|
1336
|
+
(entry) => entry.message.toLowerCase().includes(searchTerm) || entry.args.some(
|
|
1337
|
+
(arg) => String(arg).toLowerCase().includes(searchTerm)
|
|
1338
|
+
)
|
|
1339
|
+
);
|
|
1340
|
+
}
|
|
1341
|
+
if (filters.last) {
|
|
1342
|
+
filtered = filtered.slice(-filters.last);
|
|
1343
|
+
}
|
|
1344
|
+
if (filters.first) {
|
|
1345
|
+
filtered = filtered.slice(0, filters.first);
|
|
1346
|
+
}
|
|
1347
|
+
return filtered;
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Export logs in JSON format
|
|
1351
|
+
*/
|
|
1352
|
+
exportJSON(logs, options) {
|
|
1353
|
+
const data = logs.map((entry) => ({
|
|
1354
|
+
timestamp: entry.timestamp,
|
|
1355
|
+
level: entry.level,
|
|
1356
|
+
prefix: entry.prefix,
|
|
1357
|
+
message: entry.message,
|
|
1358
|
+
...options.minimal ? {} : {
|
|
1359
|
+
args: entry.args.slice(1),
|
|
1360
|
+
location: entry.location,
|
|
1361
|
+
groupInfo: entry.groupInfo
|
|
1362
|
+
}
|
|
1363
|
+
}));
|
|
1364
|
+
return options.compact ? JSON.stringify(data) : JSON.stringify(data, null, 2);
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Export logs in CSV format
|
|
1368
|
+
*/
|
|
1369
|
+
exportCSV(logs, options) {
|
|
1370
|
+
const headers = options.minimal ? ["Timestamp", "Level", "Prefix", "Message"] : ["Timestamp", "Level", "Prefix", "Message", "File", "Line", "Args"];
|
|
1371
|
+
const rows = logs.map((entry) => {
|
|
1372
|
+
const baseRow = [
|
|
1373
|
+
formatDisplayTime(new Date(entry.timestamp), "full"),
|
|
1374
|
+
entry.level.toUpperCase(),
|
|
1375
|
+
entry.prefix || "",
|
|
1376
|
+
`"${entry.message.replace(/"/g, '""')}"`
|
|
1377
|
+
];
|
|
1378
|
+
if (!options.minimal) {
|
|
1379
|
+
baseRow.push(
|
|
1380
|
+
entry.location?.file || "",
|
|
1381
|
+
entry.location?.line?.toString() || "",
|
|
1382
|
+
`"${safeStringify(entry.args.slice(1)).replace(/"/g, '""')}"`
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1385
|
+
return baseRow;
|
|
1386
|
+
});
|
|
1387
|
+
return [headers.join(","), ...rows.map((row) => row.join(","))].join("\n");
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Export logs in Markdown format
|
|
1391
|
+
*/
|
|
1392
|
+
exportMarkdown(logs, options) {
|
|
1393
|
+
const now = /* @__PURE__ */ new Date();
|
|
1394
|
+
let content = `# Log Export - ${formatDisplayTime(now, "full")}
|
|
1395
|
+
|
|
1396
|
+
`;
|
|
1397
|
+
if (!options.minimal) {
|
|
1398
|
+
const summary = this.getBufferStats();
|
|
1399
|
+
content += `## Summary
|
|
1400
|
+
`;
|
|
1401
|
+
content += `- **Total logs**: ${logs.length}
|
|
1402
|
+
`;
|
|
1403
|
+
content += `- **Errors**: ${summary.levelCounts.error + summary.levelCounts.critical}
|
|
1404
|
+
`;
|
|
1405
|
+
content += `- **Warnings**: ${summary.levelCounts.warn}
|
|
1406
|
+
|
|
1407
|
+
`;
|
|
1408
|
+
}
|
|
1409
|
+
if (options.groupBy === "level") {
|
|
1410
|
+
const grouped = logs.reduce((acc, entry) => {
|
|
1411
|
+
const level = entry.level;
|
|
1412
|
+
if (!acc[level]) {
|
|
1413
|
+
acc[level] = [];
|
|
1414
|
+
}
|
|
1415
|
+
const levelArray = acc[level];
|
|
1416
|
+
if (levelArray) {
|
|
1417
|
+
levelArray.push(entry);
|
|
1418
|
+
}
|
|
1419
|
+
return acc;
|
|
1420
|
+
}, {});
|
|
1421
|
+
Object.entries(grouped).forEach(([level, entries]) => {
|
|
1422
|
+
const emoji = this.getLevelEmoji(level);
|
|
1423
|
+
content += `## ${emoji} ${level.toUpperCase()} (${entries.length})
|
|
1424
|
+
|
|
1425
|
+
`;
|
|
1426
|
+
entries.forEach((entry) => {
|
|
1427
|
+
const time = formatDisplayTime(new Date(entry.timestamp), "time-only");
|
|
1428
|
+
const location = entry.location ? ` (${entry.location.file}:${entry.location.line})` : "";
|
|
1429
|
+
const prefix = entry.prefix ? ` **${entry.prefix}**:` : "";
|
|
1430
|
+
content += `- \`${time}\`${prefix} ${entry.message}${location}
|
|
1431
|
+
`;
|
|
1432
|
+
});
|
|
1433
|
+
content += "\n";
|
|
1434
|
+
});
|
|
1435
|
+
} else {
|
|
1436
|
+
content += "## Logs\n\n";
|
|
1437
|
+
logs.forEach((entry) => {
|
|
1438
|
+
const time = formatDisplayTime(new Date(entry.timestamp), "time-only");
|
|
1439
|
+
const emoji = this.getLevelEmoji(entry.level);
|
|
1440
|
+
const location = entry.location ? ` (${entry.location.file}:${entry.location.line})` : "";
|
|
1441
|
+
const prefix = entry.prefix ? ` **${entry.prefix}**:` : "";
|
|
1442
|
+
content += `- \`${time}\` ${emoji}${prefix} ${entry.message}${location}
|
|
1443
|
+
`;
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
return content;
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Export logs in plain text format
|
|
1450
|
+
*/
|
|
1451
|
+
exportPlain(logs, options) {
|
|
1452
|
+
return logs.map((entry) => {
|
|
1453
|
+
const time = formatDisplayTime(new Date(entry.timestamp), options.minimal ? "time-only" : "short");
|
|
1454
|
+
const level = entry.level.toUpperCase().padEnd(8);
|
|
1455
|
+
const prefix = entry.prefix ? `[${entry.prefix}] ` : "";
|
|
1456
|
+
const location = !options.minimal && entry.location ? ` (${entry.location.file}:${entry.location.line})` : "";
|
|
1457
|
+
return `${time} ${level} ${prefix}${entry.message}${location}`;
|
|
1458
|
+
}).join("\n");
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Export logs in HTML format
|
|
1462
|
+
*/
|
|
1463
|
+
exportHTML(logs, _options) {
|
|
1464
|
+
const title = `Log Export - ${formatDisplayTime(/* @__PURE__ */ new Date(), "full")}`;
|
|
1465
|
+
let html = `<!DOCTYPE html>
|
|
1466
|
+
<html lang="en">
|
|
1467
|
+
<head>
|
|
1468
|
+
<meta charset="UTF-8">
|
|
1469
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1470
|
+
<title>${title}</title>
|
|
1471
|
+
<style>
|
|
1472
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 20px; line-height: 1.6; }
|
|
1473
|
+
.header { border-bottom: 2px solid #ddd; padding-bottom: 20px; margin-bottom: 20px; }
|
|
1474
|
+
.log-entry { margin: 5px 0; padding: 8px; border-radius: 4px; font-family: 'Monaco', 'Consolas', monospace; }
|
|
1475
|
+
.timestamp { color: #666; font-size: 0.9em; }
|
|
1476
|
+
.level { font-weight: bold; padding: 2px 6px; border-radius: 3px; margin: 0 8px; }
|
|
1477
|
+
.prefix { background: #2d3748; color: #e2e8f0; padding: 2px 6px; border-radius: 3px; margin: 0 8px; }
|
|
1478
|
+
.location { color: #718096; font-size: 0.9em; }
|
|
1479
|
+
.debug { background: #f0f4ff; }
|
|
1480
|
+
.info { background: #f0f9ff; }
|
|
1481
|
+
.warn { background: #fffbeb; }
|
|
1482
|
+
.error { background: #fef2f2; }
|
|
1483
|
+
.critical { background: #fef2f2; border-left: 4px solid #dc2626; }
|
|
1484
|
+
.level.debug { background: #667eea; color: white; }
|
|
1485
|
+
.level.info { background: #74b9ff; color: white; }
|
|
1486
|
+
.level.warn { background: #fdcb6e; color: #2d3436; }
|
|
1487
|
+
.level.error { background: #e84393; color: white; }
|
|
1488
|
+
.level.critical { background: #ff3838; color: white; }
|
|
1489
|
+
</style>
|
|
1490
|
+
</head>
|
|
1491
|
+
<body>
|
|
1492
|
+
<div class="header">
|
|
1493
|
+
<h1>${title}</h1>
|
|
1494
|
+
<p>Generated by Advanced Logger v2.0.0</p>
|
|
1495
|
+
</div>
|
|
1496
|
+
<div class="logs">`;
|
|
1497
|
+
logs.forEach((entry) => {
|
|
1498
|
+
const time = formatDisplayTime(new Date(entry.timestamp), "full");
|
|
1499
|
+
const location = entry.location ? ` <span class="location">(${escapeHtml(entry.location.file)}:${entry.location.line})</span>` : "";
|
|
1500
|
+
const prefix = entry.prefix ? ` <span class="prefix">${escapeHtml(entry.prefix)}</span>` : "";
|
|
1501
|
+
html += `
|
|
1502
|
+
<div class="log-entry ${entry.level}">
|
|
1503
|
+
<span class="timestamp">${time}</span>
|
|
1504
|
+
<span class="level ${entry.level}">${entry.level.toUpperCase()}</span>
|
|
1505
|
+
${prefix}
|
|
1506
|
+
<span class="message">${escapeHtml(entry.message)}</span>
|
|
1507
|
+
${location}
|
|
1508
|
+
</div>`;
|
|
1509
|
+
});
|
|
1510
|
+
html += `
|
|
1511
|
+
</div>
|
|
1512
|
+
</body>
|
|
1513
|
+
</html>`;
|
|
1514
|
+
return html;
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Get emoji for log level
|
|
1518
|
+
*/
|
|
1519
|
+
getLevelEmoji(level) {
|
|
1520
|
+
const emojis = {
|
|
1521
|
+
debug: "🐞",
|
|
1522
|
+
info: "ℹ️",
|
|
1523
|
+
warn: "⚠️",
|
|
1524
|
+
error: "❌",
|
|
1525
|
+
critical: "🔥"
|
|
1526
|
+
};
|
|
1527
|
+
return emojis[level] || "";
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* Main export function
|
|
1531
|
+
*/
|
|
1532
|
+
export(format, filters = {}, options = {}) {
|
|
1533
|
+
const filteredLogs = this.filterLogs(filters);
|
|
1534
|
+
let data;
|
|
1535
|
+
switch (format) {
|
|
1536
|
+
case "json":
|
|
1537
|
+
data = this.exportJSON(filteredLogs, options);
|
|
1538
|
+
break;
|
|
1539
|
+
case "csv":
|
|
1540
|
+
data = this.exportCSV(filteredLogs, options);
|
|
1541
|
+
break;
|
|
1542
|
+
case "markdown":
|
|
1543
|
+
data = this.exportMarkdown(filteredLogs, options);
|
|
1544
|
+
break;
|
|
1545
|
+
case "plain":
|
|
1546
|
+
data = this.exportPlain(filteredLogs, options);
|
|
1547
|
+
break;
|
|
1548
|
+
case "html":
|
|
1549
|
+
data = this.exportHTML(filteredLogs, options);
|
|
1550
|
+
break;
|
|
1551
|
+
default:
|
|
1552
|
+
throw new Error(`Unsupported export format: ${format}`);
|
|
1553
|
+
}
|
|
1554
|
+
return {
|
|
1555
|
+
format,
|
|
1556
|
+
data,
|
|
1557
|
+
metadata: {
|
|
1558
|
+
totalLogs: this.buffer.length,
|
|
1559
|
+
filteredLogs: filteredLogs.length,
|
|
1560
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1561
|
+
filters,
|
|
1562
|
+
options
|
|
1563
|
+
}
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
/**
|
|
1567
|
+
* Copy to clipboard with fallback
|
|
1568
|
+
*/
|
|
1569
|
+
async copyToClipboard(format, filters = {}, options = {}) {
|
|
1570
|
+
const result = this.export(format, filters, options);
|
|
1571
|
+
try {
|
|
1572
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
1573
|
+
await navigator.clipboard.writeText(result.data);
|
|
1574
|
+
return true;
|
|
1575
|
+
} else {
|
|
1576
|
+
const textArea = document.createElement("textarea");
|
|
1577
|
+
textArea.value = result.data;
|
|
1578
|
+
textArea.style.position = "fixed";
|
|
1579
|
+
textArea.style.opacity = "0";
|
|
1580
|
+
document.body.appendChild(textArea);
|
|
1581
|
+
textArea.focus();
|
|
1582
|
+
textArea.select();
|
|
1583
|
+
const success = document.execCommand("copy");
|
|
1584
|
+
document.body.removeChild(textArea);
|
|
1585
|
+
return success;
|
|
1586
|
+
}
|
|
1587
|
+
} catch (error) {
|
|
1588
|
+
console.error("Failed to copy to clipboard:", error);
|
|
1589
|
+
return false;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Get all logs (for debugging)
|
|
1594
|
+
*/
|
|
1595
|
+
getAllLogs() {
|
|
1596
|
+
return [...this.buffer];
|
|
1597
|
+
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Save export to file with download prompt
|
|
1600
|
+
*/
|
|
1601
|
+
async saveToFile(format, filters = {}, options = {}) {
|
|
1602
|
+
try {
|
|
1603
|
+
const result = this.export(format, filters, options);
|
|
1604
|
+
const blob = new Blob([result.data], {
|
|
1605
|
+
type: this.getMimeType(format)
|
|
1606
|
+
});
|
|
1607
|
+
const url = URL.createObjectURL(blob);
|
|
1608
|
+
const a = document.createElement("a");
|
|
1609
|
+
const filename = this.generateFilename(format, filters);
|
|
1610
|
+
a.href = url;
|
|
1611
|
+
a.download = filename;
|
|
1612
|
+
a.style.display = "none";
|
|
1613
|
+
document.body.appendChild(a);
|
|
1614
|
+
a.click();
|
|
1615
|
+
document.body.removeChild(a);
|
|
1616
|
+
URL.revokeObjectURL(url);
|
|
1617
|
+
return true;
|
|
1618
|
+
} catch (error) {
|
|
1619
|
+
console.error("Failed to save file:", error);
|
|
1620
|
+
return false;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Get MIME type for format
|
|
1625
|
+
*/
|
|
1626
|
+
getMimeType(format) {
|
|
1627
|
+
const mimeTypes = {
|
|
1628
|
+
json: "application/json",
|
|
1629
|
+
csv: "text/csv",
|
|
1630
|
+
markdown: "text/markdown",
|
|
1631
|
+
plain: "text/plain",
|
|
1632
|
+
html: "text/html"
|
|
1633
|
+
};
|
|
1634
|
+
return mimeTypes[format] || "text/plain";
|
|
1635
|
+
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Generate filename with timestamp
|
|
1638
|
+
*/
|
|
1639
|
+
generateFilename(format, filters) {
|
|
1640
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, -5);
|
|
1641
|
+
const prefix = filters.prefixes?.length === 1 ? `_${filters.prefixes[0]}` : "";
|
|
1642
|
+
const extension = format === "markdown" ? "md" : format;
|
|
1643
|
+
return `logs${prefix}_${timestamp}.${extension}`;
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Stream logs to external endpoint
|
|
1647
|
+
*/
|
|
1648
|
+
async streamToEndpoint(endpoint, filters = {}, options = {}) {
|
|
1649
|
+
try {
|
|
1650
|
+
const logs = this.filterLogs(filters);
|
|
1651
|
+
const batchSize = options.batchSize || 100;
|
|
1652
|
+
const format = options.format || "json";
|
|
1653
|
+
for (let i = 0; i < logs.length; i += batchSize) {
|
|
1654
|
+
const batch = logs.slice(i, i + batchSize);
|
|
1655
|
+
const result = this.export(format, {}, { compact: true });
|
|
1656
|
+
const headers = {
|
|
1657
|
+
"Content-Type": "application/json"
|
|
1658
|
+
};
|
|
1659
|
+
if (options.apiKey) {
|
|
1660
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
1661
|
+
}
|
|
1662
|
+
const response = await fetch(endpoint, {
|
|
1663
|
+
method: "POST",
|
|
1664
|
+
headers,
|
|
1665
|
+
body: JSON.stringify({
|
|
1666
|
+
logs: batch,
|
|
1667
|
+
metadata: {
|
|
1668
|
+
batchIndex: Math.floor(i / batchSize),
|
|
1669
|
+
totalBatches: Math.ceil(logs.length / batchSize),
|
|
1670
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1671
|
+
}
|
|
1672
|
+
})
|
|
1673
|
+
});
|
|
1674
|
+
if (!response.ok) {
|
|
1675
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
return true;
|
|
1679
|
+
} catch (error) {
|
|
1680
|
+
console.error("Failed to stream logs:", error);
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Create export with metadata enrichment
|
|
1686
|
+
*/
|
|
1687
|
+
exportWithMetadata(format, filters = {}, options = {}) {
|
|
1688
|
+
const baseResult = this.export(format, filters, options);
|
|
1689
|
+
const bufferStats = this.getBufferStats();
|
|
1690
|
+
return {
|
|
1691
|
+
...baseResult,
|
|
1692
|
+
metadata: {
|
|
1693
|
+
...baseResult.metadata,
|
|
1694
|
+
bufferStats,
|
|
1695
|
+
performance: {
|
|
1696
|
+
memoryUsage: this.estimateMemoryUsage(),
|
|
1697
|
+
processingTime: Date.now()
|
|
1698
|
+
},
|
|
1699
|
+
system: {
|
|
1700
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "Node.js",
|
|
1701
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1702
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Estimate memory usage of buffer
|
|
1709
|
+
*/
|
|
1710
|
+
estimateMemoryUsage() {
|
|
1711
|
+
const sampleEntry = this.buffer[0];
|
|
1712
|
+
if (!sampleEntry) return 0;
|
|
1713
|
+
const sampleSize = JSON.stringify(sampleEntry).length;
|
|
1714
|
+
return sampleSize * this.buffer.length;
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
class CommandProcessor {
|
|
1718
|
+
commands = /* @__PURE__ */ new Map();
|
|
1719
|
+
aliases = /* @__PURE__ */ new Map();
|
|
1720
|
+
plugins = /* @__PURE__ */ new Map();
|
|
1721
|
+
history = [];
|
|
1722
|
+
maxHistorySize = 100;
|
|
1723
|
+
isInteractiveMode = false;
|
|
1724
|
+
/**
|
|
1725
|
+
* Register a command
|
|
1726
|
+
*/
|
|
1727
|
+
registerCommand(command) {
|
|
1728
|
+
this.commands.set(command.name, command);
|
|
1729
|
+
if (command.aliases) {
|
|
1730
|
+
for (const alias of command.aliases) {
|
|
1731
|
+
this.aliases.set(alias, command.name);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
/**
|
|
1736
|
+
* Register a plugin
|
|
1737
|
+
*/
|
|
1738
|
+
registerPlugin(plugin, logger) {
|
|
1739
|
+
if (this.plugins.has(plugin.name)) {
|
|
1740
|
+
throw new Error(`Plugin ${plugin.name} is already registered`);
|
|
1741
|
+
}
|
|
1742
|
+
this.plugins.set(plugin.name, plugin);
|
|
1743
|
+
for (const command of plugin.commands) {
|
|
1744
|
+
this.registerCommand(command);
|
|
1745
|
+
}
|
|
1746
|
+
if (plugin.initialize && logger) {
|
|
1747
|
+
plugin.initialize(this, logger);
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Unregister a plugin
|
|
1752
|
+
*/
|
|
1753
|
+
unregisterPlugin(pluginName) {
|
|
1754
|
+
const plugin = this.plugins.get(pluginName);
|
|
1755
|
+
if (!plugin) return;
|
|
1756
|
+
for (const command of plugin.commands) {
|
|
1757
|
+
this.commands.delete(command.name);
|
|
1758
|
+
if (command.aliases) {
|
|
1759
|
+
for (const alias of command.aliases) {
|
|
1760
|
+
this.aliases.delete(alias);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
if (plugin.cleanup) {
|
|
1765
|
+
plugin.cleanup();
|
|
1766
|
+
}
|
|
1767
|
+
this.plugins.delete(pluginName);
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Get all registered commands
|
|
1771
|
+
*/
|
|
1772
|
+
getCommands() {
|
|
1773
|
+
return Array.from(this.commands.values());
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Get a specific command
|
|
1777
|
+
*/
|
|
1778
|
+
getCommand(name) {
|
|
1779
|
+
let command = this.commands.get(name);
|
|
1780
|
+
if (command) return command;
|
|
1781
|
+
const aliasTarget = this.aliases.get(name);
|
|
1782
|
+
if (aliasTarget) {
|
|
1783
|
+
return this.commands.get(aliasTarget);
|
|
1784
|
+
}
|
|
1785
|
+
return void 0;
|
|
1786
|
+
}
|
|
1787
|
+
/**
|
|
1788
|
+
* Get command history
|
|
1789
|
+
*/
|
|
1790
|
+
getHistory() {
|
|
1791
|
+
return [...this.history];
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Clear command history
|
|
1795
|
+
*/
|
|
1796
|
+
clearHistory() {
|
|
1797
|
+
this.history = [];
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* Get registered plugins
|
|
1801
|
+
*/
|
|
1802
|
+
getPlugins() {
|
|
1803
|
+
return Array.from(this.plugins.values());
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Enter interactive mode
|
|
1807
|
+
*/
|
|
1808
|
+
enterInteractiveMode(logger) {
|
|
1809
|
+
this.isInteractiveMode = true;
|
|
1810
|
+
logger.info("🔧 Interactive CLI mode activated. Type /exit to quit, /help for commands.");
|
|
1811
|
+
if (typeof window !== "undefined") {
|
|
1812
|
+
this.setupBrowserInteractiveMode(logger);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Exit interactive mode
|
|
1817
|
+
*/
|
|
1818
|
+
exitInteractiveMode() {
|
|
1819
|
+
this.isInteractiveMode = false;
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* Setup browser interactive mode
|
|
1823
|
+
*/
|
|
1824
|
+
setupBrowserInteractiveMode(logger) {
|
|
1825
|
+
window.cli = (commandString) => {
|
|
1826
|
+
return this.processCommand(`/${commandString}`, logger);
|
|
1827
|
+
};
|
|
1828
|
+
logger.info('💡 Use cli("command") to execute CLI commands in browser console.');
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Process a CLI command
|
|
1832
|
+
*/
|
|
1833
|
+
async processCommand(commandString, logger) {
|
|
1834
|
+
if (!commandString.startsWith("/")) {
|
|
1835
|
+
logger.error("Invalid command. Commands must start with /");
|
|
1836
|
+
this.addToHistory(commandString, false);
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
const parts = commandString.slice(1).split(" ");
|
|
1840
|
+
const commandName = parts[0] || "";
|
|
1841
|
+
const args = parts.slice(1).join(" ");
|
|
1842
|
+
const command = this.getCommand(commandName);
|
|
1843
|
+
if (!command) {
|
|
1844
|
+
logger.error(`Unknown command: ${commandName}. Type /help for available commands.`);
|
|
1845
|
+
const suggestions = this.getSuggestions(commandName);
|
|
1846
|
+
if (suggestions.length > 0) {
|
|
1847
|
+
logger.info(`📋 Did you mean: ${suggestions.slice(0, 3).join(", ")}?`);
|
|
1848
|
+
}
|
|
1849
|
+
this.addToHistory(commandString, false);
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
try {
|
|
1853
|
+
await command.execute(args || "", logger);
|
|
1854
|
+
this.addToHistory(commandString, true);
|
|
1855
|
+
} catch (error) {
|
|
1856
|
+
logger.error(`Command '${commandName}' failed:`, error);
|
|
1857
|
+
this.addToHistory(commandString, false);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Add command to history
|
|
1862
|
+
*/
|
|
1863
|
+
addToHistory(command, success) {
|
|
1864
|
+
this.history.unshift({
|
|
1865
|
+
command,
|
|
1866
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1867
|
+
success
|
|
1868
|
+
});
|
|
1869
|
+
if (this.history.length > this.maxHistorySize) {
|
|
1870
|
+
this.history = this.history.slice(0, this.maxHistorySize);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Get command suggestions for partial matches
|
|
1875
|
+
*/
|
|
1876
|
+
getSuggestions(partial) {
|
|
1877
|
+
const commandNames = Array.from(this.commands.keys());
|
|
1878
|
+
return commandNames.filter((name) => name.startsWith(partial));
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
class ConfigCommand {
|
|
1882
|
+
name = "config";
|
|
1883
|
+
description = "Show or update logger configuration";
|
|
1884
|
+
usage = "/config [json|key=value,...]";
|
|
1885
|
+
execute(args, logger) {
|
|
1886
|
+
if (!args) {
|
|
1887
|
+
this.showStatus(logger);
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
try {
|
|
1891
|
+
if (args.startsWith("{")) {
|
|
1892
|
+
const config = JSON.parse(args);
|
|
1893
|
+
this.applyConfig(config, logger);
|
|
1894
|
+
} else {
|
|
1895
|
+
const pairs = args.split(",").map((pair) => pair.trim().split("="));
|
|
1896
|
+
const config = {};
|
|
1897
|
+
pairs.forEach(([key, value]) => {
|
|
1898
|
+
if (key && value) {
|
|
1899
|
+
config[key.trim()] = value.trim().replace(/["']/g, "");
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
this.applyConfig(config, logger);
|
|
1903
|
+
}
|
|
1904
|
+
} catch (error) {
|
|
1905
|
+
logger.error("Invalid config format. Use JSON or key=value pairs:", error);
|
|
1906
|
+
logger.info('Examples: /config {"theme":"dark"} or /config theme=neon,verbosity=debug');
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
showStatus(logger) {
|
|
1910
|
+
const statusData = {
|
|
1911
|
+
theme: logger.getConfig().theme || "default",
|
|
1912
|
+
verbosity: logger.getConfig().verbosity,
|
|
1913
|
+
colors: logger.getConfig().enableColors,
|
|
1914
|
+
timestamps: logger.getConfig().enableTimestamps,
|
|
1915
|
+
stackTrace: logger.getConfig().enableStackTrace,
|
|
1916
|
+
globalPrefix: logger.getConfig().globalPrefix || "none",
|
|
1917
|
+
bannerType: logger.getConfig().bannerType || "simple",
|
|
1918
|
+
handlers: logger.getHandlers().length
|
|
1919
|
+
};
|
|
1920
|
+
logger.group("⚙️ Logger Configuration");
|
|
1921
|
+
logger.table(statusData);
|
|
1922
|
+
logger.groupEnd();
|
|
1923
|
+
}
|
|
1924
|
+
applyConfig(config, logger) {
|
|
1925
|
+
const validKeys = ["theme", "verbosity", "enableColors", "enableTimestamps", "enableStackTrace", "globalPrefix", "bannerType"];
|
|
1926
|
+
const applied = [];
|
|
1927
|
+
Object.entries(config).forEach(([key, value]) => {
|
|
1928
|
+
if (validKeys.includes(key)) {
|
|
1929
|
+
if (key === "theme" && typeof value === "string") {
|
|
1930
|
+
logger.setTheme(value);
|
|
1931
|
+
applied.push(`${key}=${value}`);
|
|
1932
|
+
} else if (key === "bannerType" && typeof value === "string") {
|
|
1933
|
+
logger.setBannerType(value);
|
|
1934
|
+
applied.push(`${key}=${value}`);
|
|
1935
|
+
} else if (key === "verbosity") {
|
|
1936
|
+
logger.setVerbosity(value);
|
|
1937
|
+
applied.push(`${key}=${value}`);
|
|
1938
|
+
} else if (key === "globalPrefix") {
|
|
1939
|
+
logger.setGlobalPrefix(value);
|
|
1940
|
+
applied.push(`${key}=${value}`);
|
|
1941
|
+
} else {
|
|
1942
|
+
logger.updateConfig({ [key]: value });
|
|
1943
|
+
applied.push(`${key}=${value}`);
|
|
1944
|
+
}
|
|
1945
|
+
} else {
|
|
1946
|
+
logger.warn(`Invalid config key: ${key}`);
|
|
1947
|
+
}
|
|
1948
|
+
});
|
|
1949
|
+
if (applied.length > 0) {
|
|
1950
|
+
logger.success(`Configuration updated: ${applied.join(", ")}`);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
class ThemesCommand {
|
|
1955
|
+
name = "themes";
|
|
1956
|
+
description = "Show available theme presets";
|
|
1957
|
+
usage = "/themes";
|
|
1958
|
+
execute(_args, logger) {
|
|
1959
|
+
logger.group("🎨 Available Themes");
|
|
1960
|
+
Object.keys(THEME_PRESETS).forEach((themeName) => {
|
|
1961
|
+
const preview = THEME_PRESETS[themeName];
|
|
1962
|
+
const previewStyle = new StyleBuilder().bg(preview.info.background).color(preview.info.color).padding("4px 8px").rounded("4px").border(preview.info.border).build();
|
|
1963
|
+
console.log(`%c${themeName}`, previewStyle, `- ${themeName} theme preview`);
|
|
1964
|
+
});
|
|
1965
|
+
logger.groupEnd();
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
class BannersCommand {
|
|
1969
|
+
name = "banners";
|
|
1970
|
+
description = "Show available banner types";
|
|
1971
|
+
usage = "/banners";
|
|
1972
|
+
execute(_args, logger) {
|
|
1973
|
+
logger.group("🖼️ Available Banner Types");
|
|
1974
|
+
Object.keys(BANNER_VARIANTS).forEach((bannerName) => {
|
|
1975
|
+
const banner = BANNER_VARIANTS[bannerName];
|
|
1976
|
+
console.log(`%c${bannerName}`, "font-weight: bold; color: #667eea;");
|
|
1977
|
+
console.log(`%cPreview:`, "color: #666; font-size: 12px;");
|
|
1978
|
+
if (bannerName === "simple") {
|
|
1979
|
+
console.log(`%c${banner.text}`, banner.style);
|
|
1980
|
+
} else if (bannerName === "ascii") {
|
|
1981
|
+
console.log(`%c${banner.text.split("\n").slice(1, 4).join("\n")}...`, "font-family: monospace; color: #667eea; font-size: 10px;");
|
|
1982
|
+
} else if (bannerName === "unicode") {
|
|
1983
|
+
console.log(`%c${banner.text}`, banner.style);
|
|
1984
|
+
} else {
|
|
1985
|
+
console.log(`%c${bannerName} banner`, "color: #666; font-style: italic;");
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
logger.groupEnd();
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
class BannerCommand {
|
|
1992
|
+
name = "banner";
|
|
1993
|
+
description = "Change or show current banner type";
|
|
1994
|
+
usage = "/banner [type]";
|
|
1995
|
+
execute(args, logger) {
|
|
1996
|
+
if (!args) {
|
|
1997
|
+
logger.showBanner();
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
if (args in BANNER_VARIANTS) {
|
|
2001
|
+
logger.setBannerType(args);
|
|
2002
|
+
logger.showBanner();
|
|
2003
|
+
} else {
|
|
2004
|
+
logger.error(`Invalid banner type: ${args}. Available: ${Object.keys(BANNER_VARIANTS).join(", ")}`);
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
class StatusCommand {
|
|
2009
|
+
name = "status";
|
|
2010
|
+
description = "Show current logger status and configuration";
|
|
2011
|
+
usage = "/status";
|
|
2012
|
+
execute(_args, logger) {
|
|
2013
|
+
const config = logger.getConfig();
|
|
2014
|
+
const statusData = {
|
|
2015
|
+
theme: config.theme ? config.theme : "default",
|
|
2016
|
+
verbosity: config.verbosity,
|
|
2017
|
+
colors: config.enableColors,
|
|
2018
|
+
timestamps: config.enableTimestamps,
|
|
2019
|
+
stackTrace: config.enableStackTrace,
|
|
2020
|
+
globalPrefix: config.globalPrefix ? config.globalPrefix : "none",
|
|
2021
|
+
bannerType: config.bannerType ? config.bannerType : "simple",
|
|
2022
|
+
handlers: logger.getHandlers().length,
|
|
2023
|
+
bufferSize: config.bufferSize ? config.bufferSize : 1e3
|
|
2024
|
+
};
|
|
2025
|
+
logger.group("⚙️ Logger Configuration");
|
|
2026
|
+
logger.table(statusData);
|
|
2027
|
+
logger.groupEnd();
|
|
2028
|
+
const exportHandler = logger.getExportHandler();
|
|
2029
|
+
if (exportHandler) {
|
|
2030
|
+
const bufferStats = exportHandler.getBufferStats();
|
|
2031
|
+
logger.group("📊 Buffer Statistics");
|
|
2032
|
+
logger.table({
|
|
2033
|
+
size: `${bufferStats.size}/${bufferStats.maxSize}`,
|
|
2034
|
+
usage: `${bufferStats.usage.toFixed(1)}%`,
|
|
2035
|
+
oldestLog: bufferStats.oldestLog ? bufferStats.oldestLog.toISOString() : "None",
|
|
2036
|
+
newestLog: bufferStats.newestLog ? bufferStats.newestLog.toISOString() : "None",
|
|
2037
|
+
errorCount: bufferStats.levelCounts.error + bufferStats.levelCounts.critical,
|
|
2038
|
+
warningCount: bufferStats.levelCounts.warn
|
|
2039
|
+
});
|
|
2040
|
+
logger.groupEnd();
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
class ResetCommand {
|
|
2045
|
+
name = "reset";
|
|
2046
|
+
description = "Reset logger configuration to defaults";
|
|
2047
|
+
usage = "/reset";
|
|
2048
|
+
execute(_args, logger) {
|
|
2049
|
+
logger.resetConfig();
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
class DemoCommand {
|
|
2053
|
+
name = "demo";
|
|
2054
|
+
description = "Show comprehensive feature demonstration";
|
|
2055
|
+
usage = "/demo";
|
|
2056
|
+
execute(_args, logger) {
|
|
2057
|
+
logger.group("🎪 Advanced Logger Demo");
|
|
2058
|
+
logger.debug("Debug message with detailed information");
|
|
2059
|
+
logger.info("Informational message about system state");
|
|
2060
|
+
logger.warn("Warning about deprecated feature");
|
|
2061
|
+
logger.error("Error processing user request");
|
|
2062
|
+
logger.success("Operation completed successfully");
|
|
2063
|
+
logger.critical("Critical system failure detected");
|
|
2064
|
+
logger.group("📊 Advanced Features Demo");
|
|
2065
|
+
logger.table([
|
|
2066
|
+
{ feature: "Styled Console", status: "✅ Active", performance: "Excellent" },
|
|
2067
|
+
{ feature: "Theme System", status: "✅ Active", performance: "Great" },
|
|
2068
|
+
{ feature: "CLI Interface", status: "✅ Active", performance: "Good" },
|
|
2069
|
+
{ feature: "Export System", status: "✅ Active", performance: "Excellent" }
|
|
2070
|
+
]);
|
|
2071
|
+
logger.time("demo-operation");
|
|
2072
|
+
setTimeout(() => {
|
|
2073
|
+
logger.timeEnd("demo-operation");
|
|
2074
|
+
}, 100);
|
|
2075
|
+
logger.logWithSVG("SVG Demo");
|
|
2076
|
+
logger.logAnimated("🌟 Animated Logger Demo 🌟", 2);
|
|
2077
|
+
logger.groupEnd();
|
|
2078
|
+
logger.groupEnd();
|
|
2079
|
+
logger.info("Demo completed! Check the console for styled output.");
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
function parseArguments(args) {
|
|
2083
|
+
const filters = {};
|
|
2084
|
+
const options = {};
|
|
2085
|
+
let format;
|
|
2086
|
+
if (!args.trim()) return { filters, options };
|
|
2087
|
+
const argParts = args.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
|
|
2088
|
+
for (let i = 0; i < argParts.length; i++) {
|
|
2089
|
+
const arg = argParts[i];
|
|
2090
|
+
if (!arg) {
|
|
2091
|
+
continue;
|
|
2092
|
+
}
|
|
2093
|
+
if (i === 0 && !arg.startsWith("--") && arg in EXPORT_FORMATS) {
|
|
2094
|
+
format = arg;
|
|
2095
|
+
continue;
|
|
2096
|
+
}
|
|
2097
|
+
if (arg.startsWith("--")) {
|
|
2098
|
+
const [flag, value] = arg.slice(2).split("=");
|
|
2099
|
+
switch (flag) {
|
|
2100
|
+
case "level":
|
|
2101
|
+
case "levels":
|
|
2102
|
+
if (value) {
|
|
2103
|
+
filters.levels = value.split(",").map((l) => l.trim());
|
|
2104
|
+
}
|
|
2105
|
+
break;
|
|
2106
|
+
case "since":
|
|
2107
|
+
if (value) filters.since = value;
|
|
2108
|
+
break;
|
|
2109
|
+
case "until":
|
|
2110
|
+
if (value) filters.until = value;
|
|
2111
|
+
break;
|
|
2112
|
+
case "prefix":
|
|
2113
|
+
case "prefixes":
|
|
2114
|
+
if (value) {
|
|
2115
|
+
filters.prefixes = value.split(",").map((p) => p.trim());
|
|
2116
|
+
}
|
|
2117
|
+
break;
|
|
2118
|
+
case "exclude-prefix":
|
|
2119
|
+
case "exclude-prefixes":
|
|
2120
|
+
if (value) {
|
|
2121
|
+
filters.excludePrefixes = value.split(",").map((p) => p.trim());
|
|
2122
|
+
}
|
|
2123
|
+
break;
|
|
2124
|
+
case "last":
|
|
2125
|
+
if (value) filters.last = parseInt(value, 10);
|
|
2126
|
+
break;
|
|
2127
|
+
case "first":
|
|
2128
|
+
if (value) filters.first = parseInt(value, 10);
|
|
2129
|
+
break;
|
|
2130
|
+
case "search":
|
|
2131
|
+
if (value) filters.search = value.replace(/['"]/g, "");
|
|
2132
|
+
break;
|
|
2133
|
+
case "with-stack":
|
|
2134
|
+
filters.withStackTrace = true;
|
|
2135
|
+
break;
|
|
2136
|
+
case "errors-only":
|
|
2137
|
+
filters.errorsOnly = true;
|
|
2138
|
+
break;
|
|
2139
|
+
case "group-by":
|
|
2140
|
+
if (value) {
|
|
2141
|
+
filters.groupBy = value;
|
|
2142
|
+
options.groupBy = value;
|
|
2143
|
+
}
|
|
2144
|
+
break;
|
|
2145
|
+
case "minimal":
|
|
2146
|
+
options.minimal = true;
|
|
2147
|
+
break;
|
|
2148
|
+
case "compact":
|
|
2149
|
+
options.compact = true;
|
|
2150
|
+
break;
|
|
2151
|
+
case "styled":
|
|
2152
|
+
options.styled = true;
|
|
2153
|
+
break;
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
return { filters, options, format };
|
|
2158
|
+
}
|
|
2159
|
+
class ExportCommand {
|
|
2160
|
+
name = "export";
|
|
2161
|
+
description = "Export logs to various formats";
|
|
2162
|
+
usage = "/export <format> [--filter=value] [--option]";
|
|
2163
|
+
execute(args, logger) {
|
|
2164
|
+
const exportHandler = logger.getExportHandler();
|
|
2165
|
+
if (!exportHandler) {
|
|
2166
|
+
logger.error("Export handler not available. Make sure ExportLogHandler is registered.");
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
2169
|
+
const { filters, options, format } = parseArguments(args);
|
|
2170
|
+
if (!format) {
|
|
2171
|
+
logger.error("Format required. Available formats: " + Object.keys(EXPORT_FORMATS).join(", "));
|
|
2172
|
+
logger.info("Usage: /export <format> [--filter=value]");
|
|
2173
|
+
logger.info("Example: /export json --level=error,warn --last=50");
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
try {
|
|
2177
|
+
const result = exportHandler.export(format, filters, options);
|
|
2178
|
+
logger.success(`✅ Export completed: ${result.metadata.filteredLogs} logs exported in ${format} format`);
|
|
2179
|
+
if (result.data.length < 1e3) {
|
|
2180
|
+
logger.group(`📄 Preview (${format.toUpperCase()})`);
|
|
2181
|
+
console.log(result.data);
|
|
2182
|
+
logger.groupEnd();
|
|
2183
|
+
} else {
|
|
2184
|
+
logger.info(`📄 Export size: ${(result.data.length / 1024).toFixed(2)}KB`);
|
|
2185
|
+
}
|
|
2186
|
+
logger.table({
|
|
2187
|
+
format: result.format,
|
|
2188
|
+
totalLogs: result.metadata.totalLogs,
|
|
2189
|
+
filtered: result.metadata.filteredLogs,
|
|
2190
|
+
exported: result.metadata.exportedAt
|
|
2191
|
+
});
|
|
2192
|
+
} catch (error) {
|
|
2193
|
+
logger.error("Export failed:", error);
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
class CopyCommand {
|
|
2198
|
+
name = "copy";
|
|
2199
|
+
description = "Copy logs to clipboard";
|
|
2200
|
+
usage = "/copy <format> [--filter=value] [--option]";
|
|
2201
|
+
async execute(args, logger) {
|
|
2202
|
+
const exportHandler = logger.getExportHandler();
|
|
2203
|
+
if (!exportHandler) {
|
|
2204
|
+
logger.error("Export handler not available. Make sure ExportLogHandler is registered.");
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
const { filters, options, format } = parseArguments(args);
|
|
2208
|
+
if (!format) {
|
|
2209
|
+
logger.error("Format required. Available formats: " + Object.keys(EXPORT_FORMATS).join(", "));
|
|
2210
|
+
logger.info("Usage: /copy <format> [--filter=value]");
|
|
2211
|
+
logger.info("Example: /copy plain --level=error --last=25");
|
|
2212
|
+
return;
|
|
2213
|
+
}
|
|
2214
|
+
try {
|
|
2215
|
+
const success = await exportHandler.copyToClipboard(format, filters, options);
|
|
2216
|
+
if (success) {
|
|
2217
|
+
const result = exportHandler.export(format, filters, options);
|
|
2218
|
+
logger.success(`📋 Copied ${result.metadata.filteredLogs} logs to clipboard (${format} format)`);
|
|
2219
|
+
} else {
|
|
2220
|
+
logger.error("Failed to copy to clipboard. Browser may not support clipboard API.");
|
|
2221
|
+
}
|
|
2222
|
+
} catch (error) {
|
|
2223
|
+
logger.error("Copy failed:", error);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
class BufferSizeCommand {
|
|
2228
|
+
name = "buffer-size";
|
|
2229
|
+
description = "Set log buffer size";
|
|
2230
|
+
usage = "/buffer-size <size>";
|
|
2231
|
+
execute(args, logger) {
|
|
2232
|
+
const exportHandler = logger.getExportHandler();
|
|
2233
|
+
if (!exportHandler) {
|
|
2234
|
+
logger.error("Export handler not available.");
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
const size = parseInt(args.trim(), 10);
|
|
2238
|
+
if (isNaN(size) || size <= 0) {
|
|
2239
|
+
logger.error("Invalid buffer size. Must be a positive number.");
|
|
2240
|
+
logger.info("Example: /buffer-size 2000");
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
exportHandler.setBufferSize(size);
|
|
2244
|
+
logger.success(`Buffer size set to ${size}`);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
class ClearBufferCommand {
|
|
2248
|
+
name = "clear-buffer";
|
|
2249
|
+
description = "Clear the log buffer";
|
|
2250
|
+
usage = "/clear-buffer";
|
|
2251
|
+
execute(_args, logger) {
|
|
2252
|
+
const exportHandler = logger.getExportHandler();
|
|
2253
|
+
if (!exportHandler) {
|
|
2254
|
+
logger.error("Export handler not available.");
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
const stats = exportHandler.getBufferStats();
|
|
2258
|
+
exportHandler.clearBuffer();
|
|
2259
|
+
logger.success(`✅ Buffer cleared. Removed ${stats.size} log entries.`);
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
class BufferInfoCommand {
|
|
2263
|
+
name = "buffer-info";
|
|
2264
|
+
description = "Show buffer statistics and information";
|
|
2265
|
+
usage = "/buffer-info";
|
|
2266
|
+
execute(_args, logger) {
|
|
2267
|
+
const exportHandler = logger.getExportHandler();
|
|
2268
|
+
if (!exportHandler) {
|
|
2269
|
+
logger.error("Export handler not available.");
|
|
2270
|
+
return;
|
|
2271
|
+
}
|
|
2272
|
+
const stats = exportHandler.getBufferStats();
|
|
2273
|
+
logger.group("📊 Buffer Information");
|
|
2274
|
+
logger.table({
|
|
2275
|
+
size: `${stats.size}/${stats.maxSize}`,
|
|
2276
|
+
usage: `${stats.usage.toFixed(1)}%`,
|
|
2277
|
+
oldestLog: stats.oldestLog?.toLocaleString() || "None",
|
|
2278
|
+
newestLog: stats.newestLog?.toLocaleString() || "None"
|
|
2279
|
+
});
|
|
2280
|
+
logger.group("📈 Log Level Counts");
|
|
2281
|
+
logger.table(stats.levelCounts);
|
|
2282
|
+
logger.groupEnd();
|
|
2283
|
+
logger.groupEnd();
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
class HelpCommand {
|
|
2287
|
+
name = "help";
|
|
2288
|
+
description = "Show CLI help and available commands";
|
|
2289
|
+
usage = "/help [command]";
|
|
2290
|
+
execute(_args, logger) {
|
|
2291
|
+
const helpStyle = new StyleBuilder().bg("linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)").color("#495057").padding("15px 20px").rounded("8px").border("1px solid #dee2e6").font("Monaco, Consolas, monospace").size("13px").build();
|
|
2292
|
+
const helpText = `
|
|
2293
|
+
╭─────────────── ADVANCED LOGGER CLI COMMANDS ─────────────────╮
|
|
2294
|
+
│ │
|
|
2295
|
+
│ CONFIGURATION │
|
|
2296
|
+
│ /config Show current configuration │
|
|
2297
|
+
│ /config {json} Apply JSON configuration │
|
|
2298
|
+
│ /config key=val Apply key-value configuration │
|
|
2299
|
+
│ /themes Show available themes │
|
|
2300
|
+
│ /banners Show available banner types │
|
|
2301
|
+
│ /banner [type] Change/show banner type │
|
|
2302
|
+
│ /status Show logger status & buffer stats │
|
|
2303
|
+
│ /demo Show feature demonstration │
|
|
2304
|
+
│ /reset Reset to default configuration │
|
|
2305
|
+
│ │
|
|
2306
|
+
│ EXPORT & CLIPBOARD │
|
|
2307
|
+
│ /export <format> Export logs (json|csv|md|plain|html) │
|
|
2308
|
+
│ /copy <format> Copy logs to clipboard │
|
|
2309
|
+
│ /buffer-size N Set log buffer size │
|
|
2310
|
+
│ /buffer-info Show buffer statistics │
|
|
2311
|
+
│ /clear-buffer Clear stored logs │
|
|
2312
|
+
│ │
|
|
2313
|
+
│ EXPORT FILTERS (for export/copy commands) │
|
|
2314
|
+
│ --level error,warn Filter by log levels │
|
|
2315
|
+
│ --since 2h Logs from last 2 hours │
|
|
2316
|
+
│ --until 1h Logs until 1 hour ago │
|
|
2317
|
+
│ --prefix API,DB Filter by prefixes │
|
|
2318
|
+
│ --exclude-prefix INT Exclude prefixes │
|
|
2319
|
+
│ --last 50 Last 50 logs only │
|
|
2320
|
+
│ --first 25 First 25 logs only │
|
|
2321
|
+
│ --search "error" Search in log messages │
|
|
2322
|
+
│ --with-stack Only logs with stack traces │
|
|
2323
|
+
│ --errors-only Only error + critical logs │
|
|
2324
|
+
│ --group-by level Group by level/prefix/hour │
|
|
2325
|
+
│ │
|
|
2326
|
+
│ EXPORT OPTIONS │
|
|
2327
|
+
│ --minimal Minimal output format │
|
|
2328
|
+
│ --compact Remove extra whitespace │
|
|
2329
|
+
│ --styled Include styling (HTML format) │
|
|
2330
|
+
│ │
|
|
2331
|
+
├──────────────────── CONFIGURATION OPTIONS ─────────────────┤
|
|
2332
|
+
│ │
|
|
2333
|
+
│ theme: default | dark | light | neon | minimal | cyberpunk│
|
|
2334
|
+
│ bannerType: simple | ascii | unicode | svg | animated │
|
|
2335
|
+
│ verbosity: debug | info | warn | error | critical | silent│
|
|
2336
|
+
│ enableColors: true | false │
|
|
2337
|
+
│ enableTimestamps: true | false │
|
|
2338
|
+
│ enableStackTrace: true | false │
|
|
2339
|
+
│ globalPrefix: "string" │
|
|
2340
|
+
│ bufferSize: number (50-10000) │
|
|
2341
|
+
│ │
|
|
2342
|
+
├──────────────────────── EXAMPLES ──────────────────────────┤
|
|
2343
|
+
│ │
|
|
2344
|
+
│ Basic Configuration: │
|
|
2345
|
+
│ /config {"theme":"dark","verbosity":"debug"} │
|
|
2346
|
+
│ /config theme=neon,bufferSize=2000 │
|
|
2347
|
+
│ /banner animated Change to animated banner │
|
|
2348
|
+
│ │
|
|
2349
|
+
│ Export Examples: │
|
|
2350
|
+
│ /export json --level=error,warn --last=25 │
|
|
2351
|
+
│ /export csv --since=2h --prefix=API │
|
|
2352
|
+
│ /export markdown --group-by=level --errors-only │
|
|
2353
|
+
│ /export html --styled --since=1h │
|
|
2354
|
+
│ │
|
|
2355
|
+
│ Clipboard Examples: │
|
|
2356
|
+
│ /copy plain --minimal --last=10 │
|
|
2357
|
+
│ /copy json --search="authentication" --compact │
|
|
2358
|
+
│ /copy csv --since=30m --exclude-prefix=DEBUG │
|
|
2359
|
+
│ │
|
|
2360
|
+
│ Buffer Management: │
|
|
2361
|
+
│ /buffer-size 5000 Increase buffer to 5000 logs │
|
|
2362
|
+
│ /buffer-info Show detailed buffer statistics │
|
|
2363
|
+
│ /clear-buffer Clear all stored logs │
|
|
2364
|
+
│ │
|
|
2365
|
+
│ Time Formats: │
|
|
2366
|
+
│ --since=2h 2 hours ago │
|
|
2367
|
+
│ --since=30m 30 minutes ago │
|
|
2368
|
+
│ --since=1d 1 day ago │
|
|
2369
|
+
│ --since="2024-01-01T10:00:00Z" Specific ISO date │
|
|
2370
|
+
│ │
|
|
2371
|
+
╰─────────────────────────────────────────────────────────────╯`;
|
|
2372
|
+
console.log(`%c${helpText}`, helpStyle);
|
|
2373
|
+
logger.group("💡 Quick Tips");
|
|
2374
|
+
const tips = [
|
|
2375
|
+
"Use /demo to see all logger features in action",
|
|
2376
|
+
"Logs are automatically stored in a circular buffer for export",
|
|
2377
|
+
"Export formats: JSON (structured), CSV (Excel), Markdown (readable), Plain (simple), HTML (styled)",
|
|
2378
|
+
"Time filters support relative (2h, 30m) and absolute (ISO) formats",
|
|
2379
|
+
'Combine multiple filters: /export json --level=error --since=1h --search="auth"',
|
|
2380
|
+
"Use /copy for quick clipboard access instead of /export"
|
|
2381
|
+
];
|
|
2382
|
+
tips.forEach((tip) => {
|
|
2383
|
+
logger.info(`• ${tip}`);
|
|
2384
|
+
});
|
|
2385
|
+
logger.groupEnd();
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
class HistoryCommand {
|
|
2389
|
+
name = "history";
|
|
2390
|
+
description = "Show command execution history";
|
|
2391
|
+
usage = "/history [limit] - Show recent commands (default: 10)";
|
|
2392
|
+
category = "system";
|
|
2393
|
+
aliases = ["hist", "h"];
|
|
2394
|
+
execute(args, logger) {
|
|
2395
|
+
const processor = logger.cliProcessor;
|
|
2396
|
+
if (!processor) {
|
|
2397
|
+
logger.error("CLI processor not available");
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2400
|
+
const limit = parseInt(args) || 10;
|
|
2401
|
+
const history = processor.getHistory().slice(0, limit);
|
|
2402
|
+
if (history.length === 0) {
|
|
2403
|
+
logger.info("📝 No command history available");
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
logger.info(`📋 Last ${history.length} commands:`);
|
|
2407
|
+
history.forEach((entry, index) => {
|
|
2408
|
+
const status = entry.success ? "✅" : "❌";
|
|
2409
|
+
const time = entry.timestamp.toLocaleTimeString();
|
|
2410
|
+
logger.info(`${status} [${time}] ${entry.command}`);
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
class ClearHistoryCommand {
|
|
2415
|
+
name = "clearhistory";
|
|
2416
|
+
description = "Clear command execution history";
|
|
2417
|
+
usage = "/clearhistory - Remove all command history";
|
|
2418
|
+
category = "system";
|
|
2419
|
+
aliases = ["clrhist"];
|
|
2420
|
+
execute(args, logger) {
|
|
2421
|
+
const processor = logger.cliProcessor;
|
|
2422
|
+
if (!processor) {
|
|
2423
|
+
logger.error("CLI processor not available");
|
|
2424
|
+
return;
|
|
2425
|
+
}
|
|
2426
|
+
processor.clearHistory();
|
|
2427
|
+
logger.success("🗑️ Command history cleared");
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
class InteractiveCommand {
|
|
2431
|
+
name = "interactive";
|
|
2432
|
+
description = "Enter interactive CLI mode";
|
|
2433
|
+
usage = "/interactive - Start interactive command mode";
|
|
2434
|
+
category = "system";
|
|
2435
|
+
aliases = ["i", "repl"];
|
|
2436
|
+
execute(args, logger) {
|
|
2437
|
+
const processor = logger.cliProcessor;
|
|
2438
|
+
if (!processor) {
|
|
2439
|
+
logger.error("CLI processor not available");
|
|
2440
|
+
return;
|
|
2441
|
+
}
|
|
2442
|
+
processor.enterInteractiveMode(logger);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
class PluginsCommand {
|
|
2446
|
+
name = "plugins";
|
|
2447
|
+
description = "List loaded CLI plugins";
|
|
2448
|
+
usage = "/plugins - Show all registered plugins";
|
|
2449
|
+
category = "system";
|
|
2450
|
+
aliases = ["plug"];
|
|
2451
|
+
execute(args, logger) {
|
|
2452
|
+
const processor = logger.cliProcessor;
|
|
2453
|
+
if (!processor) {
|
|
2454
|
+
logger.error("CLI processor not available");
|
|
2455
|
+
return;
|
|
2456
|
+
}
|
|
2457
|
+
const plugins = processor.getPlugins();
|
|
2458
|
+
if (plugins.length === 0) {
|
|
2459
|
+
logger.info("🔌 No plugins registered");
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
logger.info(`🔌 Loaded plugins (${plugins.length}):`);
|
|
2463
|
+
plugins.forEach((plugin) => {
|
|
2464
|
+
logger.info(` 📦 ${plugin.name} v${plugin.version} - ${plugin.description}`);
|
|
2465
|
+
logger.info(` Commands: ${plugin.commands.map((c) => c.name).join(", ")}`);
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
function createDefaultCLI() {
|
|
2470
|
+
const processor = new CommandProcessor();
|
|
2471
|
+
processor.registerCommand(new HelpCommand());
|
|
2472
|
+
processor.registerCommand(new ConfigCommand());
|
|
2473
|
+
processor.registerCommand(new ThemesCommand());
|
|
2474
|
+
processor.registerCommand(new BannersCommand());
|
|
2475
|
+
processor.registerCommand(new BannerCommand());
|
|
2476
|
+
processor.registerCommand(new StatusCommand());
|
|
2477
|
+
processor.registerCommand(new ResetCommand());
|
|
2478
|
+
processor.registerCommand(new DemoCommand());
|
|
2479
|
+
processor.registerCommand(new ExportCommand());
|
|
2480
|
+
processor.registerCommand(new CopyCommand());
|
|
2481
|
+
processor.registerCommand(new BufferSizeCommand());
|
|
2482
|
+
processor.registerCommand(new ClearBufferCommand());
|
|
2483
|
+
processor.registerCommand(new BufferInfoCommand());
|
|
2484
|
+
processor.registerCommand(new HistoryCommand());
|
|
2485
|
+
processor.registerCommand(new ClearHistoryCommand());
|
|
2486
|
+
processor.registerCommand(new InteractiveCommand());
|
|
2487
|
+
processor.registerCommand(new PluginsCommand());
|
|
2488
|
+
return processor;
|
|
2489
|
+
}
|
|
2490
|
+
let LEVEL_STYLES = THEME_PRESETS.default;
|
|
2491
|
+
class Logger {
|
|
2492
|
+
config;
|
|
2493
|
+
scopedPrefix;
|
|
2494
|
+
handlers = [];
|
|
2495
|
+
timers = /* @__PURE__ */ new Map();
|
|
2496
|
+
groupDepth = 0;
|
|
2497
|
+
exportHandler;
|
|
2498
|
+
cliProcessor;
|
|
2499
|
+
themeChangeListener;
|
|
2500
|
+
displaySettings = {
|
|
2501
|
+
showTimestamp: true,
|
|
2502
|
+
showLocation: true,
|
|
2503
|
+
showBadges: true
|
|
2504
|
+
};
|
|
2505
|
+
/**
|
|
2506
|
+
* Crea una nueva instancia del Logger
|
|
2507
|
+
*
|
|
2508
|
+
* @param {Partial<LoggerConfig>} config - Configuración opcional del logger
|
|
2509
|
+
*
|
|
2510
|
+
* @example
|
|
2511
|
+
* // Logger con configuración personalizada
|
|
2512
|
+
* const logger = new Logger({
|
|
2513
|
+
* theme: 'neon',
|
|
2514
|
+
* globalPrefix: 'MiApp',
|
|
2515
|
+
* verbosity: 'debug',
|
|
2516
|
+
* bufferSize: 1000
|
|
2517
|
+
* });
|
|
2518
|
+
*/
|
|
2519
|
+
constructor(config = {}) {
|
|
2520
|
+
this.config = {
|
|
2521
|
+
...DEFAULT_CONFIG,
|
|
2522
|
+
...config
|
|
2523
|
+
};
|
|
2524
|
+
if (this.config.bufferSize) {
|
|
2525
|
+
this.exportHandler = new ExportLogHandler(this.config.bufferSize);
|
|
2526
|
+
this.handlers.push(this.exportHandler);
|
|
2527
|
+
}
|
|
2528
|
+
this.cliProcessor = createDefaultCLI();
|
|
2529
|
+
if (this.config.autoDetectTheme) {
|
|
2530
|
+
this.setupAutoThemeDetection();
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
// ===== PRIVATE HELPER METHODS =====
|
|
2534
|
+
/**
|
|
2535
|
+
* Configura la detección automática de tema con listener de cambios
|
|
2536
|
+
* @private
|
|
2537
|
+
* @description Detecta automáticamente si el navegador está en modo claro u oscuro
|
|
2538
|
+
*/
|
|
2539
|
+
setupAutoThemeDetection() {
|
|
2540
|
+
if (this.themeChangeListener) {
|
|
2541
|
+
this.themeChangeListener();
|
|
2542
|
+
this.themeChangeListener = null;
|
|
2543
|
+
}
|
|
2544
|
+
this.themeChangeListener = setupThemeChangeListener((theme) => {
|
|
2545
|
+
this.debug(`DevTools theme changed to: ${theme}`);
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2548
|
+
// ===== CONFIGURATION METHODS =====
|
|
2549
|
+
/**
|
|
2550
|
+
* Obtiene la configuración actual del logger
|
|
2551
|
+
*
|
|
2552
|
+
* @returns {LoggerConfig} Configuración completa actual
|
|
2553
|
+
*
|
|
2554
|
+
* @example
|
|
2555
|
+
* const config = logger.getConfig();
|
|
2556
|
+
* console.log('Verbosidad actual:', config.verbosity);
|
|
2557
|
+
* console.log('Tema actual:', config.theme);
|
|
2558
|
+
*
|
|
2559
|
+
* @since 0.3.0
|
|
2560
|
+
*/
|
|
2561
|
+
getConfig() {
|
|
2562
|
+
return { ...this.config };
|
|
2563
|
+
}
|
|
2564
|
+
/**
|
|
2565
|
+
* Actualiza la configuración del logger
|
|
2566
|
+
*
|
|
2567
|
+
* @param {Partial<LoggerConfig>} updates - Propiedades a actualizar
|
|
2568
|
+
*
|
|
2569
|
+
* @example
|
|
2570
|
+
* logger.updateConfig({
|
|
2571
|
+
* verbosity: 'debug',
|
|
2572
|
+
* enableTimestamps: false,
|
|
2573
|
+
* theme: 'cyberpunk'
|
|
2574
|
+
* });
|
|
2575
|
+
*
|
|
2576
|
+
* @since 0.3.0
|
|
2577
|
+
*/
|
|
2578
|
+
updateConfig(updates) {
|
|
2579
|
+
const previousAutoDetect = this.config.autoDetectTheme;
|
|
2580
|
+
this.config = { ...this.config, ...updates };
|
|
2581
|
+
if (updates.autoDetectTheme !== void 0 && updates.autoDetectTheme !== previousAutoDetect) {
|
|
2582
|
+
if (updates.autoDetectTheme) {
|
|
2583
|
+
this.setupAutoThemeDetection();
|
|
2584
|
+
} else if (this.themeChangeListener) {
|
|
2585
|
+
this.themeChangeListener();
|
|
2586
|
+
this.themeChangeListener = null;
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
/**
|
|
2591
|
+
* Establece el prefijo global para todos los mensajes de log
|
|
2592
|
+
*
|
|
2593
|
+
* @param {string} prefix - Prefijo a usar
|
|
2594
|
+
*
|
|
2595
|
+
* @example
|
|
2596
|
+
* logger.setGlobalPrefix('MiApp');
|
|
2597
|
+
* logger.info('Iniciado'); // [MiApp] Iniciado
|
|
2598
|
+
*
|
|
2599
|
+
* @since 0.3.0
|
|
2600
|
+
*/
|
|
2601
|
+
setGlobalPrefix(prefix) {
|
|
2602
|
+
this.config.globalPrefix = prefix;
|
|
2603
|
+
}
|
|
2604
|
+
/**
|
|
2605
|
+
* Establece el nivel de verbosidad para filtrar la salida de logs
|
|
2606
|
+
*
|
|
2607
|
+
* @param {Verbosity} level - Nivel mínimo a mostrar ('debug' | 'info' | 'warn' | 'error' | 'critical' | 'silent')
|
|
2608
|
+
*
|
|
2609
|
+
* @example
|
|
2610
|
+
* logger.setVerbosity('warn'); // Solo muestra warn, error y critical
|
|
2611
|
+
* logger.setVerbosity('debug'); // Muestra todos los niveles
|
|
2612
|
+
* logger.setVerbosity('silent'); // No muestra nada
|
|
2613
|
+
*
|
|
2614
|
+
* @since 0.3.0
|
|
2615
|
+
*/
|
|
2616
|
+
setVerbosity(level) {
|
|
2617
|
+
this.config.verbosity = level;
|
|
2618
|
+
}
|
|
2619
|
+
/**
|
|
2620
|
+
* Establece el tema del logger
|
|
2621
|
+
*
|
|
2622
|
+
* @param {ThemeVariant} theme - Tema a aplicar ('default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk')
|
|
2623
|
+
*
|
|
2624
|
+
* @example
|
|
2625
|
+
* logger.setTheme('neon'); // Tema con colores neón
|
|
2626
|
+
* logger.setTheme('minimal'); // Tema minimalista
|
|
2627
|
+
* logger.setTheme('cyberpunk'); // Tema cyberpunk con efectos
|
|
2628
|
+
*
|
|
2629
|
+
* @since 0.3.0
|
|
2630
|
+
*/
|
|
2631
|
+
setTheme(theme) {
|
|
2632
|
+
if (hasPreset(theme)) {
|
|
2633
|
+
this.preset(theme);
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
if (theme in THEME_PRESETS) {
|
|
2637
|
+
LEVEL_STYLES = THEME_PRESETS[theme];
|
|
2638
|
+
this.config.theme = theme;
|
|
2639
|
+
if (theme in THEME_BANNERS) {
|
|
2640
|
+
const themeBanner = THEME_BANNERS[theme];
|
|
2641
|
+
console.log(`%c${themeBanner.simple}`, themeBanner.style);
|
|
2642
|
+
}
|
|
2643
|
+
this.success(`Theme changed to: ${theme}`);
|
|
2644
|
+
} else {
|
|
2645
|
+
this.error(`Invalid theme: ${theme}. Available:`, [...getAvailablePresets(), ...Object.keys(THEME_PRESETS)]);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
/**
|
|
2649
|
+
* Establece el tipo de banner para mostrar en la inicialización
|
|
2650
|
+
*
|
|
2651
|
+
* @param {BannerType} bannerType - Tipo de banner ('simple' | 'ascii' | 'unicode' | 'svg' | 'animated')
|
|
2652
|
+
*
|
|
2653
|
+
* @example
|
|
2654
|
+
* logger.setBannerType('ascii'); // Banner con arte ASCII
|
|
2655
|
+
* logger.setBannerType('unicode'); // Banner con caracteres Unicode
|
|
2656
|
+
* logger.setBannerType('animated'); // Banner con animación
|
|
2657
|
+
*
|
|
2658
|
+
* @since 0.3.0
|
|
2659
|
+
*/
|
|
2660
|
+
setBannerType(bannerType) {
|
|
2661
|
+
this.config.bannerType = bannerType;
|
|
2662
|
+
this.success(`Banner type changed to: ${bannerType}`);
|
|
2663
|
+
}
|
|
2664
|
+
/**
|
|
2665
|
+
* Reinicia el logger a la configuración por defecto
|
|
2666
|
+
*
|
|
2667
|
+
* @example
|
|
2668
|
+
* logger.resetConfig();
|
|
2669
|
+
* // Todo vuelve a la configuración inicial
|
|
2670
|
+
*
|
|
2671
|
+
* @since 0.3.0
|
|
2672
|
+
*/
|
|
2673
|
+
resetConfig() {
|
|
2674
|
+
if (this.themeChangeListener) {
|
|
2675
|
+
this.themeChangeListener();
|
|
2676
|
+
this.themeChangeListener = null;
|
|
2677
|
+
}
|
|
2678
|
+
this.config = { ...DEFAULT_CONFIG };
|
|
2679
|
+
LEVEL_STYLES = THEME_PRESETS.default;
|
|
2680
|
+
if (this.config.autoDetectTheme) {
|
|
2681
|
+
this.setupAutoThemeDetection();
|
|
2682
|
+
}
|
|
2683
|
+
this.success("Logger configuration reset to defaults");
|
|
2684
|
+
}
|
|
2685
|
+
/**
|
|
2686
|
+
* Método de limpieza para eliminar listeners y liberar recursos
|
|
2687
|
+
*
|
|
2688
|
+
* @example
|
|
2689
|
+
* // Antes de cerrar la aplicación
|
|
2690
|
+
* logger.cleanup();
|
|
2691
|
+
*
|
|
2692
|
+
* @since 0.3.0
|
|
2693
|
+
*/
|
|
2694
|
+
cleanup() {
|
|
2695
|
+
if (this.themeChangeListener) {
|
|
2696
|
+
this.themeChangeListener();
|
|
2697
|
+
this.themeChangeListener = null;
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Factory method para crear loggers con scope evitando dependencias circulares
|
|
2702
|
+
* @private
|
|
2703
|
+
* @param {string} type - Tipo de logger ('scope' | 'api' | 'component')
|
|
2704
|
+
* @param {string} name - Nombre del scope
|
|
2705
|
+
* @returns {Promise<any>} Logger con scope
|
|
2706
|
+
*/
|
|
2707
|
+
async createScopedLogger(type, name) {
|
|
2708
|
+
try {
|
|
2709
|
+
const { ScopedLogger, APILogger, ComponentLogger } = await import("./ScopedLogger-D-RbiFZn.js");
|
|
2710
|
+
switch (type) {
|
|
2711
|
+
case "component":
|
|
2712
|
+
return new ComponentLogger(this, name);
|
|
2713
|
+
case "api":
|
|
2714
|
+
return new APILogger(this, name);
|
|
2715
|
+
case "scope":
|
|
2716
|
+
default:
|
|
2717
|
+
return new ScopedLogger(this, name);
|
|
2718
|
+
}
|
|
2719
|
+
} catch (error2) {
|
|
2720
|
+
this.error("Failed to load ScopedLogger, using basic logger with prefix:", error2);
|
|
2721
|
+
const basicLogger = new Logger(this.getConfig());
|
|
2722
|
+
basicLogger.setGlobalPrefix(`${this.config.globalPrefix || ""}:${name}`);
|
|
2723
|
+
return basicLogger;
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
// ===== SIMPLIFIED API =====
|
|
2727
|
+
/**
|
|
2728
|
+
* Aplica un preset inteligente - funciona perfectamente sin configuración
|
|
2729
|
+
*
|
|
2730
|
+
* @param {string} name - Nombre del preset a aplicar
|
|
2731
|
+
*
|
|
2732
|
+
* @example
|
|
2733
|
+
* // Presets disponibles
|
|
2734
|
+
* logger.preset('default'); // Limpio y adaptativo
|
|
2735
|
+
* logger.preset('cyberpunk'); // Colores neón, efectos brillantes
|
|
2736
|
+
* logger.preset('glassmorphism'); // Efectos de blur modernos
|
|
2737
|
+
* logger.preset('minimal'); // Minimalista y elegante
|
|
2738
|
+
* logger.preset('debug'); // Modo desarrollo detallado
|
|
2739
|
+
* logger.preset('production'); // Optimizado para producción
|
|
2740
|
+
*
|
|
2741
|
+
* @since 0.3.0
|
|
2742
|
+
*/
|
|
2743
|
+
preset(name) {
|
|
2744
|
+
if (!hasPreset(name)) {
|
|
2745
|
+
this.error(`Unknown preset: ${name}. Available presets:`, getAvailablePresets());
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
const presetConfig = getSmartPreset(name);
|
|
2749
|
+
if (presetConfig) {
|
|
2750
|
+
this.displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;
|
|
2751
|
+
this.displaySettings.showLocation = presetConfig.location?.show ?? true;
|
|
2752
|
+
this._activePreset = presetConfig;
|
|
2753
|
+
this._activePresetName = name;
|
|
2754
|
+
if (getEnvironment() === "browser") {
|
|
2755
|
+
this.success(`Applied preset: ${name}`);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Lista todos los presets disponibles
|
|
2761
|
+
*
|
|
2762
|
+
* @returns {string[]} Array con nombres de presets disponibles
|
|
2763
|
+
*
|
|
2764
|
+
* @example
|
|
2765
|
+
* const disponibles = logger.presets();
|
|
2766
|
+
* console.log(disponibles); // ['default', 'cyberpunk', 'glassmorphism', ...]
|
|
2767
|
+
*
|
|
2768
|
+
* @since 0.3.0
|
|
2769
|
+
*/
|
|
2770
|
+
presets() {
|
|
2771
|
+
return getAvailablePresets();
|
|
2772
|
+
}
|
|
2773
|
+
// ===== TOGGLE METHODS =====
|
|
2774
|
+
/**
|
|
2775
|
+
* Oculta el timestamp en los logs
|
|
2776
|
+
*
|
|
2777
|
+
* @example
|
|
2778
|
+
* logger.hideTimestamp();
|
|
2779
|
+
* logger.info('Sin marca de tiempo'); // Sin timestamp visible
|
|
2780
|
+
*
|
|
2781
|
+
* @since 0.3.0
|
|
2782
|
+
*/
|
|
2783
|
+
hideTimestamp() {
|
|
2784
|
+
this.displaySettings.showTimestamp = false;
|
|
2785
|
+
this.success("Timestamp hidden");
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Muestra el timestamp en los logs
|
|
2789
|
+
*
|
|
2790
|
+
* @example
|
|
2791
|
+
* logger.showTimestamp();
|
|
2792
|
+
* logger.info('Con marca de tiempo'); // [2024-01-15 10:30:45] Con marca de tiempo
|
|
2793
|
+
*
|
|
2794
|
+
* @since 0.3.0
|
|
2795
|
+
*/
|
|
2796
|
+
showTimestamp() {
|
|
2797
|
+
this.displaySettings.showTimestamp = true;
|
|
2798
|
+
this.success("Timestamp shown");
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Oculta la información de ubicación (archivo:línea) en los logs
|
|
2802
|
+
*
|
|
2803
|
+
* @example
|
|
2804
|
+
* logger.hideLocation();
|
|
2805
|
+
* logger.debug('Sin ubicación'); // Sin mostrar archivo:línea
|
|
2806
|
+
*
|
|
2807
|
+
* @since 0.3.0
|
|
2808
|
+
*/
|
|
2809
|
+
hideLocation() {
|
|
2810
|
+
this.displaySettings.showLocation = false;
|
|
2811
|
+
this.success("Location info hidden");
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* Muestra la información de ubicación (archivo:línea) en los logs
|
|
2815
|
+
*
|
|
2816
|
+
* @example
|
|
2817
|
+
* logger.showLocation();
|
|
2818
|
+
* logger.debug('Con ubicación'); // app.js:42 Con ubicación
|
|
2819
|
+
*
|
|
2820
|
+
* @since 0.3.0
|
|
2821
|
+
*/
|
|
2822
|
+
showLocation() {
|
|
2823
|
+
this.displaySettings.showLocation = true;
|
|
2824
|
+
this.success("Location info shown");
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Oculta los badges en los logs
|
|
2828
|
+
*
|
|
2829
|
+
* @example
|
|
2830
|
+
* logger.hideBadges();
|
|
2831
|
+
* const api = logger.api('REST');
|
|
2832
|
+
* api.info('Sin badges'); // Sin mostrar [API] [REST]
|
|
2833
|
+
*
|
|
2834
|
+
* @since 0.3.0
|
|
2835
|
+
*/
|
|
2836
|
+
hideBadges() {
|
|
2837
|
+
this.displaySettings.showBadges = false;
|
|
2838
|
+
this.success("Badges hidden");
|
|
2839
|
+
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Muestra los badges en los logs
|
|
2842
|
+
*
|
|
2843
|
+
* @example
|
|
2844
|
+
* logger.showBadges();
|
|
2845
|
+
* const api = logger.api('GraphQL');
|
|
2846
|
+
* api.info('Con badges'); // [API] [GraphQL] Con badges
|
|
2847
|
+
*
|
|
2848
|
+
* @since 0.3.0
|
|
2849
|
+
*/
|
|
2850
|
+
showBadges() {
|
|
2851
|
+
this.displaySettings.showBadges = true;
|
|
2852
|
+
this.success("Badges shown");
|
|
2853
|
+
}
|
|
2854
|
+
// ===== SCOPED LOGGERS =====
|
|
2855
|
+
/**
|
|
2856
|
+
* Crea un logger para componentes con estilo automático
|
|
2857
|
+
*
|
|
2858
|
+
* @param {string} name - Nombre del componente
|
|
2859
|
+
* @returns {ComponentLogger} Logger con scope de componente
|
|
2860
|
+
*
|
|
2861
|
+
* @example
|
|
2862
|
+
* const authLogger = logger.component('Autenticación');
|
|
2863
|
+
* authLogger.info('Validando credenciales');
|
|
2864
|
+
* // [COMPONENT] [Autenticación] Validando credenciales
|
|
2865
|
+
*
|
|
2866
|
+
* authLogger.success('Usuario autenticado');
|
|
2867
|
+
* // [COMPONENT] [Autenticación] ✓ Usuario autenticado
|
|
2868
|
+
*
|
|
2869
|
+
* @since 0.3.0
|
|
2870
|
+
*/
|
|
2871
|
+
component(name) {
|
|
2872
|
+
return this.createScopedLogger("component", name);
|
|
2873
|
+
}
|
|
2874
|
+
/**
|
|
2875
|
+
* Crea un logger para APIs con badges automáticos
|
|
2876
|
+
*
|
|
2877
|
+
* @param {string} name - Nombre de la API o endpoint
|
|
2878
|
+
* @returns {APILogger} Logger con scope de API
|
|
2879
|
+
*
|
|
2880
|
+
* @example
|
|
2881
|
+
* const api = logger.api('REST');
|
|
2882
|
+
* api.info('GET /users');
|
|
2883
|
+
* // [API] [REST] GET /users
|
|
2884
|
+
*
|
|
2885
|
+
* // Con badges adicionales
|
|
2886
|
+
* api.badges(['v2', 'cached']).info('Respuesta desde caché');
|
|
2887
|
+
* // [API] [v2] [cached] [REST] Respuesta desde caché
|
|
2888
|
+
*
|
|
2889
|
+
* @since 0.3.0
|
|
2890
|
+
*/
|
|
2891
|
+
api(name) {
|
|
2892
|
+
return this.createScopedLogger("api", name);
|
|
2893
|
+
}
|
|
2894
|
+
/**
|
|
2895
|
+
* Crea un logger con scope general y soporte de badges
|
|
2896
|
+
*
|
|
2897
|
+
* @param {string} name - Nombre del scope
|
|
2898
|
+
* @returns {ScopedLogger} Logger con scope personalizado
|
|
2899
|
+
*
|
|
2900
|
+
* @example
|
|
2901
|
+
* const dbLogger = logger.scope('Database');
|
|
2902
|
+
* dbLogger.info('Conectando a MongoDB');
|
|
2903
|
+
* // [Database] Conectando a MongoDB
|
|
2904
|
+
*
|
|
2905
|
+
* // Con badges personalizados
|
|
2906
|
+
* dbLogger.badge('SLOW').warn('Query tardó 5s');
|
|
2907
|
+
* // [SLOW] [Database] Query tardó 5s
|
|
2908
|
+
*
|
|
2909
|
+
* @since 0.3.0
|
|
2910
|
+
*/
|
|
2911
|
+
scope(name) {
|
|
2912
|
+
return this.createScopedLogger("scope", name);
|
|
2913
|
+
}
|
|
2914
|
+
// ===== SIMPLE CUSTOMIZATION =====
|
|
2915
|
+
/**
|
|
2916
|
+
* Personalización simple con configuración mínima
|
|
2917
|
+
*
|
|
2918
|
+
* @param {Object} overrides - Opciones de personalización
|
|
2919
|
+
* @param {Object} overrides.message - Configuración del mensaje
|
|
2920
|
+
* @param {Object} overrides.timestamp - Configuración del timestamp
|
|
2921
|
+
* @param {Object} overrides.location - Configuración de ubicación
|
|
2922
|
+
* @param {Object} overrides.level - Configuración del nivel
|
|
2923
|
+
* @param {Object} overrides.prefix - Configuración del prefijo
|
|
2924
|
+
* @param {string} overrides.spacing - Espaciado: 'compact' | 'normal' | 'spacious'
|
|
2925
|
+
*
|
|
2926
|
+
* @example
|
|
2927
|
+
* logger.customize({
|
|
2928
|
+
* message: { color: '#00ff00', size: '16px' },
|
|
2929
|
+
* timestamp: { show: false },
|
|
2930
|
+
* spacing: 'compact'
|
|
2931
|
+
* });
|
|
2932
|
+
*
|
|
2933
|
+
* @since 0.3.0
|
|
2934
|
+
*/
|
|
2935
|
+
customize(overrides) {
|
|
2936
|
+
if (overrides.timestamp?.show !== void 0) {
|
|
2937
|
+
this.displaySettings.showTimestamp = overrides.timestamp.show;
|
|
2938
|
+
}
|
|
2939
|
+
if (overrides.location?.show !== void 0) {
|
|
2940
|
+
this.displaySettings.showLocation = overrides.location.show;
|
|
2941
|
+
}
|
|
2942
|
+
if (overrides.prefix?.show !== void 0) ;
|
|
2943
|
+
this._customization = overrides;
|
|
2944
|
+
this.success("Customization applied");
|
|
2945
|
+
}
|
|
2946
|
+
/**
|
|
2947
|
+
* Access advanced styling API (for power users)
|
|
2948
|
+
*/
|
|
2949
|
+
styles() {
|
|
2950
|
+
return createLogStyleBuilder(this);
|
|
2951
|
+
}
|
|
2952
|
+
// ===== HANDLER MANAGEMENT =====
|
|
2953
|
+
/**
|
|
2954
|
+
* Añade un handler personalizado para extender funcionalidad
|
|
2955
|
+
*
|
|
2956
|
+
* @param {ILogHandler} handler - Handler que implementa ILogHandler
|
|
2957
|
+
*
|
|
2958
|
+
* @example
|
|
2959
|
+
* // Handler personalizado para enviar logs a servidor
|
|
2960
|
+
* const remoteHandler = new RemoteLogHandler('https://api.ejemplo.com/logs');
|
|
2961
|
+
* logger.addHandler(remoteHandler);
|
|
2962
|
+
*
|
|
2963
|
+
* @example
|
|
2964
|
+
* // Handler para guardar en archivo
|
|
2965
|
+
* const fileHandler = new FileLogHandler('./app.log');
|
|
2966
|
+
* logger.addHandler(fileHandler);
|
|
2967
|
+
*
|
|
2968
|
+
* @since 0.3.0
|
|
2969
|
+
*/
|
|
2970
|
+
addHandler(handler) {
|
|
2971
|
+
this.handlers.push(handler);
|
|
2972
|
+
}
|
|
2973
|
+
/**
|
|
2974
|
+
* Obtiene todos los handlers registrados
|
|
2975
|
+
*
|
|
2976
|
+
* @returns {ILogHandler[]} Array de handlers activos
|
|
2977
|
+
* @since 0.3.0
|
|
2978
|
+
*/
|
|
2979
|
+
getHandlers() {
|
|
2980
|
+
return [...this.handlers];
|
|
2981
|
+
}
|
|
2982
|
+
/**
|
|
2983
|
+
* Obtiene el handler de exportación si está disponible
|
|
2984
|
+
*
|
|
2985
|
+
* @returns {ExportLogHandler | undefined} Handler de exportación o undefined
|
|
2986
|
+
* @since 0.3.0
|
|
2987
|
+
*/
|
|
2988
|
+
getExportHandler() {
|
|
2989
|
+
return this.exportHandler;
|
|
2990
|
+
}
|
|
2991
|
+
// ===== CORE LOGGING METHODS =====
|
|
2992
|
+
/**
|
|
2993
|
+
* Verifica si un nivel de log debe mostrarse según la verbosidad actual
|
|
2994
|
+
* @private
|
|
2995
|
+
* @param {LogLevel} level - Nivel de log a verificar
|
|
2996
|
+
* @returns {boolean} True si debe mostrarse, false si no
|
|
2997
|
+
*/
|
|
2998
|
+
shouldLog(level) {
|
|
2999
|
+
if (this.config.verbosity === "silent") return false;
|
|
3000
|
+
const levels = { debug: 0, info: 1, warn: 2, error: 3, critical: 4 };
|
|
3001
|
+
return levels[level] >= levels[this.config.verbosity];
|
|
3002
|
+
}
|
|
3003
|
+
/**
|
|
3004
|
+
* Obtiene el prefijo efectivo (global + scope)
|
|
3005
|
+
* @private
|
|
3006
|
+
* @returns {string | undefined} Prefijo combinado o undefined
|
|
3007
|
+
*/
|
|
3008
|
+
getEffectivePrefix() {
|
|
3009
|
+
const parts = [this.config.globalPrefix, this.scopedPrefix].filter(Boolean);
|
|
3010
|
+
return parts.length > 0 ? parts.join(":") : void 0;
|
|
3011
|
+
}
|
|
3012
|
+
/**
|
|
3013
|
+
* Método central de logging que maneja estilos y formato
|
|
3014
|
+
* @protected
|
|
3015
|
+
* @param {LogLevel} level - Nivel del log
|
|
3016
|
+
* @param {...any} args - Argumentos a loggear
|
|
3017
|
+
*/
|
|
3018
|
+
log(level, ...args) {
|
|
3019
|
+
if (!this.shouldLog(level)) return;
|
|
3020
|
+
const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
|
|
3021
|
+
const prefix = this.getEffectivePrefix();
|
|
3022
|
+
const message = args.length > 0 ? String(args[0]) : "";
|
|
3023
|
+
const additionalArgs = args.slice(1);
|
|
3024
|
+
const [format, ...styles2] = createStyledOutput(
|
|
3025
|
+
level,
|
|
3026
|
+
LEVEL_STYLES,
|
|
3027
|
+
prefix,
|
|
3028
|
+
message,
|
|
3029
|
+
this.displaySettings.showLocation ? stackInfo : null,
|
|
3030
|
+
this.config.autoDetectTheme,
|
|
3031
|
+
this._activePreset,
|
|
3032
|
+
this._activePresetName
|
|
3033
|
+
);
|
|
3034
|
+
const groupIndent = " ".repeat(this.groupDepth);
|
|
3035
|
+
const finalFormat = groupIndent + format;
|
|
3036
|
+
if (additionalArgs.length > 0) {
|
|
3037
|
+
console.log(finalFormat, ...styles2, ...additionalArgs);
|
|
3038
|
+
} else {
|
|
3039
|
+
console.log(finalFormat, ...styles2);
|
|
3040
|
+
}
|
|
3041
|
+
if (this.exportHandler) {
|
|
3042
|
+
this.exportHandler.setGroupInfo(this.groupDepth);
|
|
3043
|
+
}
|
|
3044
|
+
const metadata = {
|
|
3045
|
+
timestamp: formatTimestamp(),
|
|
3046
|
+
level,
|
|
3047
|
+
prefix,
|
|
3048
|
+
stackInfo: stackInfo ? stackInfo : void 0
|
|
3049
|
+
};
|
|
3050
|
+
this.handlers.forEach((handler) => {
|
|
3051
|
+
try {
|
|
3052
|
+
handler.handle(level, message, args, metadata);
|
|
3053
|
+
} catch (error2) {
|
|
3054
|
+
console.error("Log handler failed:", error2);
|
|
3055
|
+
}
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
/**
|
|
3059
|
+
* Registra información de debug (prioridad más baja)
|
|
3060
|
+
*
|
|
3061
|
+
* @param {...any} args - Mensajes y datos a loggear
|
|
3062
|
+
*
|
|
3063
|
+
* @example
|
|
3064
|
+
* logger.debug('Variable estado:', { usuario: 'Juan', activo: true });
|
|
3065
|
+
* logger.debug('Iniciando proceso de validación');
|
|
3066
|
+
*
|
|
3067
|
+
* @since 0.3.0
|
|
3068
|
+
*/
|
|
3069
|
+
debug(...args) {
|
|
3070
|
+
this.log("debug", ...args);
|
|
3071
|
+
}
|
|
3072
|
+
/**
|
|
3073
|
+
* Registra mensajes informativos
|
|
3074
|
+
*
|
|
3075
|
+
* @param {...any} args - Mensajes y datos informativos
|
|
3076
|
+
*
|
|
3077
|
+
* @example
|
|
3078
|
+
* logger.info('Servidor iniciado en puerto 3000');
|
|
3079
|
+
* logger.info('Usuario conectado:', userId);
|
|
3080
|
+
* logger.info('Procesando', totalItems, 'elementos');
|
|
3081
|
+
*
|
|
3082
|
+
* @since 0.3.0
|
|
3083
|
+
*/
|
|
3084
|
+
info(...args) {
|
|
3085
|
+
this.log("info", ...args);
|
|
3086
|
+
}
|
|
3087
|
+
/**
|
|
3088
|
+
* Registra mensajes de advertencia
|
|
3089
|
+
*
|
|
3090
|
+
* @param {...any} args - Mensajes de advertencia
|
|
3091
|
+
*
|
|
3092
|
+
* @example
|
|
3093
|
+
* logger.warn('Memoria al 85% de capacidad');
|
|
3094
|
+
* logger.warn('API deprecada, usar v2');
|
|
3095
|
+
* logger.warn('Reintentos agotados:', maxRetries);
|
|
3096
|
+
*
|
|
3097
|
+
* @since 0.3.0
|
|
3098
|
+
*/
|
|
3099
|
+
warn(...args) {
|
|
3100
|
+
this.log("warn", ...args);
|
|
3101
|
+
}
|
|
3102
|
+
/**
|
|
3103
|
+
* Registra mensajes de error
|
|
3104
|
+
*
|
|
3105
|
+
* @param {...any} args - Mensajes de error y stack traces
|
|
3106
|
+
*
|
|
3107
|
+
* @example
|
|
3108
|
+
* logger.error('Fallo en conexión a base de datos');
|
|
3109
|
+
* logger.error('Error al procesar:', error.message, error.stack);
|
|
3110
|
+
* logger.error('Código de error:', errorCode);
|
|
3111
|
+
*
|
|
3112
|
+
* @since 0.3.0
|
|
3113
|
+
*/
|
|
3114
|
+
error(...args) {
|
|
3115
|
+
this.log("error", ...args);
|
|
3116
|
+
}
|
|
3117
|
+
/**
|
|
3118
|
+
* Registra mensajes de éxito (nivel info especial)
|
|
3119
|
+
*
|
|
3120
|
+
* @param {...any} args - Mensajes de operaciones exitosas
|
|
3121
|
+
*
|
|
3122
|
+
* @example
|
|
3123
|
+
* logger.success('Base de datos conectada');
|
|
3124
|
+
* logger.success('Usuario creado con ID:', userId);
|
|
3125
|
+
* logger.success('✓ Tests pasados: 42/42');
|
|
3126
|
+
*
|
|
3127
|
+
* @since 0.3.0
|
|
3128
|
+
*/
|
|
3129
|
+
success(...args) {
|
|
3130
|
+
if (!this.shouldLog("info")) return;
|
|
3131
|
+
const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
|
|
3132
|
+
const prefix = this.getEffectivePrefix();
|
|
3133
|
+
const message = args.length > 0 ? String(args[0]) : "";
|
|
3134
|
+
const additionalArgs = args.slice(1);
|
|
3135
|
+
const [format, ...styles2] = createStyledOutput(
|
|
3136
|
+
"info",
|
|
3137
|
+
LEVEL_STYLES,
|
|
3138
|
+
prefix,
|
|
3139
|
+
message,
|
|
3140
|
+
this.displaySettings.showLocation ? stackInfo : null,
|
|
3141
|
+
this.config.autoDetectTheme,
|
|
3142
|
+
this._activePreset,
|
|
3143
|
+
this._activePresetName
|
|
3144
|
+
);
|
|
3145
|
+
const successStyle = LEVEL_STYLES.success;
|
|
3146
|
+
let emoji = "✅";
|
|
3147
|
+
let label = "SUCCESS";
|
|
3148
|
+
if (successStyle) {
|
|
3149
|
+
if (successStyle.emoji) {
|
|
3150
|
+
emoji = successStyle.emoji;
|
|
3151
|
+
}
|
|
3152
|
+
if (successStyle.label) {
|
|
3153
|
+
label = successStyle.label;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
const successFormat = format.replace(/ℹ️ INFO/, `${emoji} ${label}`);
|
|
3157
|
+
const groupIndent = " ".repeat(this.groupDepth);
|
|
3158
|
+
const finalFormat = groupIndent + successFormat;
|
|
3159
|
+
if (additionalArgs.length > 0) {
|
|
3160
|
+
console.log(finalFormat, ...styles2, ...additionalArgs);
|
|
3161
|
+
} else {
|
|
3162
|
+
console.log(finalFormat, ...styles2);
|
|
3163
|
+
}
|
|
3164
|
+
const metadata = {
|
|
3165
|
+
timestamp: formatTimestamp(),
|
|
3166
|
+
level: "info",
|
|
3167
|
+
prefix,
|
|
3168
|
+
stackInfo: stackInfo ? stackInfo : void 0
|
|
3169
|
+
};
|
|
3170
|
+
this.handlers.forEach((handler) => {
|
|
3171
|
+
try {
|
|
3172
|
+
handler.handle("info", message, args, metadata);
|
|
3173
|
+
} catch (error2) {
|
|
3174
|
+
console.error("Log handler failed:", error2);
|
|
3175
|
+
}
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3178
|
+
/**
|
|
3179
|
+
* Registra información de trace (debugging detallado)
|
|
3180
|
+
*
|
|
3181
|
+
* @param {...any} args - Datos detallados para debugging
|
|
3182
|
+
*
|
|
3183
|
+
* @example
|
|
3184
|
+
* logger.trace('Entrando en función processData');
|
|
3185
|
+
* logger.trace('Stack completo:', new Error().stack);
|
|
3186
|
+
*
|
|
3187
|
+
* @since 0.3.0
|
|
3188
|
+
*/
|
|
3189
|
+
trace(...args) {
|
|
3190
|
+
this.log("debug", ...args);
|
|
3191
|
+
if (this.shouldLog("debug")) {
|
|
3192
|
+
console.trace(...args);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
/**
|
|
3196
|
+
* Registra errores críticos (prioridad más alta)
|
|
3197
|
+
*
|
|
3198
|
+
* @param {...any} args - Errores críticos del sistema
|
|
3199
|
+
*
|
|
3200
|
+
* @example
|
|
3201
|
+
* logger.critical('Sistema caído - reinicio inmediato requerido');
|
|
3202
|
+
* logger.critical('Pérdida de datos detectada');
|
|
3203
|
+
* logger.critical('Brecha de seguridad:', securityError);
|
|
3204
|
+
*
|
|
3205
|
+
* @since 0.3.0
|
|
3206
|
+
*/
|
|
3207
|
+
critical(...args) {
|
|
3208
|
+
this.log("critical", ...args);
|
|
3209
|
+
}
|
|
3210
|
+
// ===== ADVANCED LOGGING FEATURES =====
|
|
3211
|
+
/**
|
|
3212
|
+
* Muestra datos en formato de tabla
|
|
3213
|
+
*
|
|
3214
|
+
* @param {any} data - Datos a mostrar (array de objetos o matriz)
|
|
3215
|
+
* @param {string[]} columns - Columnas específicas a mostrar (opcional)
|
|
3216
|
+
*
|
|
3217
|
+
* @example
|
|
3218
|
+
* const usuarios = [
|
|
3219
|
+
* { id: 1, nombre: 'Juan', edad: 30 },
|
|
3220
|
+
* { id: 2, nombre: 'María', edad: 25 }
|
|
3221
|
+
* ];
|
|
3222
|
+
* logger.table(usuarios);
|
|
3223
|
+
* logger.table(usuarios, ['nombre', 'edad']); // Solo estas columnas
|
|
3224
|
+
*
|
|
3225
|
+
* @since 0.3.0
|
|
3226
|
+
*/
|
|
3227
|
+
table(data, columns) {
|
|
3228
|
+
if (!this.shouldLog("info")) return;
|
|
3229
|
+
const prefix = this.getEffectivePrefix();
|
|
3230
|
+
const tableStyle = StylePresets.accent().build();
|
|
3231
|
+
const format = `%c📊 TABLE${prefix ? ` [${prefix}]` : ""}`;
|
|
3232
|
+
console.log(format, tableStyle);
|
|
3233
|
+
if (columns) {
|
|
3234
|
+
console.table(data, columns);
|
|
3235
|
+
} else {
|
|
3236
|
+
console.table(data);
|
|
3237
|
+
}
|
|
3238
|
+
}
|
|
3239
|
+
/**
|
|
3240
|
+
* Inicia un grupo colapsable en la consola
|
|
3241
|
+
*
|
|
3242
|
+
* @param {string} label - Etiqueta del grupo
|
|
3243
|
+
* @param {boolean} collapsed - Si el grupo inicia colapsado (default: false)
|
|
3244
|
+
*
|
|
3245
|
+
* @example
|
|
3246
|
+
* logger.group('Procesando usuarios');
|
|
3247
|
+
* logger.info('Usuario 1 procesado');
|
|
3248
|
+
* logger.info('Usuario 2 procesado');
|
|
3249
|
+
* logger.groupEnd();
|
|
3250
|
+
*
|
|
3251
|
+
* @example
|
|
3252
|
+
* // Grupo colapsado por defecto
|
|
3253
|
+
* logger.group('Detalles adicionales', true);
|
|
3254
|
+
* logger.debug('Información detallada aquí');
|
|
3255
|
+
* logger.groupEnd();
|
|
3256
|
+
*
|
|
3257
|
+
* @since 0.3.0
|
|
3258
|
+
*/
|
|
3259
|
+
group(label, collapsed = false) {
|
|
3260
|
+
const groupStyle = new StyleBuilder().bg("linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)").color("#1565c0").border("1px solid #90caf9").padding("4px 12px").rounded("6px").bold().build();
|
|
3261
|
+
const format = `%c📁 ${label}`;
|
|
3262
|
+
if (collapsed) {
|
|
3263
|
+
console.groupCollapsed(format, groupStyle);
|
|
3264
|
+
} else {
|
|
3265
|
+
console.group(format, groupStyle);
|
|
3266
|
+
}
|
|
3267
|
+
this.groupDepth++;
|
|
3268
|
+
}
|
|
3269
|
+
/**
|
|
3270
|
+
* Finaliza el grupo actual de la consola
|
|
3271
|
+
*
|
|
3272
|
+
* @example
|
|
3273
|
+
* logger.group('Operaciones');
|
|
3274
|
+
* logger.info('Operación 1');
|
|
3275
|
+
* logger.info('Operación 2');
|
|
3276
|
+
* logger.groupEnd(); // Cierra el grupo
|
|
3277
|
+
*
|
|
3278
|
+
* @since 0.3.0
|
|
3279
|
+
*/
|
|
3280
|
+
groupEnd() {
|
|
3281
|
+
if (this.groupDepth > 0) {
|
|
3282
|
+
console.groupEnd();
|
|
3283
|
+
this.groupDepth--;
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
// ===== PERFORMANCE TIMING =====
|
|
3287
|
+
/**
|
|
3288
|
+
* Inicia un temporizador con la etiqueta dada
|
|
3289
|
+
*
|
|
3290
|
+
* @param {string} label - Etiqueta identificadora del temporizador
|
|
3291
|
+
*
|
|
3292
|
+
* @example
|
|
3293
|
+
* logger.time('proceso-datos');
|
|
3294
|
+
* // ... operación costosa ...
|
|
3295
|
+
* logger.timeEnd('proceso-datos'); // ⏱️ Timer ended: proceso-datos - 1523.45ms
|
|
3296
|
+
*
|
|
3297
|
+
* @since 0.3.0
|
|
3298
|
+
*/
|
|
3299
|
+
time(label) {
|
|
3300
|
+
const timer = {
|
|
3301
|
+
label,
|
|
3302
|
+
startTime: performance.now()
|
|
3303
|
+
};
|
|
3304
|
+
this.timers.set(label, timer);
|
|
3305
|
+
const timerStyle = StylePresets.warning().build();
|
|
3306
|
+
console.log(`%c⏱️ Timer started: ${label}`, timerStyle);
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* Finaliza un temporizador y muestra el tiempo transcurrido
|
|
3310
|
+
*
|
|
3311
|
+
* @param {string} label - Etiqueta del temporizador a finalizar
|
|
3312
|
+
*
|
|
3313
|
+
* @example
|
|
3314
|
+
* logger.time('consulta-db');
|
|
3315
|
+
* await consultarBaseDatos();
|
|
3316
|
+
* logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms
|
|
3317
|
+
*
|
|
3318
|
+
* @since 0.3.0
|
|
3319
|
+
*/
|
|
3320
|
+
timeEnd(label) {
|
|
3321
|
+
const timer = this.timers.get(label);
|
|
3322
|
+
if (!timer) {
|
|
3323
|
+
this.warn(`Timer '${label}' does not exist`);
|
|
3324
|
+
return;
|
|
3325
|
+
}
|
|
3326
|
+
const elapsed = performance.now() - timer.startTime;
|
|
3327
|
+
this.timers.delete(label);
|
|
3328
|
+
const timerStyle = StylePresets.success().build();
|
|
3329
|
+
console.log(`%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`, timerStyle);
|
|
3330
|
+
}
|
|
3331
|
+
// ===== ADVANCED VISUAL FEATURES =====
|
|
3332
|
+
/**
|
|
3333
|
+
* Muestra un banner con el tipo especificado o configurado
|
|
3334
|
+
*
|
|
3335
|
+
* @param {BannerType} bannerType - Tipo de banner (opcional)
|
|
3336
|
+
*
|
|
3337
|
+
* @example
|
|
3338
|
+
* logger.showBanner('ascii'); // Banner ASCII art
|
|
3339
|
+
* logger.showBanner('unicode'); // Banner con caracteres Unicode
|
|
3340
|
+
* logger.showBanner('svg'); // Banner con gráfico SVG
|
|
3341
|
+
* logger.showBanner(); // Usa el tipo configurado
|
|
3342
|
+
*
|
|
3343
|
+
* @since 0.3.0
|
|
3344
|
+
*/
|
|
3345
|
+
showBanner(bannerType) {
|
|
3346
|
+
const effectiveBannerType = bannerType ? bannerType : this.config.bannerType;
|
|
3347
|
+
displayInitBanner(effectiveBannerType);
|
|
3348
|
+
}
|
|
3349
|
+
/**
|
|
3350
|
+
* Registra mensaje con imagen SVG de fondo
|
|
3351
|
+
*
|
|
3352
|
+
* @param {string} message - Mensaje a mostrar
|
|
3353
|
+
* @param {string} svgContent - Contenido SVG personalizado (opcional)
|
|
3354
|
+
* @param {StyleOptions} options - Opciones de estilo (ancho, alto, padding)
|
|
3355
|
+
*
|
|
3356
|
+
* @example
|
|
3357
|
+
* // SVG automático con gradiente
|
|
3358
|
+
* logger.logWithSVG('🎆 Bienvenido a Better Logger');
|
|
3359
|
+
*
|
|
3360
|
+
* @example
|
|
3361
|
+
* // SVG personalizado
|
|
3362
|
+
* const customSVG = '<svg>...</svg>';
|
|
3363
|
+
* logger.logWithSVG('Logo', customSVG, { width: 400, height: 100 });
|
|
3364
|
+
*
|
|
3365
|
+
* @since 0.3.0
|
|
3366
|
+
*/
|
|
3367
|
+
logWithSVG(message, svgContent, options = {}) {
|
|
3368
|
+
const { width = 300, height = 60, padding = "30px 150px" } = options;
|
|
3369
|
+
let svgDataUri = "";
|
|
3370
|
+
if (svgContent) {
|
|
3371
|
+
const encodedSVG = encodeURIComponent(svgContent);
|
|
3372
|
+
svgDataUri = `data:image/svg+xml,${encodedSVG}`;
|
|
3373
|
+
} else {
|
|
3374
|
+
const defaultSVG = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${width} ${height}'><defs><linearGradient id='grad' x1='0%' y1='0%' x2='100%' y2='0%'><stop offset='0%' style='stop-color:%23667eea'/><stop offset='100%' style='stop-color:%23764ba2'/></linearGradient></defs><rect width='100%' height='100%' fill='url(%23grad)' rx='4'/><text x='${width / 2}' y='${height / 2 + 5}' text-anchor='middle' fill='white' font-family='monospace' font-size='14' font-weight='bold'>${message}</text></svg>`;
|
|
3375
|
+
svgDataUri = `data:image/svg+xml,${encodeURIComponent(defaultSVG)}`;
|
|
3376
|
+
}
|
|
3377
|
+
const svgStyle = new StyleBuilder().bg(`url("${svgDataUri}") no-repeat center center`).padding(padding).color("transparent").rounded("4px").build();
|
|
3378
|
+
console.log(`%c${message}`, svgStyle);
|
|
3379
|
+
}
|
|
3380
|
+
/**
|
|
3381
|
+
* Registra mensaje con gradiente animado de fondo
|
|
3382
|
+
*
|
|
3383
|
+
* @param {string} message - Mensaje a animar
|
|
3384
|
+
* @param {number} duration - Duración de la animación en segundos (default: 3)
|
|
3385
|
+
*
|
|
3386
|
+
* @example
|
|
3387
|
+
* logger.logAnimated('🌈 Animación en progreso');
|
|
3388
|
+
* logger.logAnimated('Cargando...', 5); // Animación de 5 segundos
|
|
3389
|
+
*
|
|
3390
|
+
* @since 0.3.0
|
|
3391
|
+
*/
|
|
3392
|
+
logAnimated(message, duration = 3) {
|
|
3393
|
+
if (!document.getElementById("logger-animations")) {
|
|
3394
|
+
const style = document.createElement("style");
|
|
3395
|
+
style.id = "logger-animations";
|
|
3396
|
+
style.textContent = `
|
|
3397
|
+
@keyframes loggerGradient {
|
|
3398
|
+
0% { background-position: 0% 50%; }
|
|
3399
|
+
50% { background-position: 100% 50%; }
|
|
3400
|
+
100% { background-position: 0% 50%; }
|
|
3401
|
+
}
|
|
3402
|
+
`;
|
|
3403
|
+
document.head.appendChild(style);
|
|
3404
|
+
}
|
|
3405
|
+
const animatedStyle = new StyleBuilder().bg("linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2)").css("background-size", "400% 400%").color("#ffffff").padding("12px 20px").rounded("8px").bold().font("Monaco, Consolas, monospace").animation(`loggerGradient ${duration}s ease infinite`).display("inline-block").build();
|
|
3406
|
+
console.log(`%c${message}`, animatedStyle);
|
|
3407
|
+
}
|
|
3408
|
+
/**
|
|
3409
|
+
* Agrupa logs por una propiedad específica usando Object.groupBy (cuando esté disponible)
|
|
3410
|
+
*
|
|
3411
|
+
* @param {T[]} items - Array de elementos a agrupar
|
|
3412
|
+
* @param {Function} groupBy - Función que retorna la clave de agrupación
|
|
3413
|
+
*
|
|
3414
|
+
* @example
|
|
3415
|
+
* const ventas = [
|
|
3416
|
+
* { producto: 'Laptop', categoria: 'Electrónica', precio: 1200 },
|
|
3417
|
+
* { producto: 'Mouse', categoria: 'Electrónica', precio: 25 },
|
|
3418
|
+
* { producto: 'Libro', categoria: 'Literatura', precio: 15 }
|
|
3419
|
+
* ];
|
|
3420
|
+
* logger.logGrouped(ventas, item => item.categoria);
|
|
3421
|
+
*
|
|
3422
|
+
* @since 0.3.0
|
|
3423
|
+
*/
|
|
3424
|
+
logGrouped(items, groupBy) {
|
|
3425
|
+
try {
|
|
3426
|
+
let grouped;
|
|
3427
|
+
if (Object.groupBy) {
|
|
3428
|
+
grouped = Object.groupBy(items, groupBy);
|
|
3429
|
+
} else {
|
|
3430
|
+
grouped = items.reduce((acc, item) => {
|
|
3431
|
+
const key = groupBy(item);
|
|
3432
|
+
if (!acc[key]) {
|
|
3433
|
+
acc[key] = [];
|
|
3434
|
+
}
|
|
3435
|
+
acc[key].push(item);
|
|
3436
|
+
return acc;
|
|
3437
|
+
}, {});
|
|
3438
|
+
}
|
|
3439
|
+
Object.entries(grouped).forEach(([group2, groupItems]) => {
|
|
3440
|
+
this.group(`Group: ${group2}`);
|
|
3441
|
+
this.table(groupItems);
|
|
3442
|
+
this.groupEnd();
|
|
3443
|
+
});
|
|
3444
|
+
} catch {
|
|
3445
|
+
this.info("Grouped data:", items);
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
// ===== CLI SYSTEM =====
|
|
3449
|
+
/**
|
|
3450
|
+
* Procesador de comandos CLI para configuración y exportación del logger
|
|
3451
|
+
*
|
|
3452
|
+
* @param {string} command - Comando CLI a ejecutar
|
|
3453
|
+
* @returns {Promise<void>}
|
|
3454
|
+
*
|
|
3455
|
+
* @example
|
|
3456
|
+
* // Comandos disponibles
|
|
3457
|
+
* await logger.cli('export json'); // Exporta logs en JSON
|
|
3458
|
+
* await logger.cli('export csv'); // Exporta logs en CSV
|
|
3459
|
+
* await logger.cli('theme list'); // Lista temas disponibles
|
|
3460
|
+
* await logger.cli('theme set neon'); // Cambia al tema neon
|
|
3461
|
+
* await logger.cli('config show'); // Muestra configuración actual
|
|
3462
|
+
* await logger.cli('history clear'); // Limpia historial de logs
|
|
3463
|
+
* await logger.cli('status'); // Muestra estado del logger
|
|
3464
|
+
* await logger.cli('help'); // Muestra ayuda de comandos
|
|
3465
|
+
*
|
|
3466
|
+
* @since 0.3.0
|
|
3467
|
+
*/
|
|
3468
|
+
async cli(command) {
|
|
3469
|
+
if (!this.cliProcessor) {
|
|
3470
|
+
this.error("CLI processor not initialized");
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
await this.cliProcessor.processCommand(command, this);
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
let _defaultLogger = null;
|
|
3477
|
+
function getDefaultLogger() {
|
|
3478
|
+
if (!_defaultLogger) {
|
|
3479
|
+
_defaultLogger = new Logger({
|
|
3480
|
+
verbosity: "info",
|
|
3481
|
+
enableColors: true,
|
|
3482
|
+
enableTimestamps: true,
|
|
3483
|
+
enableStackTrace: true,
|
|
3484
|
+
bufferSize: 1e3
|
|
3485
|
+
// Enable export functionality by default
|
|
3486
|
+
});
|
|
3487
|
+
try {
|
|
3488
|
+
displayInitBanner();
|
|
3489
|
+
} catch (error2) {
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
return _defaultLogger;
|
|
3493
|
+
}
|
|
3494
|
+
getDefaultLogger();
|
|
3495
|
+
export {
|
|
3496
|
+
BANNER_VARIANTS as B,
|
|
3497
|
+
ExportLogHandler as E,
|
|
3498
|
+
Logger as L,
|
|
3499
|
+
THEME_PRESETS as T,
|
|
3500
|
+
THEME_BANNERS as a,
|
|
3501
|
+
displayInitBanner as d
|
|
3502
|
+
};
|
|
3503
|
+
//# sourceMappingURL=Logger-B7L-ujY4.js.map
|