@mks2508/better-logger 5.0.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/chunks/{Logger-Cbi1f10o.js → Logger-CKqzXDh3.js} +2 -2
  2. package/dist/chunks/{Logger-Cbi1f10o.js.map → Logger-CKqzXDh3.js.map} +1 -1
  3. package/dist/chunks/{Logger-BZ7B7OXE.js → Logger-D_vuKP4l.js} +2 -2
  4. package/dist/chunks/{Logger-BZ7B7OXE.js.map → Logger-D_vuKP4l.js.map} +1 -1
  5. package/dist/chunks/cli-module-B-njrTWb.js +2 -0
  6. package/dist/chunks/cli-module-B-njrTWb.js.map +1 -0
  7. package/dist/chunks/{cli-module-ClIJmaT8.js → cli-module-Cx7qotPY.js} +16 -9
  8. package/dist/chunks/cli-module-Cx7qotPY.js.map +1 -0
  9. package/dist/cli.cjs +1 -1
  10. package/dist/cli.js +1 -1
  11. package/dist/exports.cjs +1 -1
  12. package/dist/exports.js +1 -1
  13. package/dist/index.cjs +1 -1
  14. package/dist/index.js +3 -3
  15. package/dist/styling.cjs +1 -1
  16. package/dist/styling.js +2 -2
  17. package/dist/terminal/formatter.d.ts.map +1 -1
  18. package/package.json +5 -1
  19. package/.claude/settings.local.json +0 -48
  20. package/.github/workflows/ci-quality.yml +0 -357
  21. package/.github/workflows/docs-demo.yml +0 -119
  22. package/.github/workflows/releases-core.yml +0 -512
  23. package/.github/workflows/releases-full.yml +0 -582
  24. package/.github/workflows-backup/ci.yml +0 -221
  25. package/.github/workflows-backup/nightly.yml +0 -196
  26. package/.github/workflows-backup/release-optimized.yml +0 -373
  27. package/.github/workflows-backup/release.yml +0 -269
  28. package/.release-notes-0.2.0.md +0 -129
  29. package/.yamllint +0 -28
  30. package/CHANGELOG.json +0 -1076
  31. package/CHANGELOG.md +0 -209
  32. package/CLAUDE.md +0 -217
  33. package/bun.lock +0 -333
  34. package/demo.html +0 -847
  35. package/dist/chunks/cli-module-CadqgZ1Z.js +0 -2
  36. package/dist/chunks/cli-module-CadqgZ1Z.js.map +0 -1
  37. package/dist/chunks/cli-module-ClIJmaT8.js.map +0 -1
  38. package/docs/API.md +0 -918
  39. package/docs/CORE.md +0 -264
  40. package/docs/DEVELOPMENT.md +0 -731
  41. package/docs/EXPORTS.md +0 -467
  42. package/docs/PACKAGES.md +0 -244
  43. package/docs/STYLING.md +0 -405
  44. package/docs/_config.yml +0 -36
  45. package/docs/index.md +0 -179
  46. package/examples/README.md +0 -208
  47. package/examples/basic-logging.js +0 -75
  48. package/examples/data-export.js +0 -234
  49. package/examples/package.json +0 -16
  50. package/examples/performance-timing.js +0 -170
  51. package/examples/simplified-api.js +0 -124
  52. package/examples/styling-themes.js +0 -207
  53. package/index.html +0 -358
  54. package/packages/core/package.json +0 -57
  55. package/packages/exports/package.json +0 -41
  56. package/packages/nodejs-opentui/README.md +0 -232
  57. package/packages/nodejs-opentui/package.json +0 -72
  58. package/packages/nodejs-opentui/src/LogRenderer.ts +0 -171
  59. package/packages/nodejs-opentui/src/OpenTUILogHandler.ts +0 -178
  60. package/packages/nodejs-opentui/src/components/LogBadge.tsx +0 -131
  61. package/packages/nodejs-opentui/src/index.ts +0 -133
  62. package/packages/nodejs-opentui/src/types.ts +0 -158
  63. package/packages/nodejs-opentui/tsconfig.json +0 -20
  64. package/packages/styling/package.json +0 -41
  65. package/playground/demo-all.ts +0 -95
  66. package/playground/demo-box.ts +0 -85
  67. package/playground/demo-levels.ts +0 -56
  68. package/playground/demo-real-world.ts +0 -98
  69. package/playground/demo-spinner.ts +0 -77
  70. package/playground/demo-steps.ts +0 -72
  71. package/playground/demo-table.ts +0 -83
  72. package/project-utils/README.md +0 -172
  73. package/project-utils/auto-release-gemini.ts +0 -1193
  74. package/project-utils/auto-release-ui.ts +0 -1329
  75. package/project-utils/commit-generator.ts +0 -1385
  76. package/project-utils/commit-ui.ts +0 -264
  77. package/project-utils/git-utils.ts +0 -199
  78. package/project-utils/github-release-manager.ts +0 -466
  79. package/project-utils/project-config.ts +0 -260
  80. package/project-utils/prompt-templates.js +0 -345
  81. package/project-utils/prompt-templates.ts +0 -422
  82. package/project-utils/version-manager.ts +0 -1078
  83. package/public/vite.svg +0 -1
  84. package/src/Logger.ts +0 -1858
  85. package/src/ScopedLogger.ts +0 -256
  86. package/src/cli/CommandProcessor.ts +0 -248
  87. package/src/cli/commands/ConfigCommand.ts +0 -93
  88. package/src/cli/commands/ExportCommand.ts +0 -276
  89. package/src/cli/commands/HistoryCommand.ts +0 -117
  90. package/src/cli/commands/StatusCommand.ts +0 -112
  91. package/src/cli/commands/ThemeCommand.ts +0 -88
  92. package/src/cli/help.ts +0 -127
  93. package/src/cli/index.ts +0 -71
  94. package/src/cli-module.ts +0 -21
  95. package/src/cli-primitives/box.ts +0 -86
  96. package/src/cli-primitives/cli-table.ts +0 -62
  97. package/src/cli-primitives/divider.ts +0 -17
  98. package/src/cli-primitives/header.ts +0 -18
  99. package/src/cli-primitives/index.ts +0 -13
  100. package/src/cli-primitives/server-fallback.ts +0 -54
  101. package/src/cli-primitives/spinner.ts +0 -133
  102. package/src/cli-primitives/step.ts +0 -22
  103. package/src/constants.ts +0 -313
  104. package/src/core.ts +0 -397
  105. package/src/example.ts +0 -210
  106. package/src/exports-module.ts +0 -311
  107. package/src/handlers/AnalyticsLogHandler.ts +0 -22
  108. package/src/handlers/ExportLogHandler.ts +0 -610
  109. package/src/handlers/FileLogHandler.ts +0 -169
  110. package/src/handlers/RemoteLogHandler.ts +0 -42
  111. package/src/handlers/index.ts +0 -8
  112. package/src/hooks/HookManager.ts +0 -177
  113. package/src/hooks/index.ts +0 -1
  114. package/src/index.ts +0 -395
  115. package/src/main.ts +0 -196
  116. package/src/serializers/SerializerRegistry.ts +0 -173
  117. package/src/serializers/index.ts +0 -1
  118. package/src/style.css +0 -96
  119. package/src/styling/LogStyleBuilder.ts +0 -355
  120. package/src/styling/SemanticStyles.ts +0 -380
  121. package/src/styling/SmartPresets.ts +0 -288
  122. package/src/styling/StyleBuilder.ts +0 -319
  123. package/src/styling/StyleCache.ts +0 -131
  124. package/src/styling/banners.ts +0 -168
  125. package/src/styling/index.ts +0 -27
  126. package/src/styling/themes.ts +0 -235
  127. package/src/styling-module.ts +0 -244
  128. package/src/terminal/color-converter.ts +0 -315
  129. package/src/terminal/formatter.ts +0 -236
  130. package/src/terminal/terminal-renderer.ts +0 -342
  131. package/src/transports/ConsoleTransport.ts +0 -28
  132. package/src/transports/FileTransport.ts +0 -53
  133. package/src/transports/HttpTransport.ts +0 -56
  134. package/src/transports/TransportManager.ts +0 -130
  135. package/src/transports/index.ts +0 -4
  136. package/src/types/core.ts +0 -417
  137. package/src/types/handlers.ts +0 -95
  138. package/src/types/hooks.ts +0 -45
  139. package/src/types/index.ts +0 -83
  140. package/src/types/serializers.ts +0 -30
  141. package/src/types/transports.ts +0 -52
  142. package/src/typescript.svg +0 -1
  143. package/src/utils/adapter.ts +0 -291
  144. package/src/utils/ansi-colors.ts +0 -333
  145. package/src/utils/environment-detector.ts +0 -170
  146. package/src/utils/environment.ts +0 -94
  147. package/src/utils/formatting.ts +0 -332
  148. package/src/utils/index.ts +0 -33
  149. package/src/utils/opentui-detection.ts +0 -138
  150. package/src/utils/output.ts +0 -227
  151. package/src/utils/stackTrace.ts +0 -144
  152. package/src/utils/timestamps.ts +0 -80
  153. package/src/vite-env.d.ts +0 -1
  154. package/src/writers/BufferWriter.ts +0 -157
  155. package/src/writers/index.ts +0 -6
  156. package/test-core-browser.html +0 -237
  157. package/test-core-node.js +0 -63
  158. package/tests/test-conflict-resolution.ts +0 -391
  159. package/tests/validate-workflows.sh +0 -131
  160. package/tests/yaml-autofix.sh +0 -146
  161. package/tsconfig.json +0 -50
  162. package/vite.config.ts +0 -256
package/src/Logger.ts DELETED
@@ -1,1858 +0,0 @@
1
- /**
2
- * @fileoverview Logger avanzado con arquitectura modular y API simplificada
3
- * @version 0.3.0
4
- * @since 2024
5
- *
6
- * Sistema de logging profesional con estilos CSS avanzados, temas adaptativos,
7
- * badges automáticos, contextos temporales y exportación de datos.
8
- */
9
-
10
- // Type imports
11
- import type {
12
- LogLevel,
13
- Verbosity,
14
- ThemeVariant,
15
- BannerType,
16
- LoggerConfig,
17
- TimerEntry,
18
- ILogHandler,
19
- LogMetadata,
20
- StyleOptions,
21
- Bindings,
22
- SerializerFn,
23
- HookEvent,
24
- HookCallback,
25
- MiddlewareFn,
26
- TransportTarget,
27
- TransportRecord
28
- } from './types/index.js';
29
-
30
- // Enterprise features
31
- import { SerializerRegistry } from './serializers/index.js';
32
- import { HookManager } from './hooks/index.js';
33
- import { TransportManager } from './transports/index.js';
34
-
35
- // Utility imports
36
- import { parseStackTrace } from './utils/stackTrace.js';
37
- import { formatTimestamp } from './utils/timestamps.js';
38
- import { createStyledOutput, setupThemeChangeListener } from './utils/output.js';
39
- import { getEnvironment, getColorCapability, isRunningInTerminal } from './utils/environment-detector.js';
40
- import { formatBadge } from './terminal/formatter.js';
41
-
42
- // Styling imports
43
- import {
44
- THEME_PRESETS,
45
- THEME_BANNERS,
46
- displayInitBanner,
47
- StylePresets,
48
- StyleBuilder
49
- } from './styling/index.js';
50
-
51
- // Smart presets and dynamic scoped loggers
52
- import { getSmartPreset, getAvailablePresets, hasPreset } from './styling/SmartPresets.js';
53
- import { createLogStyleBuilder } from './styling/LogStyleBuilder.js';
54
-
55
- // Scoped loggers (static import for performance)
56
- import { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';
57
-
58
- // Handler imports
59
- import { ExportLogHandler } from './handlers/index.js';
60
-
61
- // CLI imports
62
- import { createDefaultCLI, type CommandProcessor } from './cli/index.js';
63
-
64
- // Constants
65
- import { DEFAULT_CONFIG, CLI_LEVEL_MAP } from './constants.js';
66
-
67
- // CLI Primitives
68
- import type { CLILogLevel, ISpinnerHandle, IBoxOptions, ITableOptions } from './types/index.js';
69
- import { renderStep } from './cli-primitives/step.js';
70
- import { renderHeader } from './cli-primitives/header.js';
71
- import { renderDivider } from './cli-primitives/divider.js';
72
- import { renderBox } from './cli-primitives/box.js';
73
- import { renderTable } from './cli-primitives/cli-table.js';
74
- import { SpinnerManager, NoopSpinner } from './cli-primitives/spinner.js';
75
- import { ServerFallback } from './cli-primitives/server-fallback.js';
76
-
77
- /**
78
- * Estilos del tema activo actual
79
- * @private
80
- */
81
- let LEVEL_STYLES = THEME_PRESETS.default;
82
-
83
- /**
84
- * Clase principal Logger con capacidades avanzadas de logging
85
- *
86
- * @class Logger
87
- * @description Sistema completo de logging con temas, badges, contextos y exportación.
88
- * Detecta automáticamente el tema claro/oscuro del navegador.
89
- *
90
- * @example
91
- * // Uso básico sin configuración
92
- * import logger from '@mks2508/better-logger';
93
- * logger.info('Aplicación iniciada');
94
- * logger.success('Conexión establecida');
95
- *
96
- * @example
97
- * // Aplicar un preset temático
98
- * logger.preset('cyberpunk');
99
- * logger.warn('Advertencia con estilo neón');
100
- *
101
- * @example
102
- * // Logger con scope para componentes
103
- * const auth = logger.component('Autenticación');
104
- * auth.info('Usuario intentando login');
105
- * auth.success('Login exitoso');
106
- *
107
- * @since 0.3.0
108
- */
109
- export class Logger {
110
- private config: LoggerConfig;
111
- private scopedPrefix?: string;
112
- private handlers: ILogHandler[] = [];
113
- private timers: Map<string, TimerEntry> = new Map();
114
- private groupDepth: number = 0;
115
- private exportHandler?: ExportLogHandler;
116
- private cliProcessor?: CommandProcessor;
117
- private themeChangeListener?: (() => void) | null;
118
- private badgeList: string[] = [];
119
- private displaySettings = {
120
- showTimestamp: true,
121
- showLocation: true,
122
- showBadges: true
123
- };
124
-
125
- private serializerRegistry: SerializerRegistry;
126
- private hookManager: HookManager;
127
- private transportManager?: TransportManager;
128
-
129
- /** Whether CLI primitives (step, box, header, etc.) should be shown @since 5.0.0 */
130
- private _showPrimitives = true;
131
- /** Server-mode fallback for non-TTY environments @since 5.0.0 */
132
- private _serverFallback?: ServerFallback;
133
-
134
- /**
135
- * Crea una nueva instancia del Logger
136
- *
137
- * @param {Partial<LoggerConfig>} config - Configuración opcional del logger
138
- *
139
- * @example
140
- * // Logger con configuración personalizada
141
- * const logger = new Logger({
142
- * theme: 'neon',
143
- * globalPrefix: 'MiApp',
144
- * verbosity: 'debug',
145
- * bufferSize: 1000
146
- * });
147
- */
148
- constructor(config: Partial<LoggerConfig> = {}) {
149
- this.config = {
150
- ...DEFAULT_CONFIG,
151
- ...config,
152
- };
153
-
154
- // Initialize enterprise features
155
- this.serializerRegistry = new SerializerRegistry();
156
- this.hookManager = new HookManager();
157
-
158
- // Initialize export handler if buffer size is specified
159
- if (this.config.bufferSize) {
160
- this.exportHandler = new ExportLogHandler(this.config.bufferSize);
161
- this.handlers.push(this.exportHandler);
162
- }
163
-
164
- // Initialize CLI processor
165
- this.cliProcessor = createDefaultCLI();
166
-
167
- // Set up theme change listener if auto-detection is enabled
168
- if (this.config.autoDetectTheme) {
169
- this.setupAutoThemeDetection();
170
- }
171
- }
172
-
173
- // ===== PRIVATE HELPER METHODS =====
174
-
175
- /**
176
- * Configura la detección automática de tema con listener de cambios
177
- * @private
178
- * @description Detecta automáticamente si el navegador está en modo claro u oscuro
179
- */
180
- private setupAutoThemeDetection(): void {
181
- // Clean up existing listener if any
182
- if (this.themeChangeListener) {
183
- this.themeChangeListener();
184
- this.themeChangeListener = null;
185
- }
186
-
187
- // Set up new listener
188
- this.themeChangeListener = setupThemeChangeListener((theme) => {
189
- // Theme changed - logs will automatically use new colors on next call
190
- // No need to update anything as colors are resolved dynamically
191
- this.debug(`DevTools theme changed to: ${theme}`);
192
- });
193
- }
194
-
195
- // ===== CONFIGURATION METHODS =====
196
-
197
- /**
198
- * Obtiene la configuración actual del logger
199
- *
200
- * @returns {LoggerConfig} Configuración completa actual
201
- *
202
- * @example
203
- * const config = logger.getConfig();
204
- * console.log('Verbosidad actual:', config.verbosity);
205
- * console.log('Tema actual:', config.theme);
206
- *
207
- * @since 0.3.0
208
- */
209
- getConfig(): LoggerConfig {
210
- return { ...this.config };
211
- }
212
-
213
- /**
214
- * Actualiza la configuración del logger
215
- *
216
- * @param {Partial<LoggerConfig>} updates - Propiedades a actualizar
217
- *
218
- * @example
219
- * logger.updateConfig({
220
- * verbosity: 'debug',
221
- * enableTimestamps: false,
222
- * theme: 'cyberpunk'
223
- * });
224
- *
225
- * @since 0.3.0
226
- */
227
- updateConfig(updates: Partial<LoggerConfig>): void {
228
- const previousAutoDetect = this.config.autoDetectTheme;
229
- this.config = { ...this.config, ...updates };
230
-
231
- // Handle auto-detection changes
232
- if (updates.autoDetectTheme !== undefined && updates.autoDetectTheme !== previousAutoDetect) {
233
- if (updates.autoDetectTheme) {
234
- this.setupAutoThemeDetection();
235
- } else if (this.themeChangeListener) {
236
- this.themeChangeListener();
237
- this.themeChangeListener = null;
238
- }
239
- }
240
- }
241
-
242
- /**
243
- * Establece el prefijo global para todos los mensajes de log
244
- *
245
- * @param {string} prefix - Prefijo a usar
246
- *
247
- * @example
248
- * logger.setGlobalPrefix('MiApp');
249
- * logger.info('Iniciado'); // [MiApp] Iniciado
250
- *
251
- * @since 0.3.0
252
- */
253
- setGlobalPrefix(prefix: string): void {
254
- this.config.globalPrefix = prefix;
255
- }
256
-
257
- /**
258
- * Establece el nivel de verbosidad para filtrar la salida de logs
259
- *
260
- * @param {Verbosity} level - Nivel mínimo a mostrar ('debug' | 'info' | 'warn' | 'error' | 'critical' | 'silent')
261
- *
262
- * @example
263
- * logger.setVerbosity('warn'); // Solo muestra warn, error y critical
264
- * logger.setVerbosity('debug'); // Muestra todos los niveles
265
- * logger.setVerbosity('silent'); // No muestra nada
266
- *
267
- * @since 0.3.0
268
- */
269
- setVerbosity(level: Verbosity): void {
270
- this.config.verbosity = level;
271
- }
272
-
273
- /**
274
- * Establece el tema del logger
275
- *
276
- * @param {ThemeVariant} theme - Tema a aplicar ('default' | 'dark' | 'light' | 'neon' | 'minimal' | 'cyberpunk')
277
- *
278
- * @example
279
- * logger.setTheme('neon'); // Tema con colores neón
280
- * logger.setTheme('minimal'); // Tema minimalista
281
- * logger.setTheme('cyberpunk'); // Tema cyberpunk con efectos
282
- *
283
- * @since 0.3.0
284
- */
285
- setTheme(theme: ThemeVariant): void {
286
- // First check if it's a smart preset
287
- if (hasPreset(theme)) {
288
- this.preset(theme);
289
- return;
290
- }
291
-
292
- // Fallback to old theme system
293
- if (theme in THEME_PRESETS) {
294
- LEVEL_STYLES = (THEME_PRESETS as any)[theme];
295
- this.config.theme = theme;
296
-
297
- // Show theme-specific banner
298
- if (theme in THEME_BANNERS) {
299
- const themeBanner = (THEME_BANNERS as any)[theme];
300
- console.log(`%c${themeBanner.simple}`, themeBanner.style);
301
- }
302
-
303
- this.success(`Theme changed to: ${theme}`);
304
- } else {
305
- this.error(`Invalid theme: ${theme}. Available:`, [...getAvailablePresets(), ...Object.keys(THEME_PRESETS)]);
306
- }
307
- }
308
-
309
- /**
310
- * Establece el tipo de banner para mostrar en la inicialización
311
- *
312
- * @param {BannerType} bannerType - Tipo de banner ('simple' | 'ascii' | 'unicode' | 'svg' | 'animated')
313
- *
314
- * @example
315
- * logger.setBannerType('ascii'); // Banner con arte ASCII
316
- * logger.setBannerType('unicode'); // Banner con caracteres Unicode
317
- * logger.setBannerType('animated'); // Banner con animación
318
- *
319
- * @since 0.3.0
320
- */
321
- setBannerType(bannerType: BannerType): void {
322
- this.config.bannerType = bannerType;
323
- this.success(`Banner type changed to: ${bannerType}`);
324
- }
325
-
326
- /**
327
- * Reinicia el logger a la configuración por defecto
328
- *
329
- * @example
330
- * logger.resetConfig();
331
- * // Todo vuelve a la configuración inicial
332
- *
333
- * @since 0.3.0
334
- */
335
- resetConfig(): void {
336
- // Clean up theme listener
337
- if (this.themeChangeListener) {
338
- this.themeChangeListener();
339
- this.themeChangeListener = null;
340
- }
341
-
342
- this.config = { ...DEFAULT_CONFIG };
343
- LEVEL_STYLES = THEME_PRESETS.default;
344
-
345
- // Re-setup auto theme detection if enabled in default config
346
- if (this.config.autoDetectTheme) {
347
- this.setupAutoThemeDetection();
348
- }
349
-
350
- this.success('Logger configuration reset to defaults');
351
- }
352
-
353
- /**
354
- * Método de limpieza para eliminar listeners y liberar recursos
355
- *
356
- * @example
357
- * // Antes de cerrar la aplicación
358
- * logger.cleanup();
359
- *
360
- * @since 0.3.0
361
- */
362
- cleanup(): void {
363
- if (this.themeChangeListener) {
364
- this.themeChangeListener();
365
- this.themeChangeListener = null;
366
- }
367
- // Close transports
368
- this.transportManager?.close().catch(() => {});
369
- }
370
-
371
-
372
- // ===== SIMPLIFIED API =====
373
-
374
- /**
375
- * Aplica un preset inteligente - funciona perfectamente sin configuración
376
- *
377
- * @param {string} name - Nombre del preset a aplicar
378
- *
379
- * @example
380
- * // Presets disponibles
381
- * logger.preset('default'); // Limpio y adaptativo
382
- * logger.preset('cyberpunk'); // Colores neón, efectos brillantes
383
- * logger.preset('glassmorphism'); // Efectos de blur modernos
384
- * logger.preset('minimal'); // Minimalista y elegante
385
- * logger.preset('debug'); // Modo desarrollo detallado
386
- * logger.preset('production'); // Optimizado para producción
387
- *
388
- * @since 0.3.0
389
- */
390
- preset(name: string): void {
391
- if (!hasPreset(name)) {
392
- this.error(`Unknown preset: ${name}. Available presets:`, getAvailablePresets());
393
- return;
394
- }
395
-
396
- const presetConfig = getSmartPreset(name);
397
- if (presetConfig) {
398
- // Apply the smart preset configuration
399
- this.displaySettings.showTimestamp = presetConfig.timestamp?.show ?? true;
400
- this.displaySettings.showLocation = presetConfig.location?.show ?? true;
401
-
402
- // Store the preset config for use in createStyledOutput
403
- (this as any)._activePreset = presetConfig;
404
- (this as any)._activePresetName = name;
405
-
406
- // Only show success message in browser to avoid verbose terminal logs
407
- if (getEnvironment() === 'browser') {
408
- this.success(`Applied preset: ${name}`);
409
- }
410
- }
411
- }
412
-
413
- /**
414
- * Lista todos los presets disponibles
415
- *
416
- * @returns {string[]} Array con nombres de presets disponibles
417
- *
418
- * @example
419
- * const disponibles = logger.presets();
420
- * console.log(disponibles); // ['default', 'cyberpunk', 'glassmorphism', ...]
421
- *
422
- * @since 0.3.0
423
- */
424
- presets(): string[] {
425
- return getAvailablePresets();
426
- }
427
-
428
- // ===== TOGGLE METHODS =====
429
-
430
- /**
431
- * Oculta el timestamp en los logs
432
- *
433
- * @example
434
- * logger.hideTimestamp();
435
- * logger.info('Sin marca de tiempo'); // Sin timestamp visible
436
- *
437
- * @since 0.3.0
438
- */
439
- hideTimestamp(): this {
440
- this.displaySettings.showTimestamp = false;
441
- return this;
442
- }
443
-
444
- /**
445
- * Muestra el timestamp en los logs
446
- *
447
- * @example
448
- * logger.showTimestamp();
449
- * logger.info('Con marca de tiempo'); // [2024-01-15 10:30:45] Con marca de tiempo
450
- *
451
- * @since 0.3.0
452
- */
453
- showTimestamp(): this {
454
- this.displaySettings.showTimestamp = true;
455
- return this;
456
- }
457
-
458
- /**
459
- * Oculta la información de ubicación (archivo:línea) en los logs
460
- *
461
- * @example
462
- * logger.hideLocation();
463
- * logger.debug('Sin ubicación'); // Sin mostrar archivo:línea
464
- *
465
- * @since 0.3.0
466
- */
467
- hideLocation(): this {
468
- this.displaySettings.showLocation = false;
469
- return this;
470
- }
471
-
472
- /**
473
- * Muestra la información de ubicación (archivo:línea) en los logs
474
- *
475
- * @example
476
- * logger.showLocation();
477
- * logger.debug('Con ubicación'); // app.js:42 Con ubicación
478
- *
479
- * @since 0.3.0
480
- */
481
- showLocation(): this {
482
- this.displaySettings.showLocation = true;
483
- return this;
484
- }
485
-
486
- /**
487
- * Oculta los badges en los logs
488
- *
489
- * @example
490
- * logger.hideBadges();
491
- * const api = logger.api('REST');
492
- * api.info('Sin badges'); // Sin mostrar [API] [REST]
493
- *
494
- * @since 0.3.0
495
- */
496
- hideBadges(): this {
497
- this.displaySettings.showBadges = false;
498
- return this;
499
- }
500
-
501
- /**
502
- * Muestra los badges en los logs
503
- *
504
- * @example
505
- * logger.showBadges();
506
- * const api = logger.api('GraphQL');
507
- * api.info('Con badges'); // [API] [GraphQL] Con badges
508
- *
509
- * @since 0.3.0
510
- */
511
- showBadges(): this {
512
- this.displaySettings.showBadges = true;
513
- return this;
514
- }
515
-
516
- /**
517
- * Establece múltiples badges para los logs
518
- *
519
- * @param {string[]} badges - Array de badges a mostrar
520
- * @returns {this} Logger instance para encadenamiento
521
- *
522
- * @example
523
- * logger.badges(['v3', 'stable']).info('Release publicado');
524
- * logger.badges(['API', 'v2']).warn('Endpoint deprecado');
525
- *
526
- * @since 3.0.0
527
- */
528
- badges(badges: string[]): this {
529
- this.badgeList = [...badges];
530
- return this;
531
- }
532
-
533
- /**
534
- * Añade un badge individual a la lista
535
- *
536
- * @param {string} badge - Badge a añadir
537
- * @returns {this} Logger instance para encadenamiento
538
- *
539
- * @example
540
- * logger.badge('DEBUG').badge('AUTH').info('Token validado');
541
- *
542
- * @since 3.0.0
543
- */
544
- badge(badge: string): this {
545
- if (!this.badgeList.includes(badge)) {
546
- this.badgeList.push(badge);
547
- }
548
- return this;
549
- }
550
-
551
- /**
552
- * Limpia todos los badges activos
553
- *
554
- * @returns {this} Logger instance para encadenamiento
555
- *
556
- * @example
557
- * logger.clearBadges().info('Sin badges');
558
- *
559
- * @since 3.0.0
560
- */
561
- clearBadges(): this {
562
- this.badgeList = [];
563
- return this;
564
- }
565
-
566
- // ===== SCOPED LOGGERS =====
567
-
568
- component(name: string): ComponentLogger {
569
- return new ComponentLogger(this, name);
570
- }
571
-
572
- api(name: string): APILogger {
573
- return new APILogger(this, name);
574
- }
575
-
576
- scope(name: string): ScopedLogger {
577
- return new ScopedLogger(this, name);
578
- }
579
-
580
- // ===== SIMPLE CUSTOMIZATION =====
581
-
582
- /**
583
- * Personalización simple con configuración mínima
584
- *
585
- * @param {Object} overrides - Opciones de personalización
586
- * @param {Object} overrides.message - Configuración del mensaje
587
- * @param {Object} overrides.timestamp - Configuración del timestamp
588
- * @param {Object} overrides.location - Configuración de ubicación
589
- * @param {Object} overrides.level - Configuración del nivel
590
- * @param {Object} overrides.prefix - Configuración del prefijo
591
- * @param {string} overrides.spacing - Espaciado: 'compact' | 'normal' | 'spacious'
592
- *
593
- * @example
594
- * logger.customize({
595
- * message: { color: '#00ff00', size: '16px' },
596
- * timestamp: { show: false },
597
- * spacing: 'compact'
598
- * });
599
- *
600
- * @since 0.3.0
601
- */
602
- customize(overrides: {
603
- message?: { color?: string; font?: string; size?: string };
604
- timestamp?: { show?: boolean; color?: string };
605
- location?: { show?: boolean; color?: string };
606
- level?: { uppercase?: boolean; style?: string };
607
- prefix?: { show?: boolean; style?: string };
608
- spacing?: 'compact' | 'normal' | 'spacious';
609
- }): void {
610
- // Apply simple overrides
611
- if (overrides.timestamp?.show !== undefined) {
612
- this.displaySettings.showTimestamp = overrides.timestamp.show;
613
- }
614
- if (overrides.location?.show !== undefined) {
615
- this.displaySettings.showLocation = overrides.location.show;
616
- }
617
- if (overrides.prefix?.show !== undefined) {
618
- // Will be handled when we integrate with preset system
619
- }
620
-
621
- // Store customization for use in createStyledOutput
622
- (this as any)._customization = overrides;
623
- this.success('Customization applied');
624
- }
625
-
626
- /**
627
- * Access advanced styling API (for power users)
628
- */
629
- styles(): any {
630
- return createLogStyleBuilder(this);
631
- }
632
-
633
- // ===== HANDLER MANAGEMENT =====
634
-
635
- /**
636
- * Añade un handler personalizado para extender funcionalidad
637
- *
638
- * @param {ILogHandler} handler - Handler que implementa ILogHandler
639
- *
640
- * @example
641
- * // Handler personalizado para enviar logs a servidor
642
- * const remoteHandler = new RemoteLogHandler('https://api.ejemplo.com/logs');
643
- * logger.addHandler(remoteHandler);
644
- *
645
- * @example
646
- * // Handler para guardar en archivo
647
- * const fileHandler = new FileLogHandler('./app.log');
648
- * logger.addHandler(fileHandler);
649
- *
650
- * @since 0.3.0
651
- */
652
- addHandler(handler: ILogHandler): void {
653
- this.handlers.push(handler);
654
- }
655
-
656
- /**
657
- * Obtiene todos los handlers registrados
658
- *
659
- * @returns {ILogHandler[]} Array de handlers activos
660
- * @since 0.3.0
661
- */
662
- getHandlers(): ILogHandler[] {
663
- return [...this.handlers];
664
- }
665
-
666
- /**
667
- * Obtiene el handler de exportación si está disponible
668
- *
669
- * @returns {ExportLogHandler | undefined} Handler de exportación o undefined
670
- * @since 0.3.0
671
- */
672
- getExportHandler(): ExportLogHandler | undefined {
673
- return this.exportHandler;
674
- }
675
-
676
- // ===== SERIALIZERS =====
677
-
678
- /**
679
- * Añade un serializador personalizado para un tipo específico
680
- *
681
- * @param type - Constructor del tipo a serializar
682
- * @param serializer - Función de serialización
683
- * @param priority - Prioridad (mayor = primero)
684
- *
685
- * @example
686
- * logger.addSerializer(Error, (err) => ({
687
- * name: err.name,
688
- * message: err.message,
689
- * stack: err.stack?.split('\n').slice(0, 5)
690
- * }));
691
- *
692
- * @since 3.0.0
693
- */
694
- addSerializer<T>(
695
- type: new (...args: any[]) => T,
696
- serializer: SerializerFn<T>,
697
- priority?: number
698
- ): void {
699
- this.serializerRegistry.add(type, serializer, priority);
700
- }
701
-
702
- /**
703
- * Elimina un serializador registrado
704
- *
705
- * @param type - Constructor del tipo a remover
706
- * @returns true si se eliminó
707
- *
708
- * @since 3.0.0
709
- */
710
- removeSerializer<T>(type: new (...args: any[]) => T): boolean {
711
- return this.serializerRegistry.remove(type);
712
- }
713
-
714
- /**
715
- * Obtiene el registry de serializadores
716
- *
717
- * @returns SerializerRegistry
718
- * @since 3.0.0
719
- */
720
- getSerializerRegistry(): SerializerRegistry {
721
- return this.serializerRegistry;
722
- }
723
-
724
- // ===== HOOKS & MIDDLEWARE =====
725
-
726
- /**
727
- * Registra un hook para un evento
728
- *
729
- * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
730
- * @param callback - Función a ejecutar
731
- * @param priority - Prioridad (mayor = primero)
732
- * @returns Función para desregistrar
733
- *
734
- * @example
735
- * const unsubscribe = logger.on('beforeLog', (entry) => {
736
- * entry.correlationId = getCorrelationId();
737
- * return entry;
738
- * });
739
- *
740
- * @since 3.0.0
741
- */
742
- on(event: HookEvent, callback: HookCallback, priority?: number): () => void {
743
- return this.hookManager.on(event, callback, priority);
744
- }
745
-
746
- /**
747
- * Registra un hook que se ejecuta solo una vez
748
- *
749
- * @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
750
- * @param callback - Función a ejecutar
751
- * @param priority - Prioridad (mayor = primero)
752
- * @returns Función para desregistrar
753
- *
754
- * @since 3.0.0
755
- */
756
- once(event: HookEvent, callback: HookCallback, priority?: number): () => void {
757
- return this.hookManager.once(event, callback, priority);
758
- }
759
-
760
- /**
761
- * Elimina un hook registrado
762
- *
763
- * @param event - Evento del hook
764
- * @param callback - Callback a remover
765
- * @returns true si se eliminó
766
- *
767
- * @since 3.0.0
768
- */
769
- off(event: HookEvent, callback: HookCallback): boolean {
770
- return this.hookManager.off(event, callback);
771
- }
772
-
773
- /**
774
- * Añade un middleware al pipeline
775
- *
776
- * @param middleware - Función middleware
777
- * @param priority - Prioridad (mayor = primero)
778
- * @returns Función para desregistrar
779
- *
780
- * @example
781
- * logger.use((entry, next) => {
782
- * entry.requestId = asyncLocalStorage.getStore()?.requestId;
783
- * next();
784
- * });
785
- *
786
- * @since 3.0.0
787
- */
788
- use(middleware: MiddlewareFn, priority?: number): () => void {
789
- return this.hookManager.use(middleware, priority);
790
- }
791
-
792
- /**
793
- * Obtiene el HookManager
794
- *
795
- * @returns HookManager
796
- * @since 3.0.0
797
- */
798
- getHookManager(): HookManager {
799
- return this.hookManager;
800
- }
801
-
802
- // ===== TRANSPORTS =====
803
-
804
- /**
805
- * Añade un transport para envío de logs
806
- *
807
- * @param target - Configuración del transport
808
- * @returns ID único del transport
809
- *
810
- * @example
811
- * // File transport
812
- * logger.addTransport({
813
- * target: 'file',
814
- * options: { destination: '/var/log/app.log' }
815
- * });
816
- *
817
- * @example
818
- * // HTTP transport con batching
819
- * logger.addTransport({
820
- * target: 'http',
821
- * options: {
822
- * url: 'https://logs.example.com',
823
- * batchSize: 100,
824
- * flushInterval: 5000
825
- * },
826
- * level: 'warn'
827
- * });
828
- *
829
- * @since 3.0.0
830
- */
831
- addTransport(target: TransportTarget): string {
832
- if (!this.transportManager) {
833
- this.transportManager = new TransportManager();
834
- }
835
- return this.transportManager.add(target);
836
- }
837
-
838
- /**
839
- * Elimina un transport
840
- *
841
- * @param id - ID del transport a remover
842
- * @returns true si se eliminó
843
- *
844
- * @since 3.0.0
845
- */
846
- removeTransport(id: string): boolean {
847
- return this.transportManager?.remove(id) ?? false;
848
- }
849
-
850
- /**
851
- * Fuerza el flush de todos los transports
852
- *
853
- * @returns Promise que resuelve cuando todos los buffers están vaciados
854
- *
855
- * @since 3.0.0
856
- */
857
- async flushTransports(): Promise<void> {
858
- await this.transportManager?.flush();
859
- }
860
-
861
- /**
862
- * Cierra todos los transports
863
- *
864
- * @returns Promise que resuelve cuando todos están cerrados
865
- *
866
- * @since 3.0.0
867
- */
868
- async closeTransports(): Promise<void> {
869
- await this.transportManager?.close();
870
- }
871
-
872
- /**
873
- * Obtiene el TransportManager
874
- *
875
- * @returns TransportManager o undefined si no hay transports
876
- * @since 3.0.0
877
- */
878
- getTransportManager(): TransportManager | undefined {
879
- return this.transportManager;
880
- }
881
-
882
- // ===== CORE LOGGING METHODS =====
883
-
884
- /**
885
- * Verifica si un nivel de log debe mostrarse según la verbosidad actual
886
- * @private
887
- * @param {LogLevel} level - Nivel de log a verificar
888
- * @returns {boolean} True si debe mostrarse, false si no
889
- */
890
- private shouldLog(level: LogLevel): boolean {
891
- if (this.config.verbosity === 'silent') return false;
892
- const levels = { debug: 0, info: 1, warn: 2, error: 3, critical: 4 };
893
- return levels[level] >= levels[this.config.verbosity];
894
- }
895
-
896
- /**
897
- * Obtiene el prefijo efectivo (global + scope)
898
- * @private
899
- * @returns {string | undefined} Prefijo combinado o undefined
900
- */
901
- private getEffectivePrefix(): string | undefined {
902
- const parts = [this.config.globalPrefix, this.scopedPrefix].filter(Boolean);
903
- return parts.length > 0 ? parts.join(':') : undefined;
904
- }
905
-
906
- /**
907
- * Método central de logging que maneja estilos y formato
908
- * @protected
909
- * @param {LogLevel} level - Nivel del log
910
- * @param {...any} args - Argumentos a loggear
911
- */
912
- protected log(level: LogLevel, ...args: any[]): void {
913
- if (!this.shouldLog(level)) return;
914
-
915
- const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
916
- const prefix = this.getEffectivePrefix();
917
- const timestamp = formatTimestamp();
918
-
919
- // Serialize args using registry
920
- const serializedArgs = args.map(arg => this.serializerRegistry.serialize(arg));
921
-
922
- // Prepend badges to message if any
923
- let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';
924
- if (this.badgeList.length > 0 && this.displaySettings.showBadges) {
925
- const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');
926
- message = badgePrefix + ' ' + message;
927
- }
928
- const additionalArgs = serializedArgs.slice(1);
929
-
930
- // Process beforeLog hooks (sync for performance)
931
- let hookEntry = {
932
- level,
933
- message,
934
- args: serializedArgs,
935
- timestamp,
936
- prefix,
937
- stackInfo: stackInfo || undefined
938
- };
939
-
940
- // Emit beforeLog event (fire-and-forget for sync logging)
941
- this.hookManager.emit('beforeLog', hookEntry).then(processed => {
942
- message = processed.message;
943
- }).catch(() => {});
944
-
945
- // Create styled output with theme detection and display settings
946
- const [format, ...styles] = createStyledOutput(
947
- level,
948
- LEVEL_STYLES,
949
- prefix,
950
- message,
951
- this.displaySettings.showLocation ? stackInfo : null,
952
- this.config.autoDetectTheme,
953
- (this as any)._activePreset,
954
- (this as any)._activePresetName
955
- );
956
-
957
- // Add group indentation
958
- const groupIndent = ' '.repeat(this.groupDepth);
959
- const finalFormat = groupIndent + format;
960
-
961
- // Output via configured writer (console by default)
962
- this.writeOutput(finalFormat, level, styles, additionalArgs);
963
-
964
- // Update export handler group info
965
- if (this.exportHandler) {
966
- this.exportHandler.setGroupInfo(this.groupDepth);
967
- }
968
-
969
- // Call custom handlers
970
- const metadata: LogMetadata = {
971
- timestamp,
972
- level,
973
- prefix,
974
- stackInfo: stackInfo ? stackInfo : undefined,
975
- };
976
-
977
- this.handlers.forEach(handler => {
978
- try {
979
- handler.handle(level, message, serializedArgs, metadata);
980
- } catch (error) {
981
- console.error('Log handler failed:', error);
982
- }
983
- });
984
-
985
- // Write to transports (async, fire-and-forget)
986
- if (this.transportManager) {
987
- const levelValues: Record<LogLevel, number> = {
988
- debug: 0, info: 1, warn: 2, error: 3, critical: 4
989
- };
990
- const record: TransportRecord = {
991
- level,
992
- levelValue: levelValues[level],
993
- time: Date.now(),
994
- msg: message,
995
- prefix,
996
- location: stackInfo ? {
997
- file: stackInfo.file,
998
- line: stackInfo.line,
999
- column: stackInfo.column,
1000
- function: stackInfo.function
1001
- } : undefined
1002
- };
1003
- this.transportManager.write(record).catch(() => {});
1004
- }
1005
-
1006
- // Emit afterLog event (fire-and-forget)
1007
- this.hookManager.emit('afterLog', hookEntry).catch(() => {});
1008
- }
1009
-
1010
- logWithBindings(bindings: Bindings, level: LogLevel, ...args: any[]): void {
1011
- if (!this.shouldLog(level)) return;
1012
-
1013
- let prefix = '';
1014
- const colorCapability = getColorCapability();
1015
-
1016
- if (bindings.badges?.length) {
1017
- prefix += bindings.badges.map(b => formatBadge(b, 'pill', colorCapability, '#00ff88')).join(' ') + ' ';
1018
- }
1019
- if (bindings.scope) {
1020
- prefix += formatBadge(bindings.scope, 'pill', colorCapability, '#00ffff') + ' ';
1021
- }
1022
-
1023
- if (prefix && args.length > 0) {
1024
- args[0] = prefix + String(args[0]);
1025
- }
1026
-
1027
- this.log(level, ...args);
1028
- }
1029
-
1030
- debug(...args: any[]): void {
1031
- this.log('debug', ...args);
1032
- }
1033
-
1034
- /**
1035
- * Registra mensajes informativos
1036
- *
1037
- * @param {...any} args - Mensajes y datos informativos
1038
- *
1039
- * @example
1040
- * logger.info('Servidor iniciado en puerto 3000');
1041
- * logger.info('Usuario conectado:', userId);
1042
- * logger.info('Procesando', totalItems, 'elementos');
1043
- *
1044
- * @since 0.3.0
1045
- */
1046
- info(...args: any[]): void {
1047
- this.log('info', ...args);
1048
- }
1049
-
1050
- /**
1051
- * Registra mensajes de advertencia
1052
- *
1053
- * @param {...any} args - Mensajes de advertencia
1054
- *
1055
- * @example
1056
- * logger.warn('Memoria al 85% de capacidad');
1057
- * logger.warn('API deprecada, usar v2');
1058
- * logger.warn('Reintentos agotados:', maxRetries);
1059
- *
1060
- * @since 0.3.0
1061
- */
1062
- warn(...args: any[]): void {
1063
- this.log('warn', ...args);
1064
- }
1065
-
1066
- /**
1067
- * Registra mensajes de error
1068
- *
1069
- * @param {...any} args - Mensajes de error y stack traces
1070
- *
1071
- * @example
1072
- * logger.error('Fallo en conexión a base de datos');
1073
- * logger.error('Error al procesar:', error.message, error.stack);
1074
- * logger.error('Código de error:', errorCode);
1075
- *
1076
- * @since 0.3.0
1077
- */
1078
- error(...args: any[]): void {
1079
- this.log('error', ...args);
1080
- }
1081
-
1082
- /**
1083
- * Registra mensajes de éxito (nivel info especial)
1084
- *
1085
- * @param {...any} args - Mensajes de operaciones exitosas
1086
- *
1087
- * @example
1088
- * logger.success('Base de datos conectada');
1089
- * logger.success('Usuario creado con ID:', userId);
1090
- * logger.success('✓ Tests pasados: 42/42');
1091
- *
1092
- * @since 0.3.0
1093
- */
1094
- success(...args: any[]): void {
1095
- if (!this.shouldLog('info')) return;
1096
-
1097
- const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
1098
- const prefix = this.getEffectivePrefix();
1099
- const message = args.length > 0 ? String(args[0]) : '';
1100
- const additionalArgs = args.slice(1);
1101
-
1102
- // Handle success as special case - use info level with success styling
1103
- const [format, ...styles] = createStyledOutput(
1104
- 'info',
1105
- LEVEL_STYLES,
1106
- prefix,
1107
- message,
1108
- this.displaySettings.showLocation ? stackInfo : null,
1109
- this.config.autoDetectTheme,
1110
- (this as any)._activePreset,
1111
- (this as any)._activePresetName
1112
- );
1113
-
1114
- // Override with success styling
1115
- const successStyle = LEVEL_STYLES.success;
1116
- let emoji = '✅';
1117
- let label = 'SUCCESS';
1118
-
1119
- if (successStyle) {
1120
- if (successStyle.emoji) {
1121
- emoji = successStyle.emoji;
1122
- }
1123
- if (successStyle.label) {
1124
- label = successStyle.label;
1125
- }
1126
- }
1127
-
1128
- const successFormat = format.replace(/ℹ️ INFO/, `${emoji} ${label}`);
1129
-
1130
- const groupIndent = ' '.repeat(this.groupDepth);
1131
- const finalFormat = groupIndent + successFormat;
1132
-
1133
- if (additionalArgs.length > 0) {
1134
- console.log(finalFormat, ...styles, ...additionalArgs);
1135
- } else {
1136
- console.log(finalFormat, ...styles);
1137
- }
1138
-
1139
- // Call handlers
1140
- const metadata: LogMetadata = {
1141
- timestamp: formatTimestamp(),
1142
- level: 'info',
1143
- prefix,
1144
- stackInfo: stackInfo ? stackInfo : undefined,
1145
- };
1146
-
1147
- this.handlers.forEach(handler => {
1148
- try {
1149
- handler.handle('info', message, args, metadata);
1150
- } catch (error) {
1151
- console.error('Log handler failed:', error);
1152
- }
1153
- });
1154
- }
1155
-
1156
- /**
1157
- * Registra información de trace (debugging detallado)
1158
- *
1159
- * @param {...any} args - Datos detallados para debugging
1160
- *
1161
- * @example
1162
- * logger.trace('Entrando en función processData');
1163
- * logger.trace('Stack completo:', new Error().stack);
1164
- *
1165
- * @since 0.3.0
1166
- */
1167
- trace(...args: any[]): void {
1168
- this.log('debug', ...args);
1169
- if (this.shouldLog('debug')) {
1170
- console.trace(...args);
1171
- }
1172
- }
1173
-
1174
- /**
1175
- * Registra errores críticos (prioridad más alta)
1176
- *
1177
- * @param {...any} args - Errores críticos del sistema
1178
- *
1179
- * @example
1180
- * logger.critical('Sistema caído - reinicio inmediato requerido');
1181
- * logger.critical('Pérdida de datos detectada');
1182
- * logger.critical('Brecha de seguridad:', securityError);
1183
- *
1184
- * @since 0.3.0
1185
- */
1186
- critical(...args: any[]): void {
1187
- this.log('critical', ...args);
1188
- }
1189
-
1190
- // ===== ADVANCED LOGGING FEATURES =====
1191
-
1192
- /**
1193
- * Muestra datos en formato de tabla
1194
- *
1195
- * @param {any} data - Datos a mostrar (array de objetos o matriz)
1196
- * @param {string[]} columns - Columnas específicas a mostrar (opcional)
1197
- *
1198
- * @example
1199
- * const usuarios = [
1200
- * { id: 1, nombre: 'Juan', edad: 30 },
1201
- * { id: 2, nombre: 'María', edad: 25 }
1202
- * ];
1203
- * logger.table(usuarios);
1204
- * logger.table(usuarios, ['nombre', 'edad']); // Solo estas columnas
1205
- *
1206
- * @since 0.3.0
1207
- */
1208
- table(data: any, columns?: string[]): void {
1209
- if (!this.shouldLog('info')) return;
1210
-
1211
- const prefix = this.getEffectivePrefix();
1212
- const tableStyle = StylePresets.accent().build();
1213
-
1214
- const format = `%c📊 TABLE${prefix ? ` [${prefix}]` : ''}`;
1215
- console.log(format, tableStyle);
1216
-
1217
- if (columns) {
1218
- console.table(data, columns);
1219
- } else {
1220
- console.table(data);
1221
- }
1222
- }
1223
-
1224
- /**
1225
- * Inicia un grupo colapsable en la consola
1226
- *
1227
- * @param {string} label - Etiqueta del grupo
1228
- * @param {boolean} collapsed - Si el grupo inicia colapsado (default: false)
1229
- *
1230
- * @example
1231
- * logger.group('Procesando usuarios');
1232
- * logger.info('Usuario 1 procesado');
1233
- * logger.info('Usuario 2 procesado');
1234
- * logger.groupEnd();
1235
- *
1236
- * @example
1237
- * // Grupo colapsado por defecto
1238
- * logger.group('Detalles adicionales', true);
1239
- * logger.debug('Información detallada aquí');
1240
- * logger.groupEnd();
1241
- *
1242
- * @since 0.3.0
1243
- */
1244
- group(label: string, collapsed: boolean = false): void {
1245
- const groupStyle = new StyleBuilder()
1246
- .bg('linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)')
1247
- .color('#1565c0')
1248
- .border('1px solid #90caf9')
1249
- .padding('4px 12px')
1250
- .rounded('6px')
1251
- .bold()
1252
- .build();
1253
-
1254
- const format = `%c📁 ${label}`;
1255
-
1256
- if (collapsed) {
1257
- console.groupCollapsed(format, groupStyle);
1258
- } else {
1259
- console.group(format, groupStyle);
1260
- }
1261
-
1262
- this.groupDepth++;
1263
- }
1264
-
1265
- /**
1266
- * Finaliza el grupo actual de la consola
1267
- *
1268
- * @example
1269
- * logger.group('Operaciones');
1270
- * logger.info('Operación 1');
1271
- * logger.info('Operación 2');
1272
- * logger.groupEnd(); // Cierra el grupo
1273
- *
1274
- * @since 0.3.0
1275
- */
1276
- groupEnd(): void {
1277
- if (this.groupDepth > 0) {
1278
- console.groupEnd();
1279
- this.groupDepth--;
1280
- }
1281
- }
1282
-
1283
- // ===== PERFORMANCE TIMING =====
1284
-
1285
- /**
1286
- * Inicia un temporizador con la etiqueta dada
1287
- *
1288
- * @param {string} label - Etiqueta identificadora del temporizador
1289
- *
1290
- * @example
1291
- * logger.time('proceso-datos');
1292
- * // ... operación costosa ...
1293
- * logger.timeEnd('proceso-datos'); // ⏱️ Timer ended: proceso-datos - 1523.45ms
1294
- *
1295
- * @since 0.3.0
1296
- */
1297
- time(label: string): void {
1298
- const timer: TimerEntry = {
1299
- label,
1300
- startTime: performance.now(),
1301
- };
1302
- this.timers.set(label, timer);
1303
-
1304
- const timerStyle = StylePresets.warning().build();
1305
- console.log(`%c⏱️ Timer started: ${label}`, timerStyle);
1306
- }
1307
-
1308
- /**
1309
- * Finaliza un temporizador y muestra el tiempo transcurrido
1310
- *
1311
- * @param {string} label - Etiqueta del temporizador a finalizar
1312
- * @returns {number} Elapsed milliseconds, or -1 if timer not found
1313
- *
1314
- * @example
1315
- * logger.time('consulta-db');
1316
- * await consultarBaseDatos();
1317
- * const elapsed = logger.timeEnd('consulta-db'); // ⏱️ Timer ended: consulta-db - 234.56ms
1318
- *
1319
- * @since 0.3.0
1320
- */
1321
- timeEnd(label: string): number {
1322
- const timer = this.timers.get(label);
1323
- if (!timer) {
1324
- this.warn(`Timer '${label}' does not exist`);
1325
- return -1;
1326
- }
1327
-
1328
- const elapsed = performance.now() - timer.startTime;
1329
- this.timers.delete(label);
1330
-
1331
- const timerStyle = StylePresets.success().build();
1332
- console.log(`%c⏱️ Timer ended: ${label} - ${elapsed.toFixed(2)}ms`, timerStyle);
1333
-
1334
- return elapsed;
1335
- }
1336
-
1337
- // ===== ADVANCED VISUAL FEATURES =====
1338
-
1339
- /**
1340
- * Muestra un banner con el tipo especificado o configurado
1341
- *
1342
- * @param {BannerType} bannerType - Tipo de banner (opcional)
1343
- *
1344
- * @example
1345
- * logger.showBanner('ascii'); // Banner ASCII art
1346
- * logger.showBanner('unicode'); // Banner con caracteres Unicode
1347
- * logger.showBanner('svg'); // Banner con gráfico SVG
1348
- * logger.showBanner(); // Usa el tipo configurado
1349
- *
1350
- * @since 0.3.0
1351
- */
1352
- showBanner(bannerType?: BannerType): void {
1353
- const effectiveBannerType = bannerType ? bannerType : this.config.bannerType;
1354
- displayInitBanner(effectiveBannerType);
1355
- }
1356
-
1357
- /**
1358
- * Registra mensaje con imagen SVG de fondo
1359
- *
1360
- * @param {string} message - Mensaje a mostrar
1361
- * @param {string} svgContent - Contenido SVG personalizado (opcional)
1362
- * @param {StyleOptions} options - Opciones de estilo (ancho, alto, padding)
1363
- *
1364
- * @example
1365
- * // SVG automático con gradiente
1366
- * logger.logWithSVG('🎆 Bienvenido a Better Logger');
1367
- *
1368
- * @example
1369
- * // SVG personalizado
1370
- * const customSVG = '<svg>...</svg>';
1371
- * logger.logWithSVG('Logo', customSVG, { width: 400, height: 100 });
1372
- *
1373
- * @since 0.3.0
1374
- */
1375
- logWithSVG(message: string, svgContent?: string, options: StyleOptions = {}): void {
1376
- const { width = 300, height = 60, padding = '30px 150px' } = options;
1377
-
1378
- let svgDataUri = '';
1379
- if (svgContent) {
1380
- const encodedSVG = encodeURIComponent(svgContent);
1381
- svgDataUri = `data:image/svg+xml,${encodedSVG}`;
1382
- } else {
1383
- 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>`;
1384
- svgDataUri = `data:image/svg+xml,${encodeURIComponent(defaultSVG)}`;
1385
- }
1386
-
1387
- const svgStyle = new StyleBuilder()
1388
- .bg(`url("${svgDataUri}") no-repeat center center`)
1389
- .padding(padding)
1390
- .color('transparent')
1391
- .rounded('4px')
1392
- .build();
1393
-
1394
- console.log(`%c${message}`, svgStyle);
1395
- }
1396
-
1397
- /**
1398
- * Registra mensaje con gradiente animado de fondo
1399
- *
1400
- * @param {string} message - Mensaje a animar
1401
- * @param {number} duration - Duración de la animación en segundos (default: 3)
1402
- *
1403
- * @example
1404
- * logger.logAnimated('🌈 Animación en progreso');
1405
- * logger.logAnimated('Cargando...', 5); // Animación de 5 segundos
1406
- *
1407
- * @since 0.3.0
1408
- */
1409
- logAnimated(message: string, duration: number = 3): void {
1410
- // Inject CSS animation if not already present
1411
- if (!document.getElementById('logger-animations')) {
1412
- const style = document.createElement('style');
1413
- style.id = 'logger-animations';
1414
- style.textContent = `
1415
- @keyframes loggerGradient {
1416
- 0% { background-position: 0% 50%; }
1417
- 50% { background-position: 100% 50%; }
1418
- 100% { background-position: 0% 50%; }
1419
- }
1420
- `;
1421
- document.head.appendChild(style);
1422
- }
1423
-
1424
- const animatedStyle = new StyleBuilder()
1425
- .bg('linear-gradient(-45deg, #667eea, #764ba2, #667eea, #764ba2)')
1426
- .css('background-size', '400% 400%')
1427
- .color('#ffffff')
1428
- .padding('12px 20px')
1429
- .rounded('8px')
1430
- .bold()
1431
- .font('Monaco, Consolas, monospace')
1432
- .animation(`loggerGradient ${duration}s ease infinite`)
1433
- .display('inline-block')
1434
- .build();
1435
-
1436
- console.log(`%c${message}`, animatedStyle);
1437
- }
1438
-
1439
- /**
1440
- * Agrupa logs por una propiedad específica usando Object.groupBy (cuando esté disponible)
1441
- *
1442
- * @param {T[]} items - Array de elementos a agrupar
1443
- * @param {Function} groupBy - Función que retorna la clave de agrupación
1444
- *
1445
- * @example
1446
- * const ventas = [
1447
- * { producto: 'Laptop', categoria: 'Electrónica', precio: 1200 },
1448
- * { producto: 'Mouse', categoria: 'Electrónica', precio: 25 },
1449
- * { producto: 'Libro', categoria: 'Literatura', precio: 15 }
1450
- * ];
1451
- * logger.logGrouped(ventas, item => item.categoria);
1452
- *
1453
- * @since 0.3.0
1454
- */
1455
- logGrouped<T>(items: T[], groupBy: (item: T) => string): void {
1456
- try {
1457
- // Use Object.groupBy if available (ES2024), otherwise fallback to reduce
1458
- let grouped: Record<string, T[]>;
1459
-
1460
- if ((Object as any).groupBy) {
1461
- grouped = (Object as any).groupBy(items, groupBy);
1462
- } else {
1463
- grouped = items.reduce((acc, item) => {
1464
- const key = groupBy(item);
1465
- if (!acc[key]) {
1466
- acc[key] = [];
1467
- }
1468
- acc[key].push(item);
1469
- return acc;
1470
- }, {} as Record<string, T[]>);
1471
- }
1472
-
1473
- Object.entries(grouped).forEach(([group, groupItems]) => {
1474
- this.group(`Group: ${group}`);
1475
- this.table(groupItems);
1476
- this.groupEnd();
1477
- });
1478
- } catch {
1479
- this.info('Grouped data:', items);
1480
- }
1481
- }
1482
-
1483
- // ===== CLI PRIMITIVES (v5.0) =====
1484
-
1485
- /**
1486
- * Displays a step progress indicator in the terminal
1487
- *
1488
- * @param {number} current - Current step number
1489
- * @param {number} total - Total number of steps
1490
- * @param {string} message - Step description
1491
- *
1492
- * @example
1493
- * logger.step(1, 5, 'Analyzing repository...');
1494
- * logger.step(2, 5, 'Generating commit message...');
1495
- *
1496
- * @since 5.0.0
1497
- */
1498
- step(current: number, total: number, message: string): void {
1499
- if (!this._showPrimitives) return;
1500
- if (!isRunningInTerminal()) {
1501
- this.getServerFallback().step(current, total, message);
1502
- return;
1503
- }
1504
- const colorCap = getColorCapability();
1505
- const output = renderStep(current, total, message, colorCap);
1506
- process.stderr.write(output + '\n');
1507
- }
1508
-
1509
- /**
1510
- * Displays a styled header with optional subtitle
1511
- *
1512
- * @param {string} title - Main title text
1513
- * @param {string} subtitle - Optional subtitle (rendered dimmed)
1514
- *
1515
- * @example
1516
- * logger.header('Commit Wizard', 'v2.0.0');
1517
- *
1518
- * @since 5.0.0
1519
- */
1520
- header(title: string, subtitle?: string): void {
1521
- if (!this._showPrimitives) return;
1522
- if (!isRunningInTerminal()) {
1523
- this.getServerFallback().header(title, subtitle);
1524
- return;
1525
- }
1526
- const output = renderHeader(title, subtitle);
1527
- process.stderr.write(output + '\n');
1528
- }
1529
-
1530
- /**
1531
- * Displays a horizontal divider line
1532
- *
1533
- * @example
1534
- * logger.divider();
1535
- *
1536
- * @since 5.0.0
1537
- */
1538
- divider(): void {
1539
- if (!this._showPrimitives) return;
1540
- if (!isRunningInTerminal()) {
1541
- this.getServerFallback().divider();
1542
- return;
1543
- }
1544
- const output = renderDivider();
1545
- process.stderr.write(output + '\n');
1546
- }
1547
-
1548
- /**
1549
- * Outputs a blank line
1550
- *
1551
- * @example
1552
- * logger.blank();
1553
- *
1554
- * @since 5.0.0
1555
- */
1556
- blank(): void {
1557
- if (!this._showPrimitives) return;
1558
- if (!isRunningInTerminal()) {
1559
- this.getServerFallback().blank();
1560
- return;
1561
- }
1562
- process.stderr.write('\n');
1563
- }
1564
-
1565
- /**
1566
- * Renders content inside a bordered box
1567
- *
1568
- * @param {string} content - Content string (may contain newlines)
1569
- * @param {IBoxOptions} options - Box rendering options
1570
- *
1571
- * @example
1572
- * logger.box('3 commits generated\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });
1573
- *
1574
- * @since 5.0.0
1575
- */
1576
- box(content: string, options?: IBoxOptions): void {
1577
- if (!this._showPrimitives) return;
1578
- if (!isRunningInTerminal()) {
1579
- this.getServerFallback().box(content, options);
1580
- return;
1581
- }
1582
- const colorCap = getColorCapability();
1583
- const output = renderBox(content, options, colorCap);
1584
- process.stderr.write(output + '\n');
1585
- }
1586
-
1587
- /**
1588
- * Renders an array of objects as a formatted ASCII table.
1589
- * Note: This is distinct from the existing table() method which uses console.table.
1590
- *
1591
- * @param {Record<string, unknown>[]} rows - Array of row objects
1592
- * @param {ITableOptions} options - Table rendering options
1593
- *
1594
- * @example
1595
- * logger.cliTable([
1596
- * { provider: 'Groq', status: 'Available', model: 'llama-3.3-70b' },
1597
- * { provider: 'Gemini', status: 'Configured', model: 'gemini-2.5-flash' },
1598
- * ]);
1599
- *
1600
- * @since 5.0.0
1601
- */
1602
- cliTable(rows: Record<string, unknown>[], options?: ITableOptions): void {
1603
- if (!this._showPrimitives) return;
1604
- if (!isRunningInTerminal()) {
1605
- this.getServerFallback().cliTable(rows, options);
1606
- return;
1607
- }
1608
- const colorCap = getColorCapability();
1609
- const output = renderTable(rows, options, colorCap);
1610
- process.stderr.write(output + '\n');
1611
- }
1612
-
1613
- /**
1614
- * Creates a spinner handle for showing progress during async operations.
1615
- * Returns a NoopSpinner in non-TTY environments.
1616
- *
1617
- * @param {string} message - Initial spinner text
1618
- * @returns {ISpinnerHandle} Spinner controller
1619
- *
1620
- * @example
1621
- * const s = logger.spinner('Analyzing repository...');
1622
- * s.start();
1623
- * await analyzeRepo();
1624
- * s.succeed('Analysis complete (1.2s)');
1625
- *
1626
- * @since 5.0.0
1627
- */
1628
- spinner(message: string): ISpinnerHandle {
1629
- if (!isRunningInTerminal() || this.config.outputMode === 'silent') {
1630
- return new NoopSpinner(message, this);
1631
- }
1632
- return new SpinnerManager(message, this.config, this);
1633
- }
1634
-
1635
- /**
1636
- * Sets the CLI verbosity level, controlling both log verbosity and primitive visibility
1637
- *
1638
- * @param {CLILogLevel} level - CLI log level
1639
- *
1640
- * @example
1641
- * logger.setCLILevel('quiet'); // Only errors, no CLI primitives
1642
- * logger.setCLILevel('verbose'); // Debug logs + all CLI primitives
1643
- *
1644
- * @since 5.0.0
1645
- */
1646
- setCLILevel(level: CLILogLevel): void {
1647
- const mapping = CLI_LEVEL_MAP[level];
1648
- this.setVerbosity(mapping.verbosity);
1649
- this._showPrimitives = mapping.showPrimitives;
1650
- this.config.cliLevel = level;
1651
- }
1652
-
1653
- /**
1654
- * Returns the current CLI log level
1655
- * @returns {CLILogLevel} Current CLI log level
1656
- * @since 5.0.0
1657
- */
1658
- get cliLevel(): CLILogLevel {
1659
- return this.config.cliLevel ?? 'normal';
1660
- }
1661
-
1662
- /** Lazily creates the server fallback instance @private */
1663
- private getServerFallback(): ServerFallback {
1664
- if (!this._serverFallback) {
1665
- this._serverFallback = new ServerFallback(this);
1666
- }
1667
- return this._serverFallback;
1668
- }
1669
-
1670
- // ===== OUTPUT WRITER SYSTEM =====
1671
-
1672
- /**
1673
- * Writes formatted output to the configured destination.
1674
- * Respects outputMode configuration for console, silent, or custom output.
1675
- *
1676
- * @private
1677
- * @param {string} message - Formatted log message
1678
- * @param {LogLevel} level - Log level
1679
- * @param {string[]} styles - CSS styles for browser console
1680
- * @param {any[]} additionalArgs - Additional arguments to log
1681
- * @since 4.0.0
1682
- */
1683
- private writeOutput(
1684
- message: string,
1685
- level: LogLevel,
1686
- styles: string[],
1687
- additionalArgs: any[]
1688
- ): void {
1689
- const mode = this.config.outputMode ?? 'console';
1690
-
1691
- // Silent mode: no output
1692
- if (mode === 'silent') {
1693
- return;
1694
- }
1695
-
1696
- // Custom mode: use configured writer
1697
- if (mode === 'custom' && this.config.outputWriter) {
1698
- const fullMessage = additionalArgs.length > 0
1699
- ? `${message} ${additionalArgs.map(a => String(a)).join(' ')}`
1700
- : message;
1701
- this.config.outputWriter.write(fullMessage, level, styles);
1702
- return;
1703
- }
1704
-
1705
- // Default: console output
1706
- if (additionalArgs.length > 0) {
1707
- console.log(message, ...styles, ...additionalArgs);
1708
- } else {
1709
- console.log(message, ...styles);
1710
- }
1711
- }
1712
-
1713
- // ===== CLI SYSTEM =====
1714
-
1715
- /**
1716
- * Procesador de comandos CLI para configuración y exportación del logger
1717
- *
1718
- * @param {string} command - Comando CLI a ejecutar
1719
- * @returns {Promise<void>}
1720
- *
1721
- * @example
1722
- * // Comandos disponibles
1723
- * await logger.cli('export json'); // Exporta logs en JSON
1724
- * await logger.cli('export csv'); // Exporta logs en CSV
1725
- * await logger.cli('theme list'); // Lista temas disponibles
1726
- * await logger.cli('theme set neon'); // Cambia al tema neon
1727
- * await logger.cli('config show'); // Muestra configuración actual
1728
- * await logger.cli('history clear'); // Limpia historial de logs
1729
- * await logger.cli('status'); // Muestra estado del logger
1730
- * await logger.cli('help'); // Muestra ayuda de comandos
1731
- *
1732
- * @since 0.3.0
1733
- */
1734
- async cli(command: string): Promise<void> {
1735
- if (!this.cliProcessor) {
1736
- this.error('CLI processor not initialized');
1737
- return;
1738
- }
1739
-
1740
- await this.cliProcessor.processCommand(command, this);
1741
- }
1742
- }
1743
-
1744
- /**
1745
- * Lazy singleton instance - se inicializa solo cuando se necesita
1746
- * @private
1747
- */
1748
- let _defaultLogger: Logger | null = null;
1749
-
1750
- /**
1751
- * Obtiene o crea la instancia singleton del logger
1752
- * @returns {Logger} Instancia singleton del logger
1753
- */
1754
- function getDefaultLogger(): Logger {
1755
- if (!_defaultLogger) {
1756
- _defaultLogger = new Logger({
1757
- verbosity: 'info',
1758
- enableColors: true,
1759
- enableTimestamps: true,
1760
- enableStackTrace: true,
1761
- bufferSize: 1000, // Enable export functionality by default
1762
- });
1763
-
1764
- // Display initialization banner only once
1765
- try {
1766
- displayInitBanner();
1767
- } catch (error) {
1768
- // Silent fail if banner cannot be displayed
1769
- }
1770
- }
1771
- return _defaultLogger;
1772
- }
1773
-
1774
- // Export the lazy singleton getter as default
1775
- export default getDefaultLogger();
1776
-
1777
- /**
1778
- * Métodos individuales exportados para conveniencia
1779
- * @description Todos los métodos están correctamente enlazados al singleton lazy
1780
- * @since 0.3.0
1781
- */
1782
- export const debug = (...args: any[]) => getDefaultLogger().debug(...args);
1783
- export const info = (...args: any[]) => getDefaultLogger().info(...args);
1784
- export const warn = (...args: any[]) => getDefaultLogger().warn(...args);
1785
- export const error = (...args: any[]) => getDefaultLogger().error(...args);
1786
- export const success = (...args: any[]) => getDefaultLogger().success(...args);
1787
- export const trace = (...args: any[]) => getDefaultLogger().trace(...args);
1788
- export const critical = (...args: any[]) => getDefaultLogger().critical(...args);
1789
- export const table = (data: any, columns?: string[]) => getDefaultLogger().table(data, columns);
1790
- export const group = (label: string, collapsed?: boolean) => getDefaultLogger().group(label, collapsed);
1791
- export const groupEnd = () => getDefaultLogger().groupEnd();
1792
- export const time = (label: string) => getDefaultLogger().time(label);
1793
- export const timeEnd = (label: string) => getDefaultLogger().timeEnd(label);
1794
- export const setGlobalPrefix = (prefix: string) => getDefaultLogger().setGlobalPrefix(prefix);
1795
- export const setVerbosity = (level: Verbosity) => getDefaultLogger().setVerbosity(level);
1796
- export const addHandler = (handler: ILogHandler) => getDefaultLogger().addHandler(handler);
1797
- export const setTheme = (theme: ThemeVariant) => getDefaultLogger().setTheme(theme);
1798
- export const setBannerType = (bannerType: BannerType) => getDefaultLogger().setBannerType(bannerType);
1799
- export const showBanner = (bannerType?: BannerType) => getDefaultLogger().showBanner(bannerType);
1800
- export const logWithSVG = (message: string, svgContent?: string, options?: StyleOptions) =>
1801
- getDefaultLogger().logWithSVG(message, svgContent, options);
1802
- export const logAnimated = (message: string, duration?: number) =>
1803
- getDefaultLogger().logAnimated(message, duration);
1804
- export const cli = (command: string) => getDefaultLogger().cli(command);
1805
- export const cleanup = () => getDefaultLogger().cleanup();
1806
-
1807
- // Simplified API exports
1808
- export const preset = (name: string) => getDefaultLogger().preset(name);
1809
- export const presets = () => getDefaultLogger().presets();
1810
- export const hideTimestamp = () => getDefaultLogger().hideTimestamp();
1811
- export const showTimestamp = () => getDefaultLogger().showTimestamp();
1812
- export const hideLocation = () => getDefaultLogger().hideLocation();
1813
- export const showLocation = () => getDefaultLogger().showLocation();
1814
- export const hideBadges = () => getDefaultLogger().hideBadges();
1815
- export const showBadges = () => getDefaultLogger().showBadges();
1816
- export const badges = (badgeList: string[]) => getDefaultLogger().badges(badgeList);
1817
- export const badge = (badgeName: string) => getDefaultLogger().badge(badgeName);
1818
- export const clearBadges = () => getDefaultLogger().clearBadges();
1819
- export const component = (name: string) => getDefaultLogger().component(name);
1820
- export const api = (name: string) => getDefaultLogger().api(name);
1821
- export const scope = (name: string) => getDefaultLogger().scope(name);
1822
- export const customize = (overrides: any) => getDefaultLogger().customize(overrides);
1823
- export const styles = () => getDefaultLogger().styles();
1824
-
1825
- // Enterprise features exports
1826
- export const addSerializer = <T>(
1827
- type: new (...args: any[]) => T,
1828
- serializer: SerializerFn<T>,
1829
- priority?: number
1830
- ) => getDefaultLogger().addSerializer(type, serializer, priority);
1831
- export const removeSerializer = <T>(type: new (...args: any[]) => T) =>
1832
- getDefaultLogger().removeSerializer(type);
1833
- export const on = (event: HookEvent, callback: HookCallback, priority?: number) =>
1834
- getDefaultLogger().on(event, callback, priority);
1835
- export const once = (event: HookEvent, callback: HookCallback, priority?: number) =>
1836
- getDefaultLogger().once(event, callback, priority);
1837
- export const off = (event: HookEvent, callback: HookCallback) =>
1838
- getDefaultLogger().off(event, callback);
1839
- export const use = (middleware: MiddlewareFn, priority?: number) =>
1840
- getDefaultLogger().use(middleware, priority);
1841
- export const addTransport = (target: TransportTarget) =>
1842
- getDefaultLogger().addTransport(target);
1843
- export const removeTransport = (id: string) =>
1844
- getDefaultLogger().removeTransport(id);
1845
- export const flushTransports = () =>
1846
- getDefaultLogger().flushTransports();
1847
- export const closeTransports = () =>
1848
- getDefaultLogger().closeTransports();
1849
-
1850
- // Re-export handlers and utilities for backward compatibility
1851
- export { FileLogHandler, RemoteLogHandler, AnalyticsLogHandler, ExportLogHandler } from './handlers/index.js';
1852
- export { StyleBuilder, StylePresets as Styles } from './styling/index.js';
1853
-
1854
- // Re-export enterprise features
1855
- export { SerializerRegistry } from './serializers/index.js';
1856
- export { HookManager } from './hooks/index.js';
1857
- export { TransportManager, ConsoleTransport, FileTransport, HttpTransport } from './transports/index.js';
1858
- export { StyleCache, getStyleCache } from './styling/StyleCache.js';