@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.
- package/dist/chunks/{Logger-Cbi1f10o.js → Logger-CKqzXDh3.js} +2 -2
- package/dist/chunks/{Logger-Cbi1f10o.js.map → Logger-CKqzXDh3.js.map} +1 -1
- package/dist/chunks/{Logger-BZ7B7OXE.js → Logger-D_vuKP4l.js} +2 -2
- package/dist/chunks/{Logger-BZ7B7OXE.js.map → Logger-D_vuKP4l.js.map} +1 -1
- package/dist/chunks/cli-module-B-njrTWb.js +2 -0
- package/dist/chunks/cli-module-B-njrTWb.js.map +1 -0
- package/dist/chunks/{cli-module-ClIJmaT8.js → cli-module-Cx7qotPY.js} +16 -9
- package/dist/chunks/cli-module-Cx7qotPY.js.map +1 -0
- package/dist/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/exports.cjs +1 -1
- package/dist/exports.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +3 -3
- package/dist/styling.cjs +1 -1
- package/dist/styling.js +2 -2
- package/dist/terminal/formatter.d.ts.map +1 -1
- package/package.json +5 -1
- package/.claude/settings.local.json +0 -48
- package/.github/workflows/ci-quality.yml +0 -357
- package/.github/workflows/docs-demo.yml +0 -119
- package/.github/workflows/releases-core.yml +0 -512
- package/.github/workflows/releases-full.yml +0 -582
- package/.github/workflows-backup/ci.yml +0 -221
- package/.github/workflows-backup/nightly.yml +0 -196
- package/.github/workflows-backup/release-optimized.yml +0 -373
- package/.github/workflows-backup/release.yml +0 -269
- package/.release-notes-0.2.0.md +0 -129
- package/.yamllint +0 -28
- package/CHANGELOG.json +0 -1076
- package/CHANGELOG.md +0 -209
- package/CLAUDE.md +0 -217
- package/bun.lock +0 -333
- package/demo.html +0 -847
- package/dist/chunks/cli-module-CadqgZ1Z.js +0 -2
- package/dist/chunks/cli-module-CadqgZ1Z.js.map +0 -1
- package/dist/chunks/cli-module-ClIJmaT8.js.map +0 -1
- package/docs/API.md +0 -918
- package/docs/CORE.md +0 -264
- package/docs/DEVELOPMENT.md +0 -731
- package/docs/EXPORTS.md +0 -467
- package/docs/PACKAGES.md +0 -244
- package/docs/STYLING.md +0 -405
- package/docs/_config.yml +0 -36
- package/docs/index.md +0 -179
- package/examples/README.md +0 -208
- package/examples/basic-logging.js +0 -75
- package/examples/data-export.js +0 -234
- package/examples/package.json +0 -16
- package/examples/performance-timing.js +0 -170
- package/examples/simplified-api.js +0 -124
- package/examples/styling-themes.js +0 -207
- package/index.html +0 -358
- package/packages/core/package.json +0 -57
- package/packages/exports/package.json +0 -41
- package/packages/nodejs-opentui/README.md +0 -232
- package/packages/nodejs-opentui/package.json +0 -72
- package/packages/nodejs-opentui/src/LogRenderer.ts +0 -171
- package/packages/nodejs-opentui/src/OpenTUILogHandler.ts +0 -178
- package/packages/nodejs-opentui/src/components/LogBadge.tsx +0 -131
- package/packages/nodejs-opentui/src/index.ts +0 -133
- package/packages/nodejs-opentui/src/types.ts +0 -158
- package/packages/nodejs-opentui/tsconfig.json +0 -20
- package/packages/styling/package.json +0 -41
- package/playground/demo-all.ts +0 -95
- package/playground/demo-box.ts +0 -85
- package/playground/demo-levels.ts +0 -56
- package/playground/demo-real-world.ts +0 -98
- package/playground/demo-spinner.ts +0 -77
- package/playground/demo-steps.ts +0 -72
- package/playground/demo-table.ts +0 -83
- package/project-utils/README.md +0 -172
- package/project-utils/auto-release-gemini.ts +0 -1193
- package/project-utils/auto-release-ui.ts +0 -1329
- package/project-utils/commit-generator.ts +0 -1385
- package/project-utils/commit-ui.ts +0 -264
- package/project-utils/git-utils.ts +0 -199
- package/project-utils/github-release-manager.ts +0 -466
- package/project-utils/project-config.ts +0 -260
- package/project-utils/prompt-templates.js +0 -345
- package/project-utils/prompt-templates.ts +0 -422
- package/project-utils/version-manager.ts +0 -1078
- package/public/vite.svg +0 -1
- package/src/Logger.ts +0 -1858
- package/src/ScopedLogger.ts +0 -256
- package/src/cli/CommandProcessor.ts +0 -248
- package/src/cli/commands/ConfigCommand.ts +0 -93
- package/src/cli/commands/ExportCommand.ts +0 -276
- package/src/cli/commands/HistoryCommand.ts +0 -117
- package/src/cli/commands/StatusCommand.ts +0 -112
- package/src/cli/commands/ThemeCommand.ts +0 -88
- package/src/cli/help.ts +0 -127
- package/src/cli/index.ts +0 -71
- package/src/cli-module.ts +0 -21
- package/src/cli-primitives/box.ts +0 -86
- package/src/cli-primitives/cli-table.ts +0 -62
- package/src/cli-primitives/divider.ts +0 -17
- package/src/cli-primitives/header.ts +0 -18
- package/src/cli-primitives/index.ts +0 -13
- package/src/cli-primitives/server-fallback.ts +0 -54
- package/src/cli-primitives/spinner.ts +0 -133
- package/src/cli-primitives/step.ts +0 -22
- package/src/constants.ts +0 -313
- package/src/core.ts +0 -397
- package/src/example.ts +0 -210
- package/src/exports-module.ts +0 -311
- package/src/handlers/AnalyticsLogHandler.ts +0 -22
- package/src/handlers/ExportLogHandler.ts +0 -610
- package/src/handlers/FileLogHandler.ts +0 -169
- package/src/handlers/RemoteLogHandler.ts +0 -42
- package/src/handlers/index.ts +0 -8
- package/src/hooks/HookManager.ts +0 -177
- package/src/hooks/index.ts +0 -1
- package/src/index.ts +0 -395
- package/src/main.ts +0 -196
- package/src/serializers/SerializerRegistry.ts +0 -173
- package/src/serializers/index.ts +0 -1
- package/src/style.css +0 -96
- package/src/styling/LogStyleBuilder.ts +0 -355
- package/src/styling/SemanticStyles.ts +0 -380
- package/src/styling/SmartPresets.ts +0 -288
- package/src/styling/StyleBuilder.ts +0 -319
- package/src/styling/StyleCache.ts +0 -131
- package/src/styling/banners.ts +0 -168
- package/src/styling/index.ts +0 -27
- package/src/styling/themes.ts +0 -235
- package/src/styling-module.ts +0 -244
- package/src/terminal/color-converter.ts +0 -315
- package/src/terminal/formatter.ts +0 -236
- package/src/terminal/terminal-renderer.ts +0 -342
- package/src/transports/ConsoleTransport.ts +0 -28
- package/src/transports/FileTransport.ts +0 -53
- package/src/transports/HttpTransport.ts +0 -56
- package/src/transports/TransportManager.ts +0 -130
- package/src/transports/index.ts +0 -4
- package/src/types/core.ts +0 -417
- package/src/types/handlers.ts +0 -95
- package/src/types/hooks.ts +0 -45
- package/src/types/index.ts +0 -83
- package/src/types/serializers.ts +0 -30
- package/src/types/transports.ts +0 -52
- package/src/typescript.svg +0 -1
- package/src/utils/adapter.ts +0 -291
- package/src/utils/ansi-colors.ts +0 -333
- package/src/utils/environment-detector.ts +0 -170
- package/src/utils/environment.ts +0 -94
- package/src/utils/formatting.ts +0 -332
- package/src/utils/index.ts +0 -33
- package/src/utils/opentui-detection.ts +0 -138
- package/src/utils/output.ts +0 -227
- package/src/utils/stackTrace.ts +0 -144
- package/src/utils/timestamps.ts +0 -80
- package/src/vite-env.d.ts +0 -1
- package/src/writers/BufferWriter.ts +0 -157
- package/src/writers/index.ts +0 -6
- package/test-core-browser.html +0 -237
- package/test-core-node.js +0 -63
- package/tests/test-conflict-resolution.ts +0 -391
- package/tests/validate-workflows.sh +0 -131
- package/tests/yaml-autofix.sh +0 -146
- package/tsconfig.json +0 -50
- 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';
|