@mks2508/better-logger 0.18.2-alpha.1 → 0.18.2-alpha.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/README.md +38 -336
- package/dist/Logger.d.ts +243 -154
- package/dist/Logger.d.ts.map +1 -1
- package/dist/ScopedLogger.d.ts +511 -8
- package/dist/ScopedLogger.d.ts.map +1 -1
- package/dist/chunks/HookBridge-C-AvXmPD.cjs +504 -0
- package/dist/chunks/HookBridge-C-AvXmPD.cjs.map +1 -0
- package/dist/chunks/HookBridge-CI2PH79S.js +487 -0
- package/dist/chunks/HookBridge-CI2PH79S.js.map +1 -0
- package/dist/chunks/{LogContext-L7HzynFw.cjs → LogContext-BaMXleWj.cjs} +19 -4
- package/dist/chunks/LogContext-BaMXleWj.cjs.map +1 -0
- package/dist/chunks/{LogContext-Cwn-1Zzb.js → LogContext-DjlITOzZ.js} +19 -4
- package/dist/chunks/LogContext-DjlITOzZ.js.map +1 -0
- package/dist/chunks/SerializerBridge-Ba43Mk7j.js +393 -0
- package/dist/chunks/SerializerBridge-Ba43Mk7j.js.map +1 -0
- package/dist/chunks/SerializerBridge-C4a9Z37F.cjs +410 -0
- package/dist/chunks/SerializerBridge-C4a9Z37F.cjs.map +1 -0
- package/dist/chunks/{StyleManager-CIpd6wbO.cjs → StyleManager-DQ6UNRB-.cjs} +37 -11
- package/dist/chunks/StyleManager-DQ6UNRB-.cjs.map +1 -0
- package/dist/chunks/StyleManager-DjwAYbxE.js +113 -0
- package/dist/chunks/StyleManager-DjwAYbxE.js.map +1 -0
- package/dist/chunks/{core-PoT7RrTK.js → core-Blfi2klP.js} +1 -4
- package/dist/chunks/core-Blfi2klP.js.map +1 -0
- package/dist/chunks/{core-Dzz7agGa.cjs → core-CqS_UBzJ.cjs} +1 -4
- package/dist/chunks/core-CqS_UBzJ.cjs.map +1 -0
- package/dist/chunks/{environment-detector-CI3TrWK_.js → environment-detector-7NvnYUfr.js} +11 -11
- package/dist/chunks/environment-detector-7NvnYUfr.js.map +1 -0
- package/dist/chunks/{environment-detector-Cnn6wr6O.cjs → environment-detector-D-tHkKWA.cjs} +11 -11
- package/dist/chunks/environment-detector-D-tHkKWA.cjs.map +1 -0
- package/dist/chunks/server-fallback-CaCPjWby.cjs +119 -0
- package/dist/chunks/server-fallback-CaCPjWby.cjs.map +1 -0
- package/dist/chunks/server-fallback-jj0T6XaK.js +114 -0
- package/dist/chunks/server-fallback-jj0T6XaK.js.map +1 -0
- package/dist/chunks/{spinner-DNvxbM9a.cjs → spinner-BHyYEXsM.cjs} +319 -37
- package/dist/chunks/spinner-BHyYEXsM.cjs.map +1 -0
- package/dist/chunks/{spinner-D3FsF78o.js → spinner-BtkwpzYv.js} +319 -37
- package/dist/chunks/spinner-BtkwpzYv.js.map +1 -0
- package/dist/chunks/styling-CRw3KQW4.js +1592 -0
- package/dist/chunks/styling-CRw3KQW4.js.map +1 -0
- package/dist/chunks/styling-Cel2wPRy.cjs +1645 -0
- package/dist/chunks/styling-Cel2wPRy.cjs.map +1 -0
- package/dist/chunks/transports-BGfwwakw.js +1237 -0
- package/dist/chunks/transports-BGfwwakw.js.map +1 -0
- package/dist/chunks/transports-yK6CL0Ml.cjs +1278 -0
- package/dist/chunks/transports-yK6CL0Ml.cjs.map +1 -0
- package/dist/chunks/{utils-BqlFYocD.cjs → utils-W_cxqriN.cjs} +44 -37
- package/dist/chunks/utils-W_cxqriN.cjs.map +1 -0
- package/dist/chunks/{utils-VETbVpkR.js → utils-tKfBAWUM.js} +44 -37
- package/dist/chunks/utils-tKfBAWUM.js.map +1 -0
- package/dist/cli/CommandProcessor.d.ts +166 -19
- package/dist/cli/CommandProcessor.d.ts.map +1 -1
- package/dist/cli/commands/ConfigCommand.d.ts +36 -1
- package/dist/cli/commands/ConfigCommand.d.ts.map +1 -1
- package/dist/cli/commands/ExportCommand.d.ts +49 -3
- package/dist/cli/commands/ExportCommand.d.ts.map +1 -1
- package/dist/cli/commands/ThemeCommand.d.ts +62 -3
- package/dist/cli/commands/ThemeCommand.d.ts.map +1 -1
- package/dist/cli/help.d.ts +30 -2
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/index.d.ts +29 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.cjs +2 -2
- package/dist/cli.js +2 -2
- package/dist/context/LogContext.d.ts +165 -66
- package/dist/context/LogContext.d.ts.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.js +1 -1
- package/dist/core.cjs +52 -29
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +50 -27
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +52 -29
- package/dist/core.js.map +1 -1
- package/dist/hooks/HookBridge.d.ts +15 -9
- package/dist/hooks/HookBridge.d.ts.map +1 -1
- package/dist/hooks/HookManager.d.ts +295 -2
- package/dist/hooks/HookManager.d.ts.map +1 -1
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.js +1 -1
- package/dist/index.cjs +1092 -212
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1092 -212
- package/dist/index.js.map +1 -1
- package/dist/playground/TerminalBridge.d.ts +23 -16
- package/dist/playground/TerminalBridge.d.ts.map +1 -1
- package/dist/playground/box.d.ts +36 -5
- package/dist/playground/box.d.ts.map +1 -1
- package/dist/playground/cli-table.d.ts +41 -5
- package/dist/playground/cli-table.d.ts.map +1 -1
- package/dist/playground/divider.d.ts +22 -3
- package/dist/playground/divider.d.ts.map +1 -1
- package/dist/playground/header.d.ts +21 -4
- package/dist/playground/header.d.ts.map +1 -1
- package/dist/playground/server-fallback.d.ts +96 -9
- package/dist/playground/server-fallback.d.ts.map +1 -1
- package/dist/playground/spinner.d.ts +159 -10
- package/dist/playground/spinner.d.ts.map +1 -1
- package/dist/playground/step.d.ts +25 -6
- package/dist/playground/step.d.ts.map +1 -1
- package/dist/playground.cjs +1 -1
- package/dist/playground.js +1 -1
- package/dist/serializers/SerializerBridge.d.ts +13 -6
- package/dist/serializers/SerializerBridge.d.ts.map +1 -1
- package/dist/serializers/SerializerRegistry.d.ts +236 -0
- package/dist/serializers/SerializerRegistry.d.ts.map +1 -1
- package/dist/serializers.cjs +1 -1
- package/dist/serializers.js +1 -1
- package/dist/styles/StyleManager.d.ts +138 -31
- package/dist/styles/StyleManager.d.ts.map +1 -1
- package/dist/styles.cjs +2 -2
- package/dist/styles.js +2 -2
- package/dist/styling/SmartPresets.d.ts +100 -6
- package/dist/styling/SmartPresets.d.ts.map +1 -1
- package/dist/styling/StyleBuilder.d.ts +453 -32
- package/dist/styling/StyleBuilder.d.ts.map +1 -1
- package/dist/styling/banners.d.ts +83 -7
- package/dist/styling/banners.d.ts.map +1 -1
- package/dist/styling/themes.d.ts +41 -2
- package/dist/styling/themes.d.ts.map +1 -1
- package/dist/transports/ConsoleTransport.d.ts +95 -0
- package/dist/transports/ConsoleTransport.d.ts.map +1 -1
- package/dist/transports/FileTransport.d.ts +99 -18
- package/dist/transports/FileTransport.d.ts.map +1 -1
- package/dist/transports/HttpTransport.d.ts +135 -22
- package/dist/transports/HttpTransport.d.ts.map +1 -1
- package/dist/transports/OtlpTransport.d.ts +53 -36
- package/dist/transports/OtlpTransport.d.ts.map +1 -1
- package/dist/transports/TransportBridge.d.ts +19 -13
- package/dist/transports/TransportBridge.d.ts.map +1 -1
- package/dist/transports/TransportManager.d.ts +223 -8
- package/dist/transports/TransportManager.d.ts.map +1 -1
- package/dist/transports.cjs +1 -1
- package/dist/transports.js +1 -1
- package/dist/types/core.d.ts +155 -59
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +92 -14
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/serializers.d.ts +72 -0
- package/dist/types/serializers.d.ts.map +1 -1
- package/dist/types/transports.d.ts +42 -37
- package/dist/types/transports.d.ts.map +1 -1
- package/dist/utils/ansi-colors.d.ts +15 -15
- package/dist/utils/environment-detector.d.ts +11 -11
- package/dist/utils/formatting.d.ts +8 -8
- package/dist/utils/output.d.ts +9 -9
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/stackTrace.d.ts +2 -2
- package/package.json +24 -25
- package/dist/chunks/HookBridge-CiRfR67f.cjs +0 -190
- package/dist/chunks/HookBridge-CiRfR67f.cjs.map +0 -1
- package/dist/chunks/HookBridge-SgMmbXZB.js +0 -173
- package/dist/chunks/HookBridge-SgMmbXZB.js.map +0 -1
- package/dist/chunks/LogContext-Cwn-1Zzb.js.map +0 -1
- package/dist/chunks/LogContext-L7HzynFw.cjs.map +0 -1
- package/dist/chunks/SerializerBridge-BaOQOb8q.cjs +0 -166
- package/dist/chunks/SerializerBridge-BaOQOb8q.cjs.map +0 -1
- package/dist/chunks/SerializerBridge-BkpQu5c9.js +0 -149
- package/dist/chunks/SerializerBridge-BkpQu5c9.js.map +0 -1
- package/dist/chunks/StyleManager-CIpd6wbO.cjs.map +0 -1
- package/dist/chunks/StyleManager-LCvVlVdx.js +0 -87
- package/dist/chunks/StyleManager-LCvVlVdx.js.map +0 -1
- package/dist/chunks/core-Dzz7agGa.cjs.map +0 -1
- package/dist/chunks/core-PoT7RrTK.js.map +0 -1
- package/dist/chunks/environment-detector-CI3TrWK_.js.map +0 -1
- package/dist/chunks/environment-detector-Cnn6wr6O.cjs.map +0 -1
- package/dist/chunks/server-fallback-BUKjdLS7.cjs +0 -42
- package/dist/chunks/server-fallback-BUKjdLS7.cjs.map +0 -1
- package/dist/chunks/server-fallback-BsuWH1Dk.js +0 -37
- package/dist/chunks/server-fallback-BsuWH1Dk.js.map +0 -1
- package/dist/chunks/spinner-D3FsF78o.js.map +0 -1
- package/dist/chunks/spinner-DNvxbM9a.cjs.map +0 -1
- package/dist/chunks/styling-84N8T97t.js +0 -941
- package/dist/chunks/styling-84N8T97t.js.map +0 -1
- package/dist/chunks/styling-Cg5saQ46.cjs +0 -994
- package/dist/chunks/styling-Cg5saQ46.cjs.map +0 -1
- package/dist/chunks/transports-BiDk345e.js +0 -715
- package/dist/chunks/transports-BiDk345e.js.map +0 -1
- package/dist/chunks/transports-COPWmlF1.cjs +0 -756
- package/dist/chunks/transports-COPWmlF1.cjs.map +0 -1
- package/dist/chunks/utils-BqlFYocD.cjs.map +0 -1
- package/dist/chunks/utils-VETbVpkR.js.map +0 -1
- package/dist/example.d.ts +0 -18
- package/dist/example.d.ts.map +0 -1
- package/dist/main.d.ts +0 -2
- package/dist/main.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,21 +1,61 @@
|
|
|
1
|
-
import { t as LOG_LEVELS } from "./chunks/core-
|
|
2
|
-
import { o as LOG_LEVEL_TO_SEVERITY_NUMBER, s as LOG_LEVEL_TO_SEVERITY_TEXT, t as TransportManager } from "./chunks/transports-
|
|
3
|
-
import { _ as DEFAULT_CONFIG, a as safeSerialize, b as parseStackTrace, c as ansiBackground, d as ansiDim, f as ansiStyle, g as CLI_LEVEL_MAP, h as formatSuccessANSI, i as getConsoleMethod, l as ansiBold, m as formatLogLevelANSI, o as createStyledOutput, p as ansiUnderline, r as formatTablePlain, s as setupThemeChangeListener, t as createLogEntry, u as ansiColor, y as formatTimestamp } from "./chunks/utils-
|
|
4
|
-
import { a as THEME_BANNERS, c as StyleBuilder, i as BANNER_VARIANTS, l as StylePresets, n as getSmartPreset, o as displayInitBanner, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./chunks/styling-
|
|
5
|
-
import { a as getTerminalWidth, c as isRunningInTerminal, i as getTerminalHeight, l as supportsANSI, n as getEnvironment, r as getEnvironmentInfo, t as getColorCapability } from "./chunks/environment-detector-
|
|
6
|
-
import { a as renderDivider, c as formatBadge, i as renderBox, n as SpinnerManager, o as renderHeader, r as renderTable, s as renderStep, t as NoopSpinner } from "./chunks/spinner-
|
|
7
|
-
import { t as createLogContext } from "./chunks/LogContext-
|
|
8
|
-
import { t as createHookBridge } from "./chunks/HookBridge-
|
|
9
|
-
import { t as createSerializerBridge } from "./chunks/SerializerBridge-
|
|
10
|
-
import { t as ServerFallback } from "./chunks/server-fallback-
|
|
11
|
-
import { t as createStyleManager } from "./chunks/StyleManager-
|
|
1
|
+
import { t as LOG_LEVELS } from "./chunks/core-Blfi2klP.js";
|
|
2
|
+
import { o as LOG_LEVEL_TO_SEVERITY_NUMBER, s as LOG_LEVEL_TO_SEVERITY_TEXT, t as TransportManager } from "./chunks/transports-BGfwwakw.js";
|
|
3
|
+
import { _ as DEFAULT_CONFIG, a as safeSerialize, b as parseStackTrace, c as ansiBackground, d as ansiDim, f as ansiStyle, g as CLI_LEVEL_MAP, h as formatSuccessANSI, i as getConsoleMethod, l as ansiBold, m as formatLogLevelANSI, o as createStyledOutput, p as ansiUnderline, r as formatTablePlain, s as setupThemeChangeListener, t as createLogEntry, u as ansiColor, y as formatTimestamp } from "./chunks/utils-tKfBAWUM.js";
|
|
4
|
+
import { a as THEME_BANNERS, c as StyleBuilder, i as BANNER_VARIANTS, l as StylePresets, n as getSmartPreset, o as displayInitBanner, r as hasPreset, s as THEME_PRESETS, t as getAvailablePresets } from "./chunks/styling-CRw3KQW4.js";
|
|
5
|
+
import { a as getTerminalWidth, c as isRunningInTerminal, i as getTerminalHeight, l as supportsANSI, n as getEnvironment, r as getEnvironmentInfo, t as getColorCapability } from "./chunks/environment-detector-7NvnYUfr.js";
|
|
6
|
+
import { a as renderDivider, c as formatBadge, i as renderBox, n as SpinnerManager, o as renderHeader, r as renderTable, s as renderStep, t as NoopSpinner } from "./chunks/spinner-BtkwpzYv.js";
|
|
7
|
+
import { t as createLogContext } from "./chunks/LogContext-DjlITOzZ.js";
|
|
8
|
+
import { t as createHookBridge } from "./chunks/HookBridge-CI2PH79S.js";
|
|
9
|
+
import { t as createSerializerBridge } from "./chunks/SerializerBridge-Ba43Mk7j.js";
|
|
10
|
+
import { t as ServerFallback } from "./chunks/server-fallback-jj0T6XaK.js";
|
|
11
|
+
import { t as createStyleManager } from "./chunks/StyleManager-DjwAYbxE.js";
|
|
12
12
|
//#region src/ScopedLogger.ts
|
|
13
|
+
/**
|
|
14
|
+
* Logger prefijado por un scope nominal. Mantiene su propio stack de badges
|
|
15
|
+
* y contextos y delega el envío de mensajes al {@link Logger} padre a través
|
|
16
|
+
* de bindings (`{ scope, badges }`).
|
|
17
|
+
*
|
|
18
|
+
* Es la base de la jerarquía temática: {@link APILogger} y
|
|
19
|
+
* {@link ComponentLogger} extienden de ella, y {@link ContextLogger} la
|
|
20
|
+
* consume para apilar/subdesapilar sub-prefijos en el scope.
|
|
21
|
+
*
|
|
22
|
+
* No se construye directamente: se obtiene con `logger.scope('name')`.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // El factory method del Logger raíz devuelve un ScopedLogger
|
|
26
|
+
* import logger from '@mks2508/better-logger';
|
|
27
|
+
*
|
|
28
|
+
* const http = logger.scope('HTTP');
|
|
29
|
+
* http.badge('OUTBOUND').info('Request enviada');
|
|
30
|
+
* // salida: [HTTP] [OUTBOUND] Request enviada
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* // Anidar contextos dentro de un scope (el prefijo se compone con ':')
|
|
34
|
+
* const retry = http.context('retry');
|
|
35
|
+
* retry.run(() => http.warn('Reintentando petición'));
|
|
36
|
+
* // salida: [HTTP:retry] Reintentando petición
|
|
37
|
+
*
|
|
38
|
+
* @see {@link Logger.scope}
|
|
39
|
+
* @see {@link APILogger}
|
|
40
|
+
* @see {@link ComponentLogger}
|
|
41
|
+
* @see {@link ContextLogger}
|
|
42
|
+
*/
|
|
13
43
|
var ScopedLogger = class {
|
|
14
44
|
parent;
|
|
15
45
|
scopeName;
|
|
16
46
|
badgeList = [];
|
|
17
47
|
contextStack = [];
|
|
18
48
|
_timers;
|
|
49
|
+
/**
|
|
50
|
+
* Construye un ScopedLogger vinculado a un {@link Logger} padre.
|
|
51
|
+
*
|
|
52
|
+
* Los clientes no deben llamar a este constructor directamente: usen
|
|
53
|
+
* `logger.scope(name)`, que configura correctamente la instancia.
|
|
54
|
+
*
|
|
55
|
+
* @param {Logger} parent - Logger raíz al que se delegan los mensajes.
|
|
56
|
+
* @param {string} scopeName - Etiqueta del scope; se renderiza como
|
|
57
|
+
* prefijo `[scopeName]` en cada línea.
|
|
58
|
+
*/
|
|
19
59
|
constructor(parent, scopeName) {
|
|
20
60
|
this.parent = parent;
|
|
21
61
|
this.scopeName = scopeName;
|
|
@@ -34,31 +74,125 @@ var ScopedLogger = class {
|
|
|
34
74
|
if (this.contextStack.length === 0) return this.scopeName;
|
|
35
75
|
return [this.scopeName, ...this.contextStack].join(":");
|
|
36
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Reemplaza la lista actual de badges por la pasada y la aplica a todos
|
|
79
|
+
* los mensajes posteriores de este scope.
|
|
80
|
+
*
|
|
81
|
+
* @param {string[]} badges - Etiquetas a mostrar como badges adyacentes
|
|
82
|
+
* al prefijo (p. ej. `['OUTBOUND', 'CACHED']`).
|
|
83
|
+
* @returns {this} La misma instancia, para encadenar llamadas.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* logger.scope('HTTP').badges(['OUTBOUND', 'CACHED']).info('Cache hit');
|
|
87
|
+
* // salida: [HTTP] [OUTBOUND] [CACHED] Cache hit
|
|
88
|
+
*
|
|
89
|
+
* @see {@link badge} para añadir sin reemplazar los existentes.
|
|
90
|
+
* @see {@link clearBadges} para vaciar la lista.
|
|
91
|
+
*/
|
|
37
92
|
badges(badges) {
|
|
38
93
|
this.badgeList = [...badges];
|
|
39
94
|
return this;
|
|
40
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Añade un badge al scope de forma idempotente (no lo duplica si ya existe).
|
|
98
|
+
*
|
|
99
|
+
* @param {string} badge - Etiqueta a añadir a la lista de badges.
|
|
100
|
+
* @returns {this} La misma instancia, para encadenar llamadas.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* logger.scope('API')
|
|
104
|
+
* .badge('OUTBOUND')
|
|
105
|
+
* .badge('RETRY')
|
|
106
|
+
* .warn('Reintentando');
|
|
107
|
+
* // salida: [API] [OUTBOUND] [RETRY] Reintentando
|
|
108
|
+
*/
|
|
41
109
|
badge(badge) {
|
|
42
110
|
if (!this.badgeList.includes(badge)) this.badgeList.push(badge);
|
|
43
111
|
return this;
|
|
44
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Vacía la lista de badges del scope.
|
|
115
|
+
*
|
|
116
|
+
* @returns {this} La misma instancia, para encadenar llamadas.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* const http = logger.scope('HTTP');
|
|
120
|
+
* http.badge('OUTBOUND').info('uno');
|
|
121
|
+
* http.clearBadges().info('dos');
|
|
122
|
+
* // [HTTP] [OUTBOUND] uno / [HTTP] dos
|
|
123
|
+
*/
|
|
45
124
|
clearBadges() {
|
|
46
125
|
this.badgeList = [];
|
|
47
126
|
return this;
|
|
48
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Aplica un theme preset al logger padre. El preset afecta a toda la
|
|
130
|
+
* instancia raíz (no solo a este scope) porque el style es compartido.
|
|
131
|
+
*
|
|
132
|
+
* @param {string} presetName - Nombre del preset registrado en el StyleManager.
|
|
133
|
+
* @returns {this} La misma instancia, para encadenar llamadas.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* logger.scope('UI').style('cyberpunk').info('neon');
|
|
137
|
+
* @see {@link Logger.setTheme}
|
|
138
|
+
*/
|
|
49
139
|
style(presetName) {
|
|
50
140
|
this.parent.setTheme(presetName);
|
|
51
141
|
return this;
|
|
52
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Crea un {@link ContextLogger} vinculado a este scope. Los contextos se
|
|
145
|
+
* apilan en el prefijo separados por `:`, permitiendo agrupar bloques de
|
|
146
|
+
* logs relacionados (reintentos, sub-etapas, etc.) sin `console.group`.
|
|
147
|
+
*
|
|
148
|
+
* @param {string} contextName - Nombre del contexto a apilar.
|
|
149
|
+
* @returns {ContextLogger} Handler con `run`, `runAsync`, `start`/`end`.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* const retry = logger.scope('HTTP').context('retry');
|
|
153
|
+
* retry.run(() => logger.warn('Reintentando'));
|
|
154
|
+
* // salida: [HTTP:retry] Reintentando
|
|
155
|
+
* @see {@link ContextLogger}
|
|
156
|
+
*/
|
|
53
157
|
context(contextName) {
|
|
54
158
|
return new ContextLogger(this, contextName);
|
|
55
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Inicia un timer etiquetado bajo el namespace `<scopeName>:<label>`.
|
|
162
|
+
* El label es local a este scope, así que dos scopes pueden reutilizar el
|
|
163
|
+
* mismo nombre sin colisión.
|
|
164
|
+
*
|
|
165
|
+
* @param {string} label - Identificador del timer.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* const http = logger.scope('HTTP');
|
|
169
|
+
* http.time('request');
|
|
170
|
+
* // ... trabajo ...
|
|
171
|
+
* http.timeEnd('request'); // imprime "Timer: request - 12.34ms"
|
|
172
|
+
* @see {@link timeEnd}
|
|
173
|
+
*/
|
|
56
174
|
time(label) {
|
|
57
175
|
this.timers.set(label, {
|
|
58
176
|
label: `${this.scopeName}:${label}`,
|
|
59
177
|
startTime: performance.now()
|
|
60
178
|
});
|
|
61
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Detiene un timer previamente iniciado con {@link time} y registra la
|
|
182
|
+
* duración con nivel `success`. Si el label no existe, emite un `warn`
|
|
183
|
+
* y devuelve `undefined`.
|
|
184
|
+
*
|
|
185
|
+
* @param {string} label - Mismo label pasado a {@link time}.
|
|
186
|
+
* @returns {number | undefined} Milisegundos transcurridos, o `undefined`
|
|
187
|
+
* si el timer no estaba registrado.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* const http = logger.scope('HTTP');
|
|
191
|
+
* http.time('fetch');
|
|
192
|
+
* await fetch(url);
|
|
193
|
+
* const ms = http.timeEnd('fetch');
|
|
194
|
+
* if (ms && ms > 1000) http.warn('Latencia alta');
|
|
195
|
+
*/
|
|
62
196
|
timeEnd(label) {
|
|
63
197
|
const timer = this.timers.get(label);
|
|
64
198
|
if (!timer) {
|
|
@@ -70,118 +204,419 @@ var ScopedLogger = class {
|
|
|
70
204
|
this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);
|
|
71
205
|
return elapsed;
|
|
72
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Emite un mensaje a nivel `debug` con los bindings actuales del scope.
|
|
209
|
+
*
|
|
210
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales (objetos,
|
|
211
|
+
* errores, etc.) serializados igual que en el logger raíz.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* logger.scope('DB').debug('query', { sql, params });
|
|
215
|
+
*/
|
|
73
216
|
debug(...args) {
|
|
74
217
|
this.parent.logWithBindings(this.getBindings(), "debug", ...args);
|
|
75
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Emite un mensaje a nivel `info` con los bindings actuales del scope.
|
|
221
|
+
*
|
|
222
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* logger.scope('AUTH').info('Login exitoso', { userId });
|
|
226
|
+
*/
|
|
76
227
|
info(...args) {
|
|
77
228
|
this.parent.logWithBindings(this.getBindings(), "info", ...args);
|
|
78
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Emite un mensaje a nivel `warn` con los bindings actuales del scope.
|
|
232
|
+
*
|
|
233
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* logger.scope('CACHE').warn('Cache miss', { key });
|
|
237
|
+
*/
|
|
79
238
|
warn(...args) {
|
|
80
239
|
this.parent.logWithBindings(this.getBindings(), "warn", ...args);
|
|
81
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Emite un mensaje a nivel `error` con los bindings actuales del scope.
|
|
243
|
+
*
|
|
244
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales (típicamente
|
|
245
|
+
* un `Error` o contexto del fallo).
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* logger.scope('DB').error('Conexión rechazada', err);
|
|
249
|
+
*/
|
|
82
250
|
error(...args) {
|
|
83
251
|
this.parent.logWithBindings(this.getBindings(), "error", ...args);
|
|
84
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Emite un mensaje con badge visual `SUCCESS` a nivel `info`. Úselo para
|
|
255
|
+
* hitos positivos dentro del scope (conexión establecida, sync completo,
|
|
256
|
+
* commit aplicado).
|
|
257
|
+
*
|
|
258
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* logger.scope('SYNC').success('Sincronización completa', { count: 42 });
|
|
262
|
+
*/
|
|
85
263
|
success(...args) {
|
|
86
264
|
const bindings = this.getBindings();
|
|
87
265
|
this.parent.logWithBindingsAndTag(bindings, "info", "success", ...args);
|
|
88
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Emite un mensaje a nivel `critical` con los bindings actuales del scope.
|
|
269
|
+
* Reservado para fallos que detienen el flujo de la aplicación.
|
|
270
|
+
*
|
|
271
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* logger.scope('PAY').critical('Pasarela inaccesible', err);
|
|
275
|
+
*/
|
|
89
276
|
critical(...args) {
|
|
90
277
|
this.parent.logWithBindings(this.getBindings(), "critical", ...args);
|
|
91
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Emite un mensaje a nivel `trace` (verbosidad máxima) con los bindings
|
|
281
|
+
* actuales del scope. Solo aparece si la verbosity global lo permite.
|
|
282
|
+
*
|
|
283
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* logger.scope('NET').trace('packet', { bytes });
|
|
287
|
+
*/
|
|
92
288
|
trace(...args) {
|
|
93
289
|
this.parent.logWithBindings(this.getBindings(), "trace", ...args);
|
|
94
290
|
}
|
|
95
|
-
/**
|
|
291
|
+
/**
|
|
292
|
+
* Delegación a {@link Logger.step}: dibuja una barra de progreso discreta
|
|
293
|
+
* `current/total` para este scope.
|
|
294
|
+
*
|
|
295
|
+
* @param {number} current - Paso actual (1-indexed).
|
|
296
|
+
* @param {number} total - Total de pasos.
|
|
297
|
+
* @param {string} message - Texto mostrado junto al contador.
|
|
298
|
+
* @see {@link Logger.step}
|
|
299
|
+
*/
|
|
96
300
|
step(current, total, message) {
|
|
97
301
|
this.parent.step(current, total, message);
|
|
98
302
|
}
|
|
99
|
-
/**
|
|
303
|
+
/**
|
|
304
|
+
* Delegación a {@link Logger.header}: imprime un título con separadores visuales.
|
|
305
|
+
*
|
|
306
|
+
* @param {string} title - Texto del título.
|
|
307
|
+
* @param {string} [subtitle] - Subtítulo opcional bajo el título.
|
|
308
|
+
* @see {@link Logger.header}
|
|
309
|
+
*/
|
|
100
310
|
header(title, subtitle) {
|
|
101
311
|
this.parent.header(title, subtitle);
|
|
102
312
|
}
|
|
103
|
-
/**
|
|
313
|
+
/**
|
|
314
|
+
* Delegación a {@link Logger.divider}: imprime una línea separadora horizontal.
|
|
315
|
+
* @see {@link Logger.divider}
|
|
316
|
+
*/
|
|
104
317
|
divider() {
|
|
105
318
|
this.parent.divider();
|
|
106
319
|
}
|
|
107
|
-
/**
|
|
320
|
+
/**
|
|
321
|
+
* Delegación a {@link Logger.blank}: inserta una línea en blanco.
|
|
322
|
+
* @see {@link Logger.blank}
|
|
323
|
+
*/
|
|
108
324
|
blank() {
|
|
109
325
|
this.parent.blank();
|
|
110
326
|
}
|
|
111
|
-
/**
|
|
327
|
+
/**
|
|
328
|
+
* Delegación a {@link Logger.box}: dibuja un recuadro ANSI alrededor de `content`.
|
|
329
|
+
*
|
|
330
|
+
* @param {string} content - Texto a enmarcar.
|
|
331
|
+
* @param {IBoxOptions} [options] - Opciones de estilo del box.
|
|
332
|
+
* @see {@link Logger.box}
|
|
333
|
+
*/
|
|
112
334
|
box(content, options) {
|
|
113
335
|
this.parent.box(content, options);
|
|
114
336
|
}
|
|
115
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* Delegación a {@link Logger.cliTable}: renderiza `rows` como tabla ASCII.
|
|
339
|
+
*
|
|
340
|
+
* @param {Record<string, unknown>[]} rows - Filas a mostrar.
|
|
341
|
+
* @param {ITableOptions} [options] - Opciones de columnas y estilo.
|
|
342
|
+
* @see {@link Logger.cliTable}
|
|
343
|
+
*/
|
|
116
344
|
cliTable(rows, options) {
|
|
117
345
|
this.parent.cliTable(rows, options);
|
|
118
346
|
}
|
|
119
|
-
/**
|
|
347
|
+
/**
|
|
348
|
+
* Delegación a {@link Logger.spinner}: arranca un spinner con `message`.
|
|
349
|
+
*
|
|
350
|
+
* @param {string} message - Texto a mostrar al lado del spinner.
|
|
351
|
+
* @returns {ISpinnerHandle} Handle para detener/actualizar el spinner.
|
|
352
|
+
* @see {@link Logger.spinner}
|
|
353
|
+
*/
|
|
120
354
|
spinner(message) {
|
|
121
355
|
return this.parent.spinner(message);
|
|
122
356
|
}
|
|
123
|
-
/**
|
|
357
|
+
/**
|
|
358
|
+
* Delegación a {@link Logger.setCLILevel}: ajusta el nivel mínimo de las
|
|
359
|
+
* primitivas CLI visibles.
|
|
360
|
+
*
|
|
361
|
+
* @param {CLILogLevel} level - Nivel CLI (`silent` … `verbose`).
|
|
362
|
+
* @see {@link Logger.setCLILevel}
|
|
363
|
+
*/
|
|
124
364
|
setCLILevel(level) {
|
|
125
365
|
this.parent.setCLILevel(level);
|
|
126
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Apila un contexto en el prefijo del scope. Invocado por
|
|
369
|
+
* {@link ContextLogger}; los clientes no deben llamarlo directamente.
|
|
370
|
+
*
|
|
371
|
+
* @param {string} context - Nombre del contexto a apilar.
|
|
372
|
+
* @internal
|
|
373
|
+
*/
|
|
127
374
|
_pushContext(context) {
|
|
128
375
|
this.contextStack.push(context);
|
|
129
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Desapila el último contexto del prefijo del scope. Invocado por
|
|
379
|
+
* {@link ContextLogger}; los clientes no deben llamarlo directamente.
|
|
380
|
+
*
|
|
381
|
+
* @internal
|
|
382
|
+
*/
|
|
130
383
|
_popContext() {
|
|
131
384
|
this.contextStack.pop();
|
|
132
385
|
}
|
|
133
386
|
};
|
|
387
|
+
/**
|
|
388
|
+
* Logger especializado para llamadas a APIs y servicios externos.
|
|
389
|
+
*
|
|
390
|
+
* Extiende {@link ScopedLogger} pre-seteando el badge `API` y exponiendo
|
|
391
|
+
* atajos para eventos típicos de integración: llamadas lentas ({@link slow}),
|
|
392
|
+
* rate limiting ({@link rateLimit}), fallos de autenticación ({@link auth}) y
|
|
393
|
+
* APIs deprecadas ({@link deprecated}).
|
|
394
|
+
*
|
|
395
|
+
* Se obtiene con `logger.api(name)` y no se construye directamente.
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* import logger from '@mks2508/better-logger';
|
|
399
|
+
*
|
|
400
|
+
* const stripe = logger.api('Stripe');
|
|
401
|
+
* stripe.info('Consultando customer', { id });
|
|
402
|
+
* // salida: [API:Stripe] [API] Consultando customer
|
|
403
|
+
*
|
|
404
|
+
* stripe.slow('customer.retrieve', 1250);
|
|
405
|
+
* // salida: [API:Stripe] [API] [SLOW] customer.retrieve (1250ms)
|
|
406
|
+
*
|
|
407
|
+
* @see {@link Logger.api}
|
|
408
|
+
* @see {@link ScopedLogger}
|
|
409
|
+
*/
|
|
134
410
|
var APILogger = class extends ScopedLogger {
|
|
411
|
+
/**
|
|
412
|
+
* Construye un APILogger con scope `API:<apiName>` y badge `API` ya aplicado.
|
|
413
|
+
*
|
|
414
|
+
* Los clientes deben usar `logger.api(name)`.
|
|
415
|
+
*
|
|
416
|
+
* @param {Logger} parent - Logger raíz al que se delegan los mensajes.
|
|
417
|
+
* @param {string} apiName - Nombre del servicio/API (se prefija con `API:`).
|
|
418
|
+
*/
|
|
135
419
|
constructor(parent, apiName) {
|
|
136
420
|
super(parent, `API:${apiName}`);
|
|
137
421
|
this.badge("API");
|
|
138
422
|
}
|
|
423
|
+
/**
|
|
424
|
+
* Registra una llamada lenta con badge `SLOW` a nivel `warn`.
|
|
425
|
+
*
|
|
426
|
+
* @param {string} message - Descripción de la operación lenta.
|
|
427
|
+
* @param {number} [duration] - Duración medida en ms; si se pasa, se
|
|
428
|
+
* anexa al mensaje como `(Nms)`.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* const t0 = performance.now();
|
|
432
|
+
* await stripe.customers.retrieve(id);
|
|
433
|
+
* logger.api('Stripe').slow('retrieve', performance.now() - t0);
|
|
434
|
+
*/
|
|
139
435
|
slow(message, duration) {
|
|
140
436
|
this.badge("SLOW");
|
|
141
437
|
const msg = duration ? `${message} (${duration}ms)` : message;
|
|
142
438
|
this.warn(msg);
|
|
143
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* Registra un evento de rate limiting (HTTP 429) con badge `RATE_LIMIT`.
|
|
442
|
+
*
|
|
443
|
+
* @param {string} message - Detalle del límite golpeado.
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* logger.api('GitHub').rateLimit('Secondary rate limit on /search');
|
|
447
|
+
*/
|
|
144
448
|
rateLimit(message) {
|
|
145
449
|
this.badge("RATE_LIMIT");
|
|
146
450
|
this.warn(message);
|
|
147
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* Registra un fallo de autenticación (401/403) con badge `AUTH` a nivel
|
|
454
|
+
* `error`.
|
|
455
|
+
*
|
|
456
|
+
* @param {string} message - Detalle del fallo de credenciales/token.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* logger.api('OAuth').auth('Token expirado');
|
|
460
|
+
*/
|
|
148
461
|
auth(message) {
|
|
149
462
|
this.badge("AUTH");
|
|
150
463
|
this.error(message);
|
|
151
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Marca una API como deprecada con badge `DEPRECATED` a nivel `warn`.
|
|
467
|
+
*
|
|
468
|
+
* @param {string} message - Mensaje guiando a la migración (endpoint
|
|
469
|
+
* alternativo, versión retirada, etc.).
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* logger.api('Legacy').deprecated('Usar v3; v2 se retira en Q4');
|
|
473
|
+
*/
|
|
152
474
|
deprecated(message) {
|
|
153
475
|
this.badge("DEPRECATED");
|
|
154
476
|
this.warn(message);
|
|
155
477
|
}
|
|
156
478
|
};
|
|
479
|
+
/**
|
|
480
|
+
* Logger para componentes UI, módulos o cualquier unidad con ciclo de vida.
|
|
481
|
+
*
|
|
482
|
+
* Extiende {@link ScopedLogger} pre-seteando el badge `COMPONENT` y exponiendo
|
|
483
|
+
* atajos para eventos típicos: {@link lifecycle}, {@link stateChange} y
|
|
484
|
+
* {@link propsChange}.
|
|
485
|
+
*
|
|
486
|
+
* Se obtiene con `logger.component(name)` y no se construye directamente.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* import logger from '@mks2508/better-logger';
|
|
490
|
+
*
|
|
491
|
+
* const cart = logger.component('Cart');
|
|
492
|
+
* cart.lifecycle('mount');
|
|
493
|
+
* // salida: [Cart] [COMPONENT] [LIFECYCLE] mount
|
|
494
|
+
*
|
|
495
|
+
* cart.stateChange('empty', 'has-items', { count: 3 });
|
|
496
|
+
* // salida: [Cart] [COMPONENT] [STATE] empty → has-items { count: 3 }
|
|
497
|
+
*
|
|
498
|
+
* @see {@link Logger.component}
|
|
499
|
+
* @see {@link ScopedLogger}
|
|
500
|
+
*/
|
|
157
501
|
var ComponentLogger = class extends ScopedLogger {
|
|
502
|
+
/**
|
|
503
|
+
* Construye un ComponentLogger con badge `COMPONENT` ya aplicado.
|
|
504
|
+
*
|
|
505
|
+
* Los clientes deben usar `logger.component(name)`.
|
|
506
|
+
*
|
|
507
|
+
* @param {Logger} parent - Logger raíz al que se delegan los mensajes.
|
|
508
|
+
* @param {string} componentName - Nombre del componente (scope label).
|
|
509
|
+
*/
|
|
158
510
|
constructor(parent, componentName) {
|
|
159
511
|
super(parent, componentName);
|
|
160
512
|
this.badge("COMPONENT");
|
|
161
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Registra un evento de ciclo de vida con badge `LIFECYCLE` a nivel `info`.
|
|
516
|
+
*
|
|
517
|
+
* @param {string} event - Nombre del evento (`mount`, `unmount`,
|
|
518
|
+
* `update`, ...).
|
|
519
|
+
* @param {string} [message] - Detalle opcional; si se omite, solo se
|
|
520
|
+
* registra el nombre del evento.
|
|
521
|
+
*
|
|
522
|
+
* @example
|
|
523
|
+
* logger.component('Cart').lifecycle('mount', 'Modal abierto');
|
|
524
|
+
*/
|
|
162
525
|
lifecycle(event, message) {
|
|
163
526
|
this.badge("LIFECYCLE");
|
|
164
527
|
const msg = message ? `${event}: ${message}` : event;
|
|
165
528
|
this.info(msg);
|
|
166
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Registra una transición de estado con badge `STATE` a nivel `info`.
|
|
532
|
+
*
|
|
533
|
+
* @param {string} from - Estado previo.
|
|
534
|
+
* @param {string} to - Estado nuevo.
|
|
535
|
+
* @param {unknown} [data] - Payload opcional asociado a la transición.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* const fsm = logger.component('FSM');
|
|
539
|
+
* fsm.stateChange('idle', 'loading');
|
|
540
|
+
* fsm.stateChange('loading', 'success', { items: 3 });
|
|
541
|
+
*/
|
|
167
542
|
stateChange(from, to, data) {
|
|
168
543
|
this.badge("STATE");
|
|
169
544
|
const msg = `${from} → ${to}`;
|
|
170
545
|
if (data) this.info(msg, data);
|
|
171
546
|
else this.info(msg);
|
|
172
547
|
}
|
|
548
|
+
/**
|
|
549
|
+
* Registra cambios de props/debug del componente con badge `PROPS` a nivel
|
|
550
|
+
* `debug`.
|
|
551
|
+
*
|
|
552
|
+
* @param {Record<string, unknown>} changes - Mapa prop → valor (típicamente
|
|
553
|
+
* el diff de props entre renders).
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* logger.component('Cart').propsChange({ itemCount: 5, currency: 'EUR' });
|
|
557
|
+
*/
|
|
173
558
|
propsChange(changes) {
|
|
174
559
|
this.badge("PROPS");
|
|
175
560
|
this.debug("Props changed:", changes);
|
|
176
561
|
}
|
|
177
562
|
};
|
|
563
|
+
/**
|
|
564
|
+
* Handler de contexto apilable sobre un {@link ScopedLogger}.
|
|
565
|
+
*
|
|
566
|
+
* Permite agrupar bloques de logs bajo un sub-prefijo separado por `:`,
|
|
567
|
+
* manteniendo la correlación visual sin necesidad de `console.group`. El
|
|
568
|
+
* prefijo compuesto se forma como `<scopeName>:<contextName>`.
|
|
569
|
+
*
|
|
570
|
+
* Se crea con `scopedLogger.context(name)`. El patrón idiomático es
|
|
571
|
+
* {@link run}/{@link runAsync} (auto push/pop con try/finally); {@link start}
|
|
572
|
+
* y {@link end} permiten control manual cuando el bloque no cierra
|
|
573
|
+
* léxicamente (event handlers distribuidos, promesas de larga duración).
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* import logger from '@mks2508/better-logger';
|
|
577
|
+
*
|
|
578
|
+
* const http = logger.scope('HTTP');
|
|
579
|
+
*
|
|
580
|
+
* // Bloque síncrono auto-cerrado
|
|
581
|
+
* http.context('retry').run(() => {
|
|
582
|
+
* http.warn('Reintentando petición');
|
|
583
|
+
* });
|
|
584
|
+
* // salida: [HTTP:retry] Reintentando petición
|
|
585
|
+
*
|
|
586
|
+
* // Bloque async auto-cerrado
|
|
587
|
+
* await http.context('refresh').runAsync(async () => {
|
|
588
|
+
* await refreshToken();
|
|
589
|
+
* http.info('Token refrescado');
|
|
590
|
+
* });
|
|
591
|
+
*
|
|
592
|
+
* @see {@link ScopedLogger.context}
|
|
593
|
+
*/
|
|
178
594
|
var ContextLogger = class {
|
|
179
595
|
parentLogger;
|
|
180
596
|
contextName;
|
|
597
|
+
/**
|
|
598
|
+
* @param {ScopedLogger} parentLogger - Scope sobre el que se apila el contexto.
|
|
599
|
+
* @param {string} contextName - Sub-prefijo a apilar en el scope padre.
|
|
600
|
+
*/
|
|
181
601
|
constructor(parentLogger, contextName) {
|
|
182
602
|
this.parentLogger = parentLogger;
|
|
183
603
|
this.contextName = contextName;
|
|
184
604
|
}
|
|
605
|
+
/**
|
|
606
|
+
* Ejecuta `fn` síncrona dentro del contexto, garantizando el pop del
|
|
607
|
+
* prefijo incluso si `fn` lanza. El contexto solo está activo durante la
|
|
608
|
+
* ejecución de `fn`.
|
|
609
|
+
*
|
|
610
|
+
* @typeParam T - Tipo de retorno de `fn`.
|
|
611
|
+
* @param {() => T} fn - Función a ejecutar bajo el contexto.
|
|
612
|
+
* @returns {T} Lo que devuelva `fn`.
|
|
613
|
+
* @throws {unknown} Relanza cualquier excepción de `fn` tras desapilar.
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* logger.scope('HTTP').context('warmup').run(() => {
|
|
617
|
+
* logger.info('Pre-cargando caché');
|
|
618
|
+
* });
|
|
619
|
+
*/
|
|
185
620
|
run(fn) {
|
|
186
621
|
this.parentLogger._pushContext(this.contextName);
|
|
187
622
|
try {
|
|
@@ -190,6 +625,21 @@ var ContextLogger = class {
|
|
|
190
625
|
this.parentLogger._popContext();
|
|
191
626
|
}
|
|
192
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* Variante async de {@link run}: mantiene el contexto activo mientras se
|
|
630
|
+
* awaiting la promesa de `fn`, incluyendo awaits internos.
|
|
631
|
+
*
|
|
632
|
+
* @typeParam T - Tipo resuelto por la promesa de `fn`.
|
|
633
|
+
* @param {() => Promise<T>} fn - Función async a ejecutar bajo el contexto.
|
|
634
|
+
* @returns {Promise<T>} Promesa que resuelve al valor de `fn`.
|
|
635
|
+
* @throws {unknown} Relanza cualquier rechazo de `fn` tras desapilar.
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* await logger.scope('HTTP').context('fetch').runAsync(async () => {
|
|
639
|
+
* const r = await fetch(url);
|
|
640
|
+
* logger.info('Recibido', { status: r.status });
|
|
641
|
+
* });
|
|
642
|
+
*/
|
|
193
643
|
async runAsync(fn) {
|
|
194
644
|
this.parentLogger._pushContext(this.contextName);
|
|
195
645
|
try {
|
|
@@ -198,27 +648,80 @@ var ContextLogger = class {
|
|
|
198
648
|
this.parentLogger._popContext();
|
|
199
649
|
}
|
|
200
650
|
}
|
|
651
|
+
/**
|
|
652
|
+
* Apila el contexto manualmente. Útil cuando el bloque que lo consume no
|
|
653
|
+
* cierra léxicamente (event handlers, timeouts, streams). Debe emparejarse
|
|
654
|
+
* con un {@link end} posterior; olvidarlo deja el prefijo contaminado para
|
|
655
|
+
* los logs siguientes del scope.
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* const ctx = logger.scope('WS').context('subscribe');
|
|
659
|
+
* socket.onopen = () => { ctx.start(); ctx.info('connected'); };
|
|
660
|
+
* socket.onclose = () => { ctx.info('disconnected'); ctx.end(); };
|
|
661
|
+
* @see {@link end}
|
|
662
|
+
*/
|
|
201
663
|
start() {
|
|
202
664
|
this.parentLogger._pushContext(this.contextName);
|
|
203
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* Desapila el último contexto abierto con {@link start}.
|
|
668
|
+
*
|
|
669
|
+
* @see {@link start}
|
|
670
|
+
*/
|
|
204
671
|
end() {
|
|
205
672
|
this.parentLogger._popContext();
|
|
206
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* Atajo a `scopedLogger.debug(...)`. El contexto se aplica al prefijo del
|
|
676
|
+
* scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
677
|
+
*
|
|
678
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
679
|
+
*/
|
|
207
680
|
debug(...args) {
|
|
208
681
|
this.parentLogger.debug(...args);
|
|
209
682
|
}
|
|
683
|
+
/**
|
|
684
|
+
* Atajo a `scopedLogger.info(...)`. El contexto se aplica al prefijo del
|
|
685
|
+
* scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
686
|
+
*
|
|
687
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
688
|
+
*/
|
|
210
689
|
info(...args) {
|
|
211
690
|
this.parentLogger.info(...args);
|
|
212
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* Atajo a `scopedLogger.warn(...)`. El contexto se aplica al prefijo del
|
|
694
|
+
* scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
695
|
+
*
|
|
696
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
697
|
+
*/
|
|
213
698
|
warn(...args) {
|
|
214
699
|
this.parentLogger.warn(...args);
|
|
215
700
|
}
|
|
701
|
+
/**
|
|
702
|
+
* Atajo a `scopedLogger.error(...)`. El contexto se aplica al prefijo del
|
|
703
|
+
* scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
704
|
+
*
|
|
705
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
706
|
+
*/
|
|
216
707
|
error(...args) {
|
|
217
708
|
this.parentLogger.error(...args);
|
|
218
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Atajo a `scopedLogger.success(...)`. El contexto se aplica al prefijo del
|
|
712
|
+
* scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
713
|
+
*
|
|
714
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
715
|
+
*/
|
|
219
716
|
success(...args) {
|
|
220
717
|
this.parentLogger.success(...args);
|
|
221
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* Atajo a `scopedLogger.critical(...)`. El contexto se aplica al prefijo
|
|
721
|
+
* del scope padre solo si se invoca dentro de un bloque {@link run}/{@link start}.
|
|
722
|
+
*
|
|
723
|
+
* @param {...unknown[]} args - Mensaje y argumentos adicionales.
|
|
724
|
+
*/
|
|
222
725
|
critical(...args) {
|
|
223
726
|
this.parentLogger.critical(...args);
|
|
224
727
|
}
|
|
@@ -226,7 +729,34 @@ var ContextLogger = class {
|
|
|
226
729
|
//#endregion
|
|
227
730
|
//#region src/cli/CommandProcessor.ts
|
|
228
731
|
/**
|
|
229
|
-
* CLI
|
|
732
|
+
* Procesador central del CLI del logger. Resuelve nombres de comando (con
|
|
733
|
+
* aliases), despacha ejecución, mantiene historial acotado (max 100 entradas)
|
|
734
|
+
* y soporta un sistema de plugins para extensión de terceros.
|
|
735
|
+
*
|
|
736
|
+
* No es un binario standalone: se invoca desde la consola del navegador vía
|
|
737
|
+
* `window.cli("<command>")` (modo interactivo habilitado por
|
|
738
|
+
* {@link enterInteractiveMode}) o desde código vía `logger.cli()`. El
|
|
739
|
+
* constructor no registra ningún comando por defecto — usar
|
|
740
|
+
* {@link createDefaultCLI} para obtener una instancia con los 8 comandos
|
|
741
|
+
* estándar ya cargados.
|
|
742
|
+
*
|
|
743
|
+
* @example
|
|
744
|
+
* ```ts
|
|
745
|
+
* const cli = createDefaultCLI();
|
|
746
|
+
* await cli.processCommand('/themes', logger);
|
|
747
|
+
* await cli.processCommand('/config theme=neon', logger);
|
|
748
|
+
* ```
|
|
749
|
+
*
|
|
750
|
+
* @example
|
|
751
|
+
* ```ts
|
|
752
|
+
* // Modo interactivo: expone `window.cli` en el navegador
|
|
753
|
+
* cli.enterInteractiveMode(logger);
|
|
754
|
+
* // Desde la devtools: cli('help') → procesa '/help'
|
|
755
|
+
* ```
|
|
756
|
+
*
|
|
757
|
+
* @see {@link createDefaultCLI}
|
|
758
|
+
* @see {@link ICommand}
|
|
759
|
+
* @see {@link ICLIPlugin}
|
|
230
760
|
*/
|
|
231
761
|
var CommandProcessor = class {
|
|
232
762
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -236,14 +766,26 @@ var CommandProcessor = class {
|
|
|
236
766
|
maxHistorySize = 100;
|
|
237
767
|
isInteractiveMode = false;
|
|
238
768
|
/**
|
|
239
|
-
*
|
|
769
|
+
* Registra un comando. Si el comando declara `aliases`, también se indexan
|
|
770
|
+
* para resolución. Un comando con el mismo `name` sobreescribe al previo.
|
|
771
|
+
*
|
|
772
|
+
* @param {ICommand} command - Comando a registrar.
|
|
773
|
+
* @see {@link ICommand}
|
|
240
774
|
*/
|
|
241
775
|
registerCommand(command) {
|
|
242
776
|
this.commands.set(command.name, command);
|
|
243
777
|
if (command.aliases) for (const alias of command.aliases) this.aliases.set(alias, command.name);
|
|
244
778
|
}
|
|
245
779
|
/**
|
|
246
|
-
*
|
|
780
|
+
* Registra un plugin: indexa todos sus commands y, si el plugin define
|
|
781
|
+
* `initialize`, lo invoca con el processor y el logger. Los comandos del
|
|
782
|
+
* plugin se registran vía {@link registerCommand} y sus aliases quedan
|
|
783
|
+
* resolvibles igual que los directos.
|
|
784
|
+
*
|
|
785
|
+
* @param {ICLIPlugin} plugin - Plugin a registrar.
|
|
786
|
+
* @param {Logger} [logger] - Logger activo; requerido solo si el plugin define `initialize`.
|
|
787
|
+
* @throws {Error} Si ya existe un plugin registrado con el mismo `name`.
|
|
788
|
+
* @see {@link unregisterPlugin}
|
|
247
789
|
*/
|
|
248
790
|
registerPlugin(plugin, logger) {
|
|
249
791
|
if (this.plugins.has(plugin.name)) throw new Error(`Plugin ${plugin.name} is already registered`);
|
|
@@ -252,7 +794,12 @@ var CommandProcessor = class {
|
|
|
252
794
|
if (plugin.initialize && logger) plugin.initialize(this, logger);
|
|
253
795
|
}
|
|
254
796
|
/**
|
|
255
|
-
*
|
|
797
|
+
* Desregistra un plugin por nombre: elimina todos sus commands (y los
|
|
798
|
+
* aliases que aportasen), invoca su hook `cleanup` si existe y lo quita
|
|
799
|
+
* del registry. No-op si el nombre no existe.
|
|
800
|
+
*
|
|
801
|
+
* @param {string} pluginName - Nombre del plugin a desregistrar.
|
|
802
|
+
* @see {@link registerPlugin}
|
|
256
803
|
*/
|
|
257
804
|
unregisterPlugin(pluginName) {
|
|
258
805
|
const plugin = this.plugins.get(pluginName);
|
|
@@ -265,13 +812,20 @@ var CommandProcessor = class {
|
|
|
265
812
|
this.plugins.delete(pluginName);
|
|
266
813
|
}
|
|
267
814
|
/**
|
|
268
|
-
*
|
|
815
|
+
* Lista todos los commands registrados (directamente o vía plugins).
|
|
816
|
+
* No incluye aliases.
|
|
817
|
+
*
|
|
818
|
+
* @returns {ICommand[]} Snapshot array de los commands registrados.
|
|
269
819
|
*/
|
|
270
820
|
getCommands() {
|
|
271
821
|
return Array.from(this.commands.values());
|
|
272
822
|
}
|
|
273
823
|
/**
|
|
274
|
-
*
|
|
824
|
+
* Resuelve un comando por nombre canónico o alias. Devuelve `undefined`
|
|
825
|
+
* si no existe ninguno que matchee.
|
|
826
|
+
*
|
|
827
|
+
* @param {string} name - Nombre canónico o alias del comando.
|
|
828
|
+
* @returns {ICommand | undefined} El comando resuelto, o `undefined`.
|
|
275
829
|
*/
|
|
276
830
|
getCommand(name) {
|
|
277
831
|
let command = this.commands.get(name);
|
|
@@ -280,25 +834,38 @@ var CommandProcessor = class {
|
|
|
280
834
|
if (aliasTarget) return this.commands.get(aliasTarget);
|
|
281
835
|
}
|
|
282
836
|
/**
|
|
283
|
-
*
|
|
837
|
+
* Devuelve una copia del historial de comandos ejecutados (más recientes
|
|
838
|
+
* primero). Acotado a 100 entradas por {@link maxHistorySize}; las más
|
|
839
|
+
* viejas se descartan al insertar nuevas.
|
|
840
|
+
*
|
|
841
|
+
* @returns {HistoryEntry[]} Snapshot del historial; mutar el array devuelto
|
|
842
|
+
* no afecta al estado interno del processor.
|
|
284
843
|
*/
|
|
285
844
|
getHistory() {
|
|
286
845
|
return [...this.history];
|
|
287
846
|
}
|
|
288
847
|
/**
|
|
289
|
-
*
|
|
848
|
+
* Vacía el historial de comandos en memoria.
|
|
290
849
|
*/
|
|
291
850
|
clearHistory() {
|
|
292
851
|
this.history = [];
|
|
293
852
|
}
|
|
294
853
|
/**
|
|
295
|
-
*
|
|
854
|
+
* Lista los plugins actualmente registrados.
|
|
855
|
+
*
|
|
856
|
+
* @returns {ICLIPlugin[]} Snapshot array de plugins activos.
|
|
296
857
|
*/
|
|
297
858
|
getPlugins() {
|
|
298
859
|
return Array.from(this.plugins.values());
|
|
299
860
|
}
|
|
300
861
|
/**
|
|
301
|
-
*
|
|
862
|
+
* Activa el modo interactivo. Marca el flag interno y, si se ejecuta en
|
|
863
|
+
* navegador, expone `window.cli(command)` para invocar comandos desde la
|
|
864
|
+
* devtools sin prefijo `/` (se añade automáticamente al input).
|
|
865
|
+
*
|
|
866
|
+
* @param {Logger} logger - Logger activo (emite el mensaje de bienvenida
|
|
867
|
+
* con hint sobre `cli(...)` en browser).
|
|
868
|
+
* @see {@link exitInteractiveMode}
|
|
302
869
|
*/
|
|
303
870
|
enterInteractiveMode(logger) {
|
|
304
871
|
this.isInteractiveMode = true;
|
|
@@ -306,13 +873,22 @@ var CommandProcessor = class {
|
|
|
306
873
|
if (typeof window !== "undefined") this.setupBrowserInteractiveMode(logger);
|
|
307
874
|
}
|
|
308
875
|
/**
|
|
309
|
-
*
|
|
876
|
+
* Desactiva el flag de modo interactivo. Nota: no elimina el `window.cli`
|
|
877
|
+
* que {@link enterInteractiveMode} haya expuesto en el navegador — el
|
|
878
|
+
* handler global sigue vivo hasta reload.
|
|
879
|
+
*
|
|
880
|
+
* @see {@link enterInteractiveMode}
|
|
310
881
|
*/
|
|
311
882
|
exitInteractiveMode() {
|
|
312
883
|
this.isInteractiveMode = false;
|
|
313
884
|
}
|
|
314
885
|
/**
|
|
315
|
-
*
|
|
886
|
+
* Instala `window.cli(command)` como wrapper delgado alrededor de
|
|
887
|
+
* {@link processCommand}, prefijando `/` automáticamente. Solo se invoca
|
|
888
|
+
* desde {@link enterInteractiveMode} cuando `window` está disponible.
|
|
889
|
+
*
|
|
890
|
+
* @internal
|
|
891
|
+
* @param logger - Logger activo, reenviado a cada invocación.
|
|
316
892
|
*/
|
|
317
893
|
setupBrowserInteractiveMode(logger) {
|
|
318
894
|
window.cli = (commandString) => {
|
|
@@ -321,7 +897,20 @@ var CommandProcessor = class {
|
|
|
321
897
|
logger.info("💡 Use cli(\"command\") to execute CLI commands in browser console.");
|
|
322
898
|
}
|
|
323
899
|
/**
|
|
324
|
-
*
|
|
900
|
+
* Parsea y ejecuta un comando. El formato esperado es `/name args...`:
|
|
901
|
+
* split por espacios, primer token = nombre del comando, resto = args
|
|
902
|
+
* (re-joined con espacios). Si el comando no existe, loguea el error y
|
|
903
|
+
* sugiere similares vía {@link getSuggestions} ("Did you mean: ...?").
|
|
904
|
+
*
|
|
905
|
+
* Toda invocación (válida o no) se registra en el historial con flag de
|
|
906
|
+
* éxito/fallo según si `execute` resolvió o throweó.
|
|
907
|
+
*
|
|
908
|
+
* @param {string} commandString - Comando completo, debe empezar con `/`.
|
|
909
|
+
* @param {Logger} logger - Logger activo para output y errores.
|
|
910
|
+
* @returns {Promise<void>} Resuelve cuando el comando termina (sync o async).
|
|
911
|
+
* Nunca rechaza: los errores de `execute` se capturan y se loguean.
|
|
912
|
+
* @see {@link ICommand.execute}
|
|
913
|
+
* @see {@link getSuggestions}
|
|
325
914
|
*/
|
|
326
915
|
async processCommand(commandString, logger) {
|
|
327
916
|
if (!commandString.startsWith("/")) {
|
|
@@ -349,7 +938,12 @@ var CommandProcessor = class {
|
|
|
349
938
|
}
|
|
350
939
|
}
|
|
351
940
|
/**
|
|
352
|
-
*
|
|
941
|
+
* Inserta una entrada al frente del historial y trunca a
|
|
942
|
+
* {@link maxHistorySize} (100) si hace falta.
|
|
943
|
+
*
|
|
944
|
+
* @internal
|
|
945
|
+
* @param command - String crudo del comando ejecutado.
|
|
946
|
+
* @param success - Si la ejecución tuvo éxito.
|
|
353
947
|
*/
|
|
354
948
|
addToHistory(command, success) {
|
|
355
949
|
this.history.unshift({
|
|
@@ -360,7 +954,12 @@ var CommandProcessor = class {
|
|
|
360
954
|
if (this.history.length > this.maxHistorySize) this.history = this.history.slice(0, this.maxHistorySize);
|
|
361
955
|
}
|
|
362
956
|
/**
|
|
363
|
-
*
|
|
957
|
+
* Devuelve nombres de comando que empiezan con el prefijo dado. Alimente
|
|
958
|
+
* el hint "Did you mean" de {@link processCommand} cuando un comando no
|
|
959
|
+
* se encuentra. Match por `startsWith` (no fuzzy).
|
|
960
|
+
*
|
|
961
|
+
* @param {string} partial - Prefijo parcial tipeado por el usuario.
|
|
962
|
+
* @returns {string[]} Nombres canónicos que matchean; aliases excluidos.
|
|
364
963
|
*/
|
|
365
964
|
getSuggestions(partial) {
|
|
366
965
|
return Array.from(this.commands.keys()).filter((name) => name.startsWith(partial));
|
|
@@ -369,12 +968,47 @@ var CommandProcessor = class {
|
|
|
369
968
|
//#endregion
|
|
370
969
|
//#region src/cli/commands/ConfigCommand.ts
|
|
371
970
|
/**
|
|
372
|
-
*
|
|
971
|
+
* Comando `/config` del CLI runtime del {@link Logger}. Inspecciona o muta
|
|
972
|
+
* la configuración del logger en vivo desde la DevTools console.
|
|
973
|
+
*
|
|
974
|
+
* Acepta tres modos de invocación:
|
|
975
|
+
* - Sin argumentos: vuelca el estado actual como tabla agrupada.
|
|
976
|
+
* - JSON completo (empieza con `{`): aplica un objeto de configuración parcial.
|
|
977
|
+
* - Pares `key=value` separados por coma: atajo para mutaciones puntuales.
|
|
978
|
+
*
|
|
979
|
+
* Solo se aplican las keys de la whitelist interna (`theme`, `verbosity`,
|
|
980
|
+
* `enableColors`, `enableTimestamps`, `enableStackTrace`, `globalPrefix`,
|
|
981
|
+
* `bannerType`); cualquier otra key se rechaza con un `warn` y se ignora.
|
|
982
|
+
*
|
|
983
|
+
* @example
|
|
984
|
+
* // Sin argumentos: ver estado actual
|
|
985
|
+
* // > /config
|
|
986
|
+
*
|
|
987
|
+
* @example
|
|
988
|
+
* // Objeto JSON completo
|
|
989
|
+
* // > /config {"theme":"neon","verbosity":"debug"}
|
|
990
|
+
*
|
|
991
|
+
* @example
|
|
992
|
+
* // Atajo key=value (múltiples pares separados por coma)
|
|
993
|
+
* // > /config theme=neon,verbosity=debug,globalPrefix=MiApp
|
|
994
|
+
*
|
|
995
|
+
* @see {@link ICommand} para el contrato que implementa este comando.
|
|
996
|
+
* @see {@link Logger.setTheme}, {@link Logger.setVerbosity},
|
|
997
|
+
* {@link Logger.setBannerType}, {@link Logger.setGlobalPrefix}
|
|
998
|
+
* para los setters subyacentes.
|
|
373
999
|
*/
|
|
374
1000
|
var ConfigCommand = class {
|
|
375
1001
|
name = "config";
|
|
376
1002
|
description = "Show or update logger configuration";
|
|
377
1003
|
usage = "/config [json|key=value,...]";
|
|
1004
|
+
/**
|
|
1005
|
+
* Ejecuta el comando `/config` contra el logger dado.
|
|
1006
|
+
*
|
|
1007
|
+
* @param args - Argumentos crudos del usuario. Vacío = status; con `{`
|
|
1008
|
+
* inicial = parse JSON; resto = pares `key=value` separados
|
|
1009
|
+
* por coma.
|
|
1010
|
+
* @param logger - Instancia destino cuyos setters se invocan.
|
|
1011
|
+
*/
|
|
378
1012
|
execute(args, logger) {
|
|
379
1013
|
if (!args) {
|
|
380
1014
|
this.showStatus(logger);
|
|
@@ -448,12 +1082,30 @@ var ConfigCommand = class {
|
|
|
448
1082
|
//#endregion
|
|
449
1083
|
//#region src/cli/commands/ThemeCommand.ts
|
|
450
1084
|
/**
|
|
451
|
-
*
|
|
1085
|
+
* Comando `/themes` del CLI runtime del {@link Logger}. Lista los presets
|
|
1086
|
+
* temáticos disponibles en {@link THEME_PRESETS}, renderizando una preview
|
|
1087
|
+
* con los colores reales de cada tema (background, foreground, border).
|
|
1088
|
+
*
|
|
1089
|
+
* Es de solo lectura: no muta el logger. Útil para descubrir qué tema
|
|
1090
|
+
* aplicar antes de correr `/config theme=<name>`.
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* // Listar todos los temas con preview coloreada
|
|
1094
|
+
* // > /themes
|
|
1095
|
+
*
|
|
1096
|
+
* @see {@link THEME_PRESETS} para el catálogo completo de temas.
|
|
1097
|
+
* @see {@link ConfigCommand} para aplicar un tema vía `/config theme=...`.
|
|
452
1098
|
*/
|
|
453
1099
|
var ThemesCommand = class {
|
|
454
1100
|
name = "themes";
|
|
455
1101
|
description = "Show available theme presets";
|
|
456
1102
|
usage = "/themes";
|
|
1103
|
+
/**
|
|
1104
|
+
* Ejecuta el comando `/themes` contra el logger dado.
|
|
1105
|
+
*
|
|
1106
|
+
* @param _args - Ignorado (comando sin parámetros).
|
|
1107
|
+
* @param logger - Instancia usada para abrir/cerrar el `group` de salida.
|
|
1108
|
+
*/
|
|
457
1109
|
execute(_args, logger) {
|
|
458
1110
|
logger.group("🎨 Available Themes");
|
|
459
1111
|
Object.keys(THEME_PRESETS).forEach((themeName) => {
|
|
@@ -465,12 +1117,30 @@ var ThemesCommand = class {
|
|
|
465
1117
|
}
|
|
466
1118
|
};
|
|
467
1119
|
/**
|
|
468
|
-
*
|
|
1120
|
+
* Comando `/banners` del CLI runtime del {@link Logger}. Enumera los tipos
|
|
1121
|
+
* de banner disponibles en {@link BANNER_VARIANTS} (`simple`, `ascii`,
|
|
1122
|
+
* `unicode`, ...) con una mini-preview de cada uno para inspección visual.
|
|
1123
|
+
*
|
|
1124
|
+
* Es de solo lectura: no muta el logger. Para cambiar el banner activo
|
|
1125
|
+
* usar {@link BannerCommand}.
|
|
1126
|
+
*
|
|
1127
|
+
* @example
|
|
1128
|
+
* // Listar todas las variantes de banner con preview
|
|
1129
|
+
* // > /banners
|
|
1130
|
+
*
|
|
1131
|
+
* @see {@link BANNER_VARIANTS} para el catálogo completo de variantes.
|
|
1132
|
+
* @see {@link BannerCommand} para aplicar un tipo concreto.
|
|
469
1133
|
*/
|
|
470
1134
|
var BannersCommand = class {
|
|
471
1135
|
name = "banners";
|
|
472
1136
|
description = "Show available banner types";
|
|
473
1137
|
usage = "/banners";
|
|
1138
|
+
/**
|
|
1139
|
+
* Ejecuta el comando `/banners` contra el logger dado.
|
|
1140
|
+
*
|
|
1141
|
+
* @param _args - Ignorado (comando sin parámetros).
|
|
1142
|
+
* @param logger - Instancia usada para abrir/cerrar el `group` de salida.
|
|
1143
|
+
*/
|
|
474
1144
|
execute(_args, logger) {
|
|
475
1145
|
logger.group("🖼️ Available Banner Types");
|
|
476
1146
|
Object.keys(BANNER_VARIANTS).forEach((bannerName) => {
|
|
@@ -486,12 +1156,35 @@ var BannersCommand = class {
|
|
|
486
1156
|
}
|
|
487
1157
|
};
|
|
488
1158
|
/**
|
|
489
|
-
*
|
|
1159
|
+
* Comando `/banner [type]` del CLI runtime del {@link Logger}.
|
|
1160
|
+
*
|
|
1161
|
+
* - Sin argumentos: re-renderiza el banner actualmente activo.
|
|
1162
|
+
* - Con un tipo válido: lo aplica vía {@link Logger.setBannerType} y lo
|
|
1163
|
+
* muestra inmediatamente.
|
|
1164
|
+
* - Con un tipo inválido: loguea un `error` listando las opciones válidas.
|
|
1165
|
+
*
|
|
1166
|
+
* @example
|
|
1167
|
+
* // Mostrar el banner actual
|
|
1168
|
+
* // > /banner
|
|
1169
|
+
*
|
|
1170
|
+
* @example
|
|
1171
|
+
* // Cambiar a un tipo concreto
|
|
1172
|
+
* // > /banner ascii
|
|
1173
|
+
*
|
|
1174
|
+
* @see {@link BANNER_VARIANTS} para los tipos aceptados.
|
|
1175
|
+
* @see {@link Logger.setBannerType} y {@link Logger.showBanner} para los
|
|
1176
|
+
* métodos subyacentes.
|
|
490
1177
|
*/
|
|
491
1178
|
var BannerCommand = class {
|
|
492
1179
|
name = "banner";
|
|
493
1180
|
description = "Change or show current banner type";
|
|
494
1181
|
usage = "/banner [type]";
|
|
1182
|
+
/**
|
|
1183
|
+
* Ejecuta el comando `/banner` contra el logger dado.
|
|
1184
|
+
*
|
|
1185
|
+
* @param args - Tipo de banner solicitado. Vacío = mostrar banner actual.
|
|
1186
|
+
* @param logger - Instancia destino cuyo banner se actualiza/muestra.
|
|
1187
|
+
*/
|
|
495
1188
|
execute(args, logger) {
|
|
496
1189
|
if (!args) {
|
|
497
1190
|
logger.showBanner();
|
|
@@ -506,12 +1199,27 @@ var BannerCommand = class {
|
|
|
506
1199
|
//#endregion
|
|
507
1200
|
//#region src/cli/commands/ExportCommand.ts
|
|
508
1201
|
/**
|
|
509
|
-
*
|
|
1202
|
+
* Comando `/status` del CLI runtime del {@link Logger}. Vuelca la
|
|
1203
|
+
* configuración vigente y algunas estadísticas (theme, verbosity, flags
|
|
1204
|
+
* de features, handler count, bufferSize) en una tabla agrupada dentro
|
|
1205
|
+
* de la consola. Es de solo lectura: no muta el logger.
|
|
1206
|
+
*
|
|
1207
|
+
* @example
|
|
1208
|
+
* // Inspeccionar el estado actual del logger
|
|
1209
|
+
* // > /status
|
|
1210
|
+
*
|
|
1211
|
+
* @see {@link Logger.getConfig} fuente de los datos mostrados.
|
|
510
1212
|
*/
|
|
511
1213
|
var StatusCommand = class {
|
|
512
1214
|
name = "status";
|
|
513
1215
|
description = "Show current logger status and configuration";
|
|
514
1216
|
usage = "/status";
|
|
1217
|
+
/**
|
|
1218
|
+
* Ejecuta el comando `/status` contra el logger dado.
|
|
1219
|
+
*
|
|
1220
|
+
* @param _args - Ignorado (comando sin parámetros).
|
|
1221
|
+
* @param logger - Instancia de la que se lee la configuración.
|
|
1222
|
+
*/
|
|
515
1223
|
execute(_args, logger) {
|
|
516
1224
|
const config = logger.getConfig();
|
|
517
1225
|
const statusData = {
|
|
@@ -531,23 +1239,54 @@ var StatusCommand = class {
|
|
|
531
1239
|
}
|
|
532
1240
|
};
|
|
533
1241
|
/**
|
|
534
|
-
*
|
|
1242
|
+
* Comando `/reset` del CLI runtime del {@link Logger}. Restaura la
|
|
1243
|
+
* configuración a sus defaults de fábrica vía {@link Logger.resetConfig}.
|
|
1244
|
+
* No resetea handlers ni transports registrados — solo config.
|
|
1245
|
+
*
|
|
1246
|
+
* @example
|
|
1247
|
+
* // Volver a la configuración por defecto
|
|
1248
|
+
* // > /reset
|
|
1249
|
+
*
|
|
1250
|
+
* @see {@link Logger.resetConfig} para el método subyacente.
|
|
535
1251
|
*/
|
|
536
1252
|
var ResetCommand = class {
|
|
537
1253
|
name = "reset";
|
|
538
1254
|
description = "Reset logger configuration to defaults";
|
|
539
1255
|
usage = "/reset";
|
|
1256
|
+
/**
|
|
1257
|
+
* Ejecuta el comando `/reset` contra el logger dado.
|
|
1258
|
+
*
|
|
1259
|
+
* @param _args - Ignorado (comando sin parámetros).
|
|
1260
|
+
* @param logger - Instancia cuya configuración se resetea.
|
|
1261
|
+
*/
|
|
540
1262
|
execute(_args, logger) {
|
|
541
1263
|
logger.resetConfig();
|
|
542
1264
|
}
|
|
543
1265
|
};
|
|
544
1266
|
/**
|
|
545
|
-
*
|
|
1267
|
+
* Comando `/demo` del CLI runtime del {@link Logger}. Ejecuta una
|
|
1268
|
+
* demostración integral de las capacidades del logger: todos los niveles
|
|
1269
|
+
* de log (debug → critical), tablas, timers (`time`/`timeEnd`), SVG inline
|
|
1270
|
+
* y mensajes animados. Útil para validar que el styling funciona en un
|
|
1271
|
+
* entorno nuevo o tras un cambio de tema.
|
|
1272
|
+
*
|
|
1273
|
+
* @example
|
|
1274
|
+
* // Lanzar la demo completa
|
|
1275
|
+
* // > /demo
|
|
1276
|
+
*
|
|
1277
|
+
* @see {@link Logger} para cada feature individual (`table`, `time`,
|
|
1278
|
+
* `logWithSVG`, `logAnimated`, ...).
|
|
546
1279
|
*/
|
|
547
1280
|
var DemoCommand = class {
|
|
548
1281
|
name = "demo";
|
|
549
1282
|
description = "Show comprehensive feature demonstration";
|
|
550
1283
|
usage = "/demo";
|
|
1284
|
+
/**
|
|
1285
|
+
* Ejecuta el comando `/demo` contra el logger dado.
|
|
1286
|
+
*
|
|
1287
|
+
* @param _args - Ignorado (comando sin parámetros).
|
|
1288
|
+
* @param logger - Instancia sobre la que se ejecutan los ejemplos.
|
|
1289
|
+
*/
|
|
551
1290
|
execute(_args, logger) {
|
|
552
1291
|
logger.group("🎪 Advanced Logger Demo");
|
|
553
1292
|
logger.debug("Debug message with detailed information");
|
|
@@ -593,12 +1332,38 @@ var DemoCommand = class {
|
|
|
593
1332
|
//#endregion
|
|
594
1333
|
//#region src/cli/help.ts
|
|
595
1334
|
/**
|
|
596
|
-
*
|
|
1335
|
+
* Comando `/help`: renderiza en consola el panel de ayuda del CLI con todos
|
|
1336
|
+
* los comandos disponibles, opciones de configuración, filtros de export y
|
|
1337
|
+
* ejemplos. El panel usa un gradient claro con {@link StyleBuilder} y los
|
|
1338
|
+
* quick tips se agrupan vía `logger.group`.
|
|
1339
|
+
*
|
|
1340
|
+
* Registrado por defecto por {@link createDefaultCLI}.
|
|
1341
|
+
*
|
|
1342
|
+
* @example
|
|
1343
|
+
* ```ts
|
|
1344
|
+
* const cli = createDefaultCLI();
|
|
1345
|
+
* await cli.processCommand('/help', logger);
|
|
1346
|
+
* // Imprime el panel ASCII con gradient + grupo "Quick Tips".
|
|
1347
|
+
* ```
|
|
1348
|
+
*
|
|
1349
|
+
* @see {@link ICommand}
|
|
1350
|
+
* @see {@link createDefaultCLI}
|
|
597
1351
|
*/
|
|
598
1352
|
var HelpCommand = class {
|
|
599
1353
|
name = "help";
|
|
600
1354
|
description = "Show CLI help and available commands";
|
|
601
1355
|
usage = "/help [command]";
|
|
1356
|
+
/**
|
|
1357
|
+
* Renderiza el panel de ayuda completo. Actualmente ignora `_args`: el
|
|
1358
|
+
* `usage` declara `/help [command]` (sub-comando opcional) pero la
|
|
1359
|
+
* implementación siempre muestra el panel global.
|
|
1360
|
+
*
|
|
1361
|
+
* @param {string} _args - Argumentos opcionales (reservado para ayuda por
|
|
1362
|
+
* sub-comando; sin uso actual).
|
|
1363
|
+
* @param {Logger} logger - Logger activo; se usa solo para `group`/`info`
|
|
1364
|
+
* de los quick tips.
|
|
1365
|
+
* @returns {void}
|
|
1366
|
+
*/
|
|
602
1367
|
execute(_args, logger) {
|
|
603
1368
|
const helpStyle = new StyleBuilder().bg("linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)").color("#495057").padding("15px 20px").rounded("8px").border("1px solid #dee2e6").font("Monaco, Consolas, monospace").size("13px").build();
|
|
604
1369
|
console.log(`%c
|
|
@@ -698,7 +1463,30 @@ var HelpCommand = class {
|
|
|
698
1463
|
//#endregion
|
|
699
1464
|
//#region src/cli/index.ts
|
|
700
1465
|
/**
|
|
701
|
-
*
|
|
1466
|
+
* Crea un {@link CommandProcessor} con los 8 comandos estándar ya registrados:
|
|
1467
|
+
* `help`, `config`, `themes`, `banners`, `banner`, `status`, `reset` y
|
|
1468
|
+
* `demo`. Es el factory canónico — los consumidores normalmente no construyen
|
|
1469
|
+
* un `CommandProcessor` vacío a mano, ya que este no trae comandos cargados.
|
|
1470
|
+
*
|
|
1471
|
+
* @returns {CommandProcessor} Processor listo para usar, sin modo interactivo activo.
|
|
1472
|
+
*
|
|
1473
|
+
* @example
|
|
1474
|
+
* ```ts
|
|
1475
|
+
* const cli = createDefaultCLI();
|
|
1476
|
+
* await cli.processCommand('/help', logger);
|
|
1477
|
+
* await cli.processCommand('/config theme=neon', logger);
|
|
1478
|
+
* ```
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* ```ts
|
|
1482
|
+
* // Modo interactivo en el navegador: expone `window.cli`
|
|
1483
|
+
* const cli = createDefaultCLI();
|
|
1484
|
+
* cli.enterInteractiveMode(logger);
|
|
1485
|
+
* // desde devtools: cli('themes') → procesa '/themes'
|
|
1486
|
+
* ```
|
|
1487
|
+
*
|
|
1488
|
+
* @see {@link CommandProcessor}
|
|
1489
|
+
* @see {@link HelpCommand}
|
|
702
1490
|
*/
|
|
703
1491
|
function createDefaultCLI() {
|
|
704
1492
|
const processor = new CommandProcessor();
|
|
@@ -715,7 +1503,9 @@ function createDefaultCLI() {
|
|
|
715
1503
|
//#endregion
|
|
716
1504
|
//#region src/transports/TransportBridge.ts
|
|
717
1505
|
/**
|
|
718
|
-
*
|
|
1506
|
+
* Crea una instancia de {@link TransportBridge}.
|
|
1507
|
+
*
|
|
1508
|
+
* @internal
|
|
719
1509
|
*/
|
|
720
1510
|
function createTransportBridge() {
|
|
721
1511
|
let transportManager;
|
|
@@ -745,7 +1535,10 @@ function createTransportBridge() {
|
|
|
745
1535
|
//#endregion
|
|
746
1536
|
//#region src/playground/TerminalBridge.ts
|
|
747
1537
|
/**
|
|
748
|
-
*
|
|
1538
|
+
* Crea un {@link TerminalBridge} usando un getter para evitar referencias
|
|
1539
|
+
* circulares en la construcción.
|
|
1540
|
+
*
|
|
1541
|
+
* @internal
|
|
749
1542
|
*/
|
|
750
1543
|
function createTerminalBridge(options) {
|
|
751
1544
|
let _showPrimitives = true;
|
|
@@ -870,37 +1663,38 @@ var Logger = class Logger {
|
|
|
870
1663
|
hookBridge;
|
|
871
1664
|
logContext;
|
|
872
1665
|
transportBridge;
|
|
873
|
-
/**
|
|
1666
|
+
/** Fijado por `success()` para que `log()` salte su propio dispatch. */
|
|
874
1667
|
_successTagDispatched = false;
|
|
875
1668
|
styleManager;
|
|
876
|
-
/**
|
|
1669
|
+
/** Controla si las CLI primitives (step, box, header, ...) deben renderizarse. */
|
|
877
1670
|
_showPrimitives = true;
|
|
878
1671
|
terminalBridge;
|
|
879
1672
|
/**
|
|
880
|
-
*
|
|
881
|
-
*
|
|
1673
|
+
* Referencia activa al smart-preset (fijada por `preset()`). Tipada como
|
|
1674
|
+
* `unknown` para mantener limpia la surface pública; la consume
|
|
1675
|
+
* `createStyledOutput`.
|
|
882
1676
|
*/
|
|
883
1677
|
_activePreset;
|
|
884
1678
|
/**
|
|
885
|
-
*
|
|
886
|
-
*
|
|
1679
|
+
* Nombre del smart-preset activo. Se guarda aparte para que la detección
|
|
1680
|
+
* de cambio de tema pueda re-renderizar sin re-ejecutar el body del preset.
|
|
887
1681
|
*/
|
|
888
1682
|
_activePresetName;
|
|
889
1683
|
/**
|
|
890
|
-
*
|
|
891
|
-
* `createStyledOutput
|
|
1684
|
+
* Overrides aplicados por el último `customize()`. Se conservan para que
|
|
1685
|
+
* `createStyledOutput` los lea después.
|
|
892
1686
|
*/
|
|
893
1687
|
_customization;
|
|
894
1688
|
/**
|
|
895
|
-
*
|
|
896
|
-
*
|
|
1689
|
+
* Bindings propios de este logger (provenientes de llamadas a `child()`).
|
|
1690
|
+
* Source of truth única de la contribución de este logger a la cadena de contexto.
|
|
897
1691
|
* @private
|
|
898
1692
|
*/
|
|
899
1693
|
_bindings = {};
|
|
900
1694
|
/**
|
|
901
|
-
*
|
|
902
|
-
*
|
|
903
|
-
*
|
|
1695
|
+
* Referencia al record de contexto mergueado del parent en el momento en
|
|
1696
|
+
* que se creó este logger. Junto con `_bindings`, forma la cadena de
|
|
1697
|
+
* contexto. `undefined` para el logger raíz.
|
|
904
1698
|
* @private
|
|
905
1699
|
*/
|
|
906
1700
|
_parentContextRecord;
|
|
@@ -1068,65 +1862,66 @@ var Logger = class Logger {
|
|
|
1068
1862
|
this.success(`Banner type changed to: ${bannerType}`);
|
|
1069
1863
|
}
|
|
1070
1864
|
/**
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1865
|
+
* Ejecuta `fn` dentro de un scope AsyncLocalStorage donde `bindings` se
|
|
1866
|
+
* merguean al contexto para todas las llamadas de log dentro de `fn`.
|
|
1073
1867
|
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1868
|
+
* Sin `fn` (el shape legacy de setter): no-op por backwards compatibility.
|
|
1869
|
+
* Preferir `child()` para bindings persistentes o `withContextAsync()`
|
|
1870
|
+
* para callbacks async.
|
|
1077
1871
|
*
|
|
1078
|
-
* @param bindings -
|
|
1079
|
-
* @param fn -
|
|
1080
|
-
* @returns
|
|
1872
|
+
* @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`
|
|
1873
|
+
* @param fn - Función sincrónica opcional a ejecutar con los bindings en scope
|
|
1874
|
+
* @returns El valor de retorno de `fn`, o `undefined` si no se pasa `fn`
|
|
1081
1875
|
*
|
|
1082
1876
|
* @example
|
|
1083
|
-
* //
|
|
1877
|
+
* // Callback sincrónico scoped
|
|
1084
1878
|
* logger.withContext({ requestId: 'r-42' }, () => {
|
|
1085
|
-
* doWork(); // logs
|
|
1879
|
+
* doWork(); // los logs de aquí ven requestId en attributes
|
|
1086
1880
|
* });
|
|
1087
1881
|
*
|
|
1088
1882
|
* @example
|
|
1089
|
-
* //
|
|
1883
|
+
* // Binding persistente: usar child()
|
|
1090
1884
|
* const reqLog = logger.child({ requestId: 'r-42' });
|
|
1091
|
-
* reqLog.info('handling request'); // attributes
|
|
1885
|
+
* reqLog.info('handling request'); // attributes incluye requestId
|
|
1092
1886
|
*
|
|
1093
|
-
* @see {@link child}
|
|
1094
|
-
* @see {@link withContextAsync}
|
|
1887
|
+
* @see {@link child} para una copia inmutable con el contexto mergueado
|
|
1888
|
+
* @see {@link withContextAsync} para la variante con callback async
|
|
1095
1889
|
*/
|
|
1096
1890
|
withContext(bindings, fn) {
|
|
1097
1891
|
return this.logContext.withContext(bindings, fn);
|
|
1098
1892
|
}
|
|
1099
1893
|
/**
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1894
|
+
* Variante async de `withContext`. Ejecuta `fn` dentro de un scope
|
|
1895
|
+
* AsyncLocalStorage para que los bindings estén disponibles a todas las
|
|
1896
|
+
* llamadas de log async dentro de `fn`.
|
|
1102
1897
|
*
|
|
1103
|
-
* @param bindings -
|
|
1104
|
-
* @param fn -
|
|
1105
|
-
* @returns
|
|
1898
|
+
* @param bindings - Pares key-value a adjuntar durante la ejecución de `fn`
|
|
1899
|
+
* @param fn - Función async a ejecutar con los bindings en scope
|
|
1900
|
+
* @returns El valor de retorno de `fn`
|
|
1106
1901
|
*
|
|
1107
1902
|
* @example
|
|
1108
1903
|
* await logger.withContextAsync({ requestId: 'r-42' }, async () => {
|
|
1109
|
-
* await fetchData(); // logs
|
|
1904
|
+
* await fetchData(); // los logs de aquí ven requestId en attributes
|
|
1110
1905
|
* });
|
|
1111
1906
|
*
|
|
1112
|
-
* @see {@link child}
|
|
1113
|
-
* @see {@link withContext}
|
|
1907
|
+
* @see {@link child} para un child logger persistente
|
|
1908
|
+
* @see {@link withContext} para la variante con callback sincrónico
|
|
1114
1909
|
*/
|
|
1115
1910
|
withContextAsync(bindings, fn) {
|
|
1116
1911
|
return this.logContext.withContextAsync(bindings, fn);
|
|
1117
1912
|
}
|
|
1118
1913
|
/**
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
*
|
|
1914
|
+
* Devuelve una copia inmutable de este logger con el contexto extra bound.
|
|
1915
|
+
* Las llamadas futuras sobre el child emiten con el contexto mergueado,
|
|
1916
|
+
* sin mutar al parent — el patrón canónico de MDC.
|
|
1122
1917
|
*
|
|
1123
|
-
* @param extra -
|
|
1124
|
-
* @returns
|
|
1918
|
+
* @param extra - Pares key-value a adjuntar (requestId, userId, ...)
|
|
1919
|
+
* @returns Un nuevo Logger con el contexto mergueado
|
|
1125
1920
|
*
|
|
1126
1921
|
* @example
|
|
1127
1922
|
* const reqLog = logger.child({ requestId: req.id });
|
|
1128
|
-
* reqLog.info('start'); //
|
|
1129
|
-
* logger.info('unrelated'); //
|
|
1923
|
+
* reqLog.info('start'); // emite attributes: { requestId }
|
|
1924
|
+
* logger.info('unrelated'); // NO afectado — el contexto del parent queda intacto
|
|
1130
1925
|
*
|
|
1131
1926
|
*/
|
|
1132
1927
|
child(extra) {
|
|
@@ -1136,21 +1931,21 @@ var Logger = class Logger {
|
|
|
1136
1931
|
return childLogger;
|
|
1137
1932
|
}
|
|
1138
1933
|
/**
|
|
1139
|
-
*
|
|
1140
|
-
* records
|
|
1141
|
-
* {@link child}
|
|
1934
|
+
* Descarta todas las keys del contexto bound. Tras esta llamada, los
|
|
1935
|
+
* records emitidos dejan de llevar `attributes` hasta que
|
|
1936
|
+
* {@link withContext} o {@link child} restablezcan uno.
|
|
1142
1937
|
*
|
|
1143
|
-
* @returns
|
|
1938
|
+
* @returns La misma instancia del logger, ahora sin contexto
|
|
1144
1939
|
*/
|
|
1145
1940
|
clearContext() {
|
|
1146
1941
|
this.logContext.clearContext();
|
|
1147
1942
|
return this;
|
|
1148
1943
|
}
|
|
1149
1944
|
/**
|
|
1150
|
-
* Snapshot
|
|
1151
|
-
*
|
|
1945
|
+
* Snapshot del contexto bound. El objeto devuelto es una shallow copy:
|
|
1946
|
+
* mutarlo NO afecta lo que emiten las llamadas de log posteriores.
|
|
1152
1947
|
*
|
|
1153
|
-
* @returns
|
|
1948
|
+
* @returns Un snapshot read-only del contexto actual
|
|
1154
1949
|
*/
|
|
1155
1950
|
getContext() {
|
|
1156
1951
|
let merged = this._parentContextRecord ?? {};
|
|
@@ -1161,12 +1956,12 @@ var Logger = class Logger {
|
|
|
1161
1956
|
return merged;
|
|
1162
1957
|
}
|
|
1163
1958
|
/**
|
|
1164
|
-
*
|
|
1165
|
-
*
|
|
1166
|
-
* record
|
|
1959
|
+
* Actualiza el resource OTel por defecto (service.name, version, env).
|
|
1960
|
+
* Se persiste en el campo `resource` de cada record emitido, salvo que
|
|
1961
|
+
* el propio record lo override.
|
|
1167
1962
|
*
|
|
1168
|
-
* @param resource -
|
|
1169
|
-
* @returns
|
|
1963
|
+
* @param resource - Resource OTel parcial a merguear con el actual
|
|
1964
|
+
* @returns La misma instancia del logger, para chaining
|
|
1170
1965
|
*
|
|
1171
1966
|
* @example
|
|
1172
1967
|
* logger.setResource({ 'service.name': 'api', 'service.version': '1.2.3' });
|
|
@@ -1195,20 +1990,15 @@ var Logger = class Logger {
|
|
|
1195
1990
|
this.success("Logger configuration reset to defaults");
|
|
1196
1991
|
}
|
|
1197
1992
|
/**
|
|
1198
|
-
* Método de limpieza para eliminar listeners y liberar recursos
|
|
1199
|
-
*
|
|
1200
|
-
*
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1203
|
-
*
|
|
1204
|
-
*/
|
|
1205
|
-
/**
|
|
1206
|
-
* Tears down every resource held by this Logger. Safe to call multiple
|
|
1207
|
-
* times. Fixed in 5.1.0 to fully drain transports + clear timers +
|
|
1208
|
-
* drop the legacy handler list + reset group depth + clear context.
|
|
1993
|
+
* Método de limpieza para eliminar listeners y liberar recursos.
|
|
1994
|
+
*
|
|
1995
|
+
* Vacía los transports (drain), limpia timers, suelta la lista de
|
|
1996
|
+
* handlers legacy, resetea el group depth y limpia el context.
|
|
1997
|
+
* Seguro de invocar múltiples veces.
|
|
1209
1998
|
*
|
|
1210
1999
|
* @example
|
|
1211
|
-
*
|
|
2000
|
+
* // Antes de cerrar la aplicación
|
|
2001
|
+
* await logger.cleanup();
|
|
1212
2002
|
*
|
|
1213
2003
|
*/
|
|
1214
2004
|
async cleanup() {
|
|
@@ -1237,7 +2027,7 @@ var Logger = class Logger {
|
|
|
1237
2027
|
* logger.preset('glassmorphism'); // Efectos de blur modernos
|
|
1238
2028
|
* logger.preset('minimal'); // Minimalista y elegante
|
|
1239
2029
|
* logger.preset('debug'); // Modo desarrollo detallado
|
|
1240
|
-
* logger.preset('production'); //
|
|
2030
|
+
* logger.preset('production'); // Enfocado en producción
|
|
1241
2031
|
*
|
|
1242
2032
|
*/
|
|
1243
2033
|
preset(name) {
|
|
@@ -1383,12 +2173,63 @@ var Logger = class Logger {
|
|
|
1383
2173
|
this.badgeList = [];
|
|
1384
2174
|
return this;
|
|
1385
2175
|
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Crea un logger scoped para un componente o módulo del dominio.
|
|
2178
|
+
*
|
|
2179
|
+
* El `ComponentLogger` resultante prepends un badge `[name]` a cada
|
|
2180
|
+
* mensaje y comparte configuración, transports y hooks con el logger
|
|
2181
|
+
* padre. Útil para trazar el origen de los logs en apps con muchos
|
|
2182
|
+
* módulos (Auth, DB, Cache, ...).
|
|
2183
|
+
*
|
|
2184
|
+
* @param {string} name - Nombre del componente que aparecerá como badge
|
|
2185
|
+
* @returns {ComponentLogger} Logger scoped para el componente
|
|
2186
|
+
*
|
|
2187
|
+
* @example
|
|
2188
|
+
* const auth = logger.component('Auth');
|
|
2189
|
+
* auth.info('Validando token'); // [Auth] Validando token
|
|
2190
|
+
* auth.success('Token válido');
|
|
2191
|
+
*
|
|
2192
|
+
* @see {@link api} para loggers de endpoints REST/GraphQL
|
|
2193
|
+
* @see {@link scope} para un scope genérico sin badge de componente
|
|
2194
|
+
*/
|
|
1386
2195
|
component(name) {
|
|
1387
2196
|
return new ComponentLogger(this, name);
|
|
1388
2197
|
}
|
|
2198
|
+
/**
|
|
2199
|
+
* Crea un logger scoped para un endpoint o surface de API.
|
|
2200
|
+
*
|
|
2201
|
+
* Como `component()` pero con styling orientado a APIs (badge `[API]`
|
|
2202
|
+
* por defecto más el nombre del sub-scope). Útil para distinguir
|
|
2203
|
+
* tráfico REST vs GraphQL vs WebSocket en los logs.
|
|
2204
|
+
*
|
|
2205
|
+
* @param {string} name - Nombre de la API o surface (p.ej. `'REST'`, `'GraphQL'`)
|
|
2206
|
+
* @returns {APILogger} Logger scoped para la API
|
|
2207
|
+
*
|
|
2208
|
+
* @example
|
|
2209
|
+
* const rest = logger.api('REST');
|
|
2210
|
+
* rest.info('GET /users/42'); // [API] [REST] GET /users/42
|
|
2211
|
+
*
|
|
2212
|
+
* @see {@link component} para loggers de componentes de dominio
|
|
2213
|
+
*/
|
|
1389
2214
|
api(name) {
|
|
1390
2215
|
return new APILogger(this, name);
|
|
1391
2216
|
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Crea un logger scoped genérico con un prefijo.
|
|
2219
|
+
*
|
|
2220
|
+
* Variante minimal de `component()` / `api()`: solo aplica un prefijo
|
|
2221
|
+
* de scope sin badges ni styling especial. Útil para sub-módulos que
|
|
2222
|
+
* no encajan en las categorías de `component`/`api`.
|
|
2223
|
+
*
|
|
2224
|
+
* @param {string} name - Texto del prefijo de scope
|
|
2225
|
+
* @returns {ScopedLogger} Logger con el scope aplicado
|
|
2226
|
+
*
|
|
2227
|
+
* @example
|
|
2228
|
+
* const db = logger.scope('db');
|
|
2229
|
+
* db.info('Pool conectado'); // [db] Pool conectado
|
|
2230
|
+
*
|
|
2231
|
+
* @see {@link component} y {@link api} para variantes con badges
|
|
2232
|
+
*/
|
|
1392
2233
|
scope(name) {
|
|
1393
2234
|
return new ScopedLogger(this, name);
|
|
1394
2235
|
}
|
|
@@ -1625,33 +2466,29 @@ var Logger = class Logger {
|
|
|
1625
2466
|
return LOG_LEVELS[level] >= LOG_LEVELS[this.config.verbosity];
|
|
1626
2467
|
}
|
|
1627
2468
|
/**
|
|
1628
|
-
*
|
|
1629
|
-
* (
|
|
1630
|
-
* `log()
|
|
1631
|
-
* `time()` — so all emissions hit the same transport pipeline.
|
|
2469
|
+
* Tag pendiente de inyectar en el siguiente `TransportRecord` emitido
|
|
2470
|
+
* por `log()`. Lo fijan `success()` y `logWithBindingsAndTag()` antes
|
|
2471
|
+
* de delegar; `log()` lo consume y lo resetea a `undefined`.
|
|
1632
2472
|
*
|
|
1633
|
-
* @
|
|
1634
|
-
* @param message - Final, post-hook message text
|
|
1635
|
-
* @param prefix - Effective prefix (global + scope)
|
|
1636
|
-
* @param stackInfo - Optional caller location
|
|
1637
|
-
* @param extra - Optional fields to merge into the record (e.g. `{ tag: 'success' }`)
|
|
2473
|
+
* @internal
|
|
1638
2474
|
*/
|
|
1639
2475
|
_dispatchTag;
|
|
1640
2476
|
/**
|
|
1641
|
-
*
|
|
2477
|
+
* Computa el contexto completamente mergueado para este logger.
|
|
1642
2478
|
*
|
|
1643
|
-
*
|
|
1644
|
-
*
|
|
1645
|
-
*
|
|
1646
|
-
*
|
|
2479
|
+
* La cadena de contexto se construye en el momento de crear el child:
|
|
2480
|
+
* cada child almacena el contexto fully-merged de su parent (en ese
|
|
2481
|
+
* instante) como `_parentContextRecord`. Esto implica que
|
|
2482
|
+
* `_parentContextRecord` ya contiene los bindings de todos los ancestros
|
|
2483
|
+
* en el orden de precedencia correcto (root primero, child más cercano al final).
|
|
1647
2484
|
*
|
|
1648
|
-
*
|
|
1649
|
-
* 1. _parentContextRecord —
|
|
1650
|
-
* 2. _bindings —
|
|
1651
|
-
* 3. ALS store — withContext
|
|
2485
|
+
* Orden de merge (gana el último):
|
|
2486
|
+
* 1. _parentContextRecord — snapshot del contexto mergueado del parent en la creación
|
|
2487
|
+
* 2. _bindings — bindings propios de este logger (llamadas a `child()`)
|
|
2488
|
+
* 3. ALS store — scope de `withContext`/`withContextAsync` (prioridad máxima)
|
|
1652
2489
|
*
|
|
1653
2490
|
* @internal
|
|
1654
|
-
* @returns
|
|
2491
|
+
* @returns El record de contexto mergueado
|
|
1655
2492
|
*/
|
|
1656
2493
|
_getMergedContext() {
|
|
1657
2494
|
let merged = this._parentContextRecord ?? {};
|
|
@@ -1666,7 +2503,7 @@ var Logger = class Logger {
|
|
|
1666
2503
|
};
|
|
1667
2504
|
return merged;
|
|
1668
2505
|
}
|
|
1669
|
-
/** @internal
|
|
2506
|
+
/** @internal Expone el contexto base mergueado (sin ALS) a la closure de la child factory de LogContext. */
|
|
1670
2507
|
_captureMergedContext() {
|
|
1671
2508
|
let merged = this._parentContextRecord ?? {};
|
|
1672
2509
|
if (this._bindings && Object.keys(this._bindings).length > 0) merged = {
|
|
@@ -1675,6 +2512,21 @@ var Logger = class Logger {
|
|
|
1675
2512
|
};
|
|
1676
2513
|
return merged;
|
|
1677
2514
|
}
|
|
2515
|
+
/**
|
|
2516
|
+
* Construye y despacha un `TransportRecord` al {@link TransportManager}
|
|
2517
|
+
* (no-op si no hay transports registrados). Lo comparten todos los
|
|
2518
|
+
* caminos de log — `log()`, `success()` y los métodos visuales como
|
|
2519
|
+
* `table()` / `group()` / `time()` — para que toda emisión atraviese
|
|
2520
|
+
* el mismo pipeline de transports.
|
|
2521
|
+
*
|
|
2522
|
+
* @protected
|
|
2523
|
+
* @param {LogLevel} level - Nivel canónico (trace/debug/info/warn/error/critical)
|
|
2524
|
+
* @param {string} message - Mensaje final, post-hook
|
|
2525
|
+
* @param {string | undefined} prefix - Prefijo efectivo (global + scope)
|
|
2526
|
+
* @param {StackInfo | null} stackInfo - Ubicación del caller, opcional
|
|
2527
|
+
* @param {Partial<TransportRecord>} [extra] - Campos extra a mergear en el record
|
|
2528
|
+
* (p.ej. `{ tag: 'success' }` o `attributes` adicionales)
|
|
2529
|
+
*/
|
|
1678
2530
|
dispatchToTransports(level, message, prefix, stackInfo, extra) {
|
|
1679
2531
|
const record = {
|
|
1680
2532
|
level,
|
|
@@ -1706,37 +2558,23 @@ var Logger = class Logger {
|
|
|
1706
2558
|
return parts.length > 0 ? parts.join(":") : void 0;
|
|
1707
2559
|
}
|
|
1708
2560
|
/**
|
|
1709
|
-
* Método central de logging.
|
|
1710
|
-
*
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
* Fire-and-forget callers (e.g. `logger.info(...)` without `await`)
|
|
1714
|
-
* still work — the resulting `Promise<void>` is dropped on the floor.
|
|
1715
|
-
* Awaiting is recommended when `beforeLog` hooks mutate `message`
|
|
1716
|
-
* (e.g. PII redaction, correlation IDs).
|
|
2561
|
+
* Método central de logging. Espera el hook pipeline `beforeLog`
|
|
2562
|
+
* antes de despachar a consola y transports, para que redacciones
|
|
2563
|
+
* o enriquecimientos (PII, correlation IDs) se reflejen en el
|
|
2564
|
+
* mensaje emitido.
|
|
1717
2565
|
*
|
|
1718
|
-
*
|
|
1719
|
-
*
|
|
1720
|
-
*
|
|
1721
|
-
* @returns Promise that resolves once the record has been dispatched
|
|
1722
|
-
*
|
|
1723
|
-
*/
|
|
1724
|
-
/**
|
|
1725
|
-
* Protected logging method. Awaits the `beforeLog` hook pipeline
|
|
1726
|
-
* synchronously (so redactions / enrichments are reflected in the
|
|
1727
|
-
* emitted message before console + transport dispatch).
|
|
2566
|
+
* Los callers fire-and-forget (p.ej. `logger.info(...)` sin `await`)
|
|
2567
|
+
* siguen funcionando: el `Promise<void>` resultante se descarta.
|
|
2568
|
+
* Se recomienda `await` cuando los hooks `beforeLog` mutan `message`.
|
|
1728
2569
|
*
|
|
1729
|
-
*
|
|
1730
|
-
*
|
|
1731
|
-
*
|
|
1732
|
-
* (e.g. PII redaction, correlation IDs).
|
|
2570
|
+
* El tag opcional (`TransportRecord.tag`) NO se pasa como argumento:
|
|
2571
|
+
* se establece vía `_dispatchTag` (ver `success()` y
|
|
2572
|
+
* {@link logWithBindingsAndTag}) antes de invocar este método.
|
|
1733
2573
|
*
|
|
1734
2574
|
* @protected
|
|
1735
|
-
* @param level - Nivel del log
|
|
1736
|
-
* @param args - Argumentos a loggear
|
|
1737
|
-
* @
|
|
1738
|
-
* `TransportRecord.tag` (e.g. `'success'` for success records).
|
|
1739
|
-
* @returns Promise that resolves once the record has been dispatched
|
|
2575
|
+
* @param {LogLevel} level - Nivel del log
|
|
2576
|
+
* @param {unknown[]} args - Argumentos a loggear (mensaje + datos)
|
|
2577
|
+
* @returns {Promise<void>} Promesa que resuelve al completar el dispatch
|
|
1740
2578
|
*
|
|
1741
2579
|
*/
|
|
1742
2580
|
async log(level, ...args) {
|
|
@@ -1786,6 +2624,22 @@ var Logger = class Logger {
|
|
|
1786
2624
|
else this.dispatchToTransports(level, message, prefix, stackInfo);
|
|
1787
2625
|
this.hookBridge.getHookManager().emit("afterLog", processed).catch(() => {});
|
|
1788
2626
|
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Emite un log aplicando bindings (badges, scope) al prefijo del
|
|
2629
|
+
* mensaje antes de delegar en {@link Logger.log}.
|
|
2630
|
+
*
|
|
2631
|
+
* No es API pública de consumo: existe para que `ScopedLogger`
|
|
2632
|
+
* (`component()` / `api()` / `scope()`) pueda reutilizar el pipeline
|
|
2633
|
+
* central de `log()` sin duplicar la lógica de styling/badges.
|
|
2634
|
+
*
|
|
2635
|
+
* @internal
|
|
2636
|
+
* @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)
|
|
2637
|
+
* @param {LogLevel} level - Nivel de log
|
|
2638
|
+
* @param {unknown[]} args - Argumentos a loggear
|
|
2639
|
+
* @returns {Promise<void>} Promesa del dispatch
|
|
2640
|
+
*
|
|
2641
|
+
* @see {@link logWithBindingsAndTag} para la variante con `tag`
|
|
2642
|
+
*/
|
|
1789
2643
|
logWithBindings(bindings, level, ...args) {
|
|
1790
2644
|
if (!this.shouldLog(level)) return Promise.resolve();
|
|
1791
2645
|
let prefix = "";
|
|
@@ -1796,19 +2650,45 @@ var Logger = class Logger {
|
|
|
1796
2650
|
return this.log(level, ...args);
|
|
1797
2651
|
}
|
|
1798
2652
|
/**
|
|
1799
|
-
*
|
|
1800
|
-
* `log()`
|
|
1801
|
-
*
|
|
2653
|
+
* Como {@link logWithBindings} pero fija `_dispatchTag` antes de
|
|
2654
|
+
* delegar, para que `log()` despache el `TransportRecord` con el
|
|
2655
|
+
* tag indicado. Lo usa `ScopedLogger.success()` para propagar
|
|
2656
|
+
* `tag: 'success'` a través del pipeline normal de `log()`.
|
|
2657
|
+
*
|
|
2658
|
+
* @internal
|
|
2659
|
+
* @param {Bindings} bindings - Bindings de scope (badges, scope name, ...)
|
|
2660
|
+
* @param {LogLevel} level - Nivel de log
|
|
2661
|
+
* @param {LogTag} tag - Tag a inyectar en el `TransportRecord`
|
|
2662
|
+
* @param {unknown[]} args - Argumentos a loggear
|
|
2663
|
+
* @returns {Promise<void>} Promesa del dispatch
|
|
1802
2664
|
*/
|
|
1803
2665
|
logWithBindingsAndTag(bindings, level, tag, ...args) {
|
|
1804
2666
|
this._dispatchTag = tag;
|
|
1805
2667
|
return this.logWithBindings(bindings, level, ...args);
|
|
1806
2668
|
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Registra mensajes de debug (nivel más verboso junto a `trace`).
|
|
2671
|
+
* Pensado para diagnóstico de desarrollo: valores intermedios, flags
|
|
2672
|
+
* de control flow, estado interno. Devuelve `Promise<void>`.
|
|
2673
|
+
*
|
|
2674
|
+
* Filtrado por defecto cuando `verbosity > 'debug'` (ver `setVerbosity`).
|
|
2675
|
+
*
|
|
2676
|
+
* @param {unknown[]} args - Mensaje + datos a inspeccionar
|
|
2677
|
+
* @returns {Promise<void>} Promesa del dispatch
|
|
2678
|
+
*
|
|
2679
|
+
* @example
|
|
2680
|
+
* logger.debug('Estado interno:', { conn, queueSize });
|
|
2681
|
+
* logger.debug('Entrando en branch X');
|
|
2682
|
+
*
|
|
2683
|
+
* @see {@link trace} para diagnósticos aún más granulares
|
|
2684
|
+
* @see {@link setVerbosity} para controlar el nivel mínimo visible
|
|
2685
|
+
*/
|
|
1807
2686
|
debug(...args) {
|
|
1808
2687
|
return this.log("debug", ...args);
|
|
1809
2688
|
}
|
|
1810
2689
|
/**
|
|
1811
|
-
* Registra mensajes informativos.
|
|
2690
|
+
* Registra mensajes informativos. El `await` retorna cuando el hook
|
|
2691
|
+
* `beforeLog` y el dispatch a transports han terminado.
|
|
1812
2692
|
*
|
|
1813
2693
|
* @param args - Mensajes y datos informativos
|
|
1814
2694
|
*
|
|
@@ -1821,7 +2701,7 @@ var Logger = class Logger {
|
|
|
1821
2701
|
return this.log("info", ...args);
|
|
1822
2702
|
}
|
|
1823
2703
|
/**
|
|
1824
|
-
* Registra mensajes de advertencia.
|
|
2704
|
+
* Registra mensajes de advertencia.
|
|
1825
2705
|
*
|
|
1826
2706
|
* @param args - Mensajes de advertencia
|
|
1827
2707
|
*
|
|
@@ -1830,7 +2710,7 @@ var Logger = class Logger {
|
|
|
1830
2710
|
return this.log("warn", ...args);
|
|
1831
2711
|
}
|
|
1832
2712
|
/**
|
|
1833
|
-
* Registra mensajes de error.
|
|
2713
|
+
* Registra mensajes de error.
|
|
1834
2714
|
*
|
|
1835
2715
|
* @param args - Mensaje de error y stack traces
|
|
1836
2716
|
*
|
|
@@ -1910,7 +2790,7 @@ var Logger = class Logger {
|
|
|
1910
2790
|
this.log("trace", ...args);
|
|
1911
2791
|
}
|
|
1912
2792
|
/**
|
|
1913
|
-
* Registra errores críticos (prioridad más alta).
|
|
2793
|
+
* Registra errores críticos (prioridad más alta).
|
|
1914
2794
|
*
|
|
1915
2795
|
* @param args - Errores críticos del sistema
|
|
1916
2796
|
*
|
|
@@ -2030,7 +2910,7 @@ var Logger = class Logger {
|
|
|
2030
2910
|
* Finaliza un temporizador y muestra el tiempo transcurrido
|
|
2031
2911
|
*
|
|
2032
2912
|
* @param {string} label - Etiqueta del temporizador a finalizar
|
|
2033
|
-
* @returns {number}
|
|
2913
|
+
* @returns {number} Milisegundos transcurridos, o `-1` si no se encuentra el timer
|
|
2034
2914
|
*
|
|
2035
2915
|
* @example
|
|
2036
2916
|
* logger.time('consulta-db');
|
|
@@ -2152,11 +3032,11 @@ var Logger = class Logger {
|
|
|
2152
3032
|
} });
|
|
2153
3033
|
}
|
|
2154
3034
|
/**
|
|
2155
|
-
*
|
|
3035
|
+
* Muestra un indicador de progreso de pasos en la terminal
|
|
2156
3036
|
*
|
|
2157
|
-
* @param {number} current -
|
|
2158
|
-
* @param {number} total -
|
|
2159
|
-
* @param {string} message -
|
|
3037
|
+
* @param {number} current - Número de paso actual
|
|
3038
|
+
* @param {number} total - Número total de pasos
|
|
3039
|
+
* @param {string} message - Descripción del paso
|
|
2160
3040
|
*
|
|
2161
3041
|
* @example
|
|
2162
3042
|
* logger.step(1, 5, 'Analyzing repository...');
|
|
@@ -2167,10 +3047,10 @@ var Logger = class Logger {
|
|
|
2167
3047
|
this.terminalBridge.step(current, total, message);
|
|
2168
3048
|
}
|
|
2169
3049
|
/**
|
|
2170
|
-
*
|
|
3050
|
+
* Muestra un header con estilo y subtítulo opcional
|
|
2171
3051
|
*
|
|
2172
|
-
* @param {string} title -
|
|
2173
|
-
* @param {string} subtitle -
|
|
3052
|
+
* @param {string} title - Texto del título principal
|
|
3053
|
+
* @param {string} subtitle - Subtítulo opcional (se renderiza atenuado)
|
|
2174
3054
|
*
|
|
2175
3055
|
* @example
|
|
2176
3056
|
* logger.header('Commit Wizard', 'v2.0.0');
|
|
@@ -2180,7 +3060,7 @@ var Logger = class Logger {
|
|
|
2180
3060
|
this.terminalBridge.header(title, subtitle);
|
|
2181
3061
|
}
|
|
2182
3062
|
/**
|
|
2183
|
-
*
|
|
3063
|
+
* Muestra una línea divisoria horizontal
|
|
2184
3064
|
*
|
|
2185
3065
|
* @example
|
|
2186
3066
|
* logger.divider();
|
|
@@ -2190,7 +3070,7 @@ var Logger = class Logger {
|
|
|
2190
3070
|
this.terminalBridge.divider();
|
|
2191
3071
|
}
|
|
2192
3072
|
/**
|
|
2193
|
-
*
|
|
3073
|
+
* Emite una línea en blanco
|
|
2194
3074
|
*
|
|
2195
3075
|
* @example
|
|
2196
3076
|
* logger.blank();
|
|
@@ -2200,10 +3080,10 @@ var Logger = class Logger {
|
|
|
2200
3080
|
this.terminalBridge.blank();
|
|
2201
3081
|
}
|
|
2202
3082
|
/**
|
|
2203
|
-
*
|
|
3083
|
+
* Renderiza contenido dentro de un box con borde
|
|
2204
3084
|
*
|
|
2205
|
-
* @param {string} content -
|
|
2206
|
-
* @param {IBoxOptions} options -
|
|
3085
|
+
* @param {string} content - String de contenido (puede contener newlines)
|
|
3086
|
+
* @param {IBoxOptions} options - Opciones de renderizado del box
|
|
2207
3087
|
*
|
|
2208
3088
|
* @example
|
|
2209
3089
|
* logger.box('3 commits generated\nProvider: Groq', { title: 'Done', borderColor: '#00ff00' });
|
|
@@ -2213,11 +3093,11 @@ var Logger = class Logger {
|
|
|
2213
3093
|
this.terminalBridge.box(content, options);
|
|
2214
3094
|
}
|
|
2215
3095
|
/**
|
|
2216
|
-
*
|
|
2217
|
-
*
|
|
3096
|
+
* Renderiza un array de objetos como una tabla ASCII formateada.
|
|
3097
|
+
* Distinto del método `table()` existente, que usa `console.table`.
|
|
2218
3098
|
*
|
|
2219
|
-
* @param {Record<string, unknown>[]} rows - Array
|
|
2220
|
-
* @param {ITableOptions} options -
|
|
3099
|
+
* @param {Record<string, unknown>[]} rows - Array de objetos fila
|
|
3100
|
+
* @param {ITableOptions} options - Opciones de renderizado de la tabla
|
|
2221
3101
|
*
|
|
2222
3102
|
* @example
|
|
2223
3103
|
* logger.cliTable([
|
|
@@ -2230,11 +3110,11 @@ var Logger = class Logger {
|
|
|
2230
3110
|
this.terminalBridge.cliTable(rows, options);
|
|
2231
3111
|
}
|
|
2232
3112
|
/**
|
|
2233
|
-
*
|
|
2234
|
-
*
|
|
3113
|
+
* Crea un handle de spinner para mostrar progreso durante operaciones async.
|
|
3114
|
+
* Devuelve un `NoopSpinner` en entornos non-TTY.
|
|
2235
3115
|
*
|
|
2236
|
-
* @param {string} message -
|
|
2237
|
-
* @returns {ISpinnerHandle}
|
|
3116
|
+
* @param {string} message - Texto inicial del spinner
|
|
3117
|
+
* @returns {ISpinnerHandle} Controller del spinner
|
|
2238
3118
|
*
|
|
2239
3119
|
* @example
|
|
2240
3120
|
* const s = logger.spinner('Analyzing repository...');
|
|
@@ -2247,13 +3127,14 @@ var Logger = class Logger {
|
|
|
2247
3127
|
return this.terminalBridge.spinner(message);
|
|
2248
3128
|
}
|
|
2249
3129
|
/**
|
|
2250
|
-
*
|
|
3130
|
+
* Fija el nivel de verbosidad del CLI, controlando a la vez la verbosidad
|
|
3131
|
+
* de logs y la visibilidad de las primitives
|
|
2251
3132
|
*
|
|
2252
|
-
* @param {CLILogLevel} level -
|
|
3133
|
+
* @param {CLILogLevel} level - Nivel de log del CLI
|
|
2253
3134
|
*
|
|
2254
3135
|
* @example
|
|
2255
|
-
* logger.setCLILevel('quiet'); //
|
|
2256
|
-
* logger.setCLILevel('verbose'); // Debug logs +
|
|
3136
|
+
* logger.setCLILevel('quiet'); // Solo errors, sin CLI primitives
|
|
3137
|
+
* logger.setCLILevel('verbose'); // Debug logs + todas las CLI primitives
|
|
2257
3138
|
*
|
|
2258
3139
|
*/
|
|
2259
3140
|
setCLILevel(level) {
|
|
@@ -2263,21 +3144,21 @@ var Logger = class Logger {
|
|
|
2263
3144
|
this.config.cliLevel = level;
|
|
2264
3145
|
}
|
|
2265
3146
|
/**
|
|
2266
|
-
*
|
|
2267
|
-
* @returns {CLILogLevel}
|
|
3147
|
+
* Devuelve el nivel de log del CLI actual
|
|
3148
|
+
* @returns {CLILogLevel} Nivel de log del CLI actual
|
|
2268
3149
|
*/
|
|
2269
3150
|
get cliLevel() {
|
|
2270
3151
|
return this.config.cliLevel ?? "normal";
|
|
2271
3152
|
}
|
|
2272
3153
|
/**
|
|
2273
|
-
*
|
|
2274
|
-
*
|
|
3154
|
+
* Escribe output formateado al destino configurado.
|
|
3155
|
+
* Respeta la configuración `outputMode` para output a consola, silencioso o custom.
|
|
2275
3156
|
*
|
|
2276
3157
|
* @private
|
|
2277
|
-
* @param {string} message -
|
|
2278
|
-
* @param {LogLevel} level -
|
|
2279
|
-
* @param {string[]} styles - CSS
|
|
2280
|
-
* @param {unknown[]} additionalArgs -
|
|
3158
|
+
* @param {string} message - Mensaje de log formateado
|
|
3159
|
+
* @param {LogLevel} level - Nivel de log
|
|
3160
|
+
* @param {string[]} styles - Estilos CSS para la consola del navegador
|
|
3161
|
+
* @param {unknown[]} additionalArgs - Argumentos adicionales a loggear
|
|
2281
3162
|
*/
|
|
2282
3163
|
writeOutput(message, level, styles, additionalArgs) {
|
|
2283
3164
|
const mode = this.config.outputMode ?? "console";
|
|
@@ -2317,21 +3198,20 @@ var Logger = class Logger {
|
|
|
2317
3198
|
}
|
|
2318
3199
|
};
|
|
2319
3200
|
/**
|
|
2320
|
-
|
|
2321
|
-
*
|
|
2322
|
-
* not on module import. Fixes BUG-N11 (eager side-effect at import time).
|
|
3201
|
+
* Instancia singleton lazy — se inicializa en la primera llamada a
|
|
3202
|
+
* {@link getDefaultLogger}, no al importar el módulo.
|
|
2323
3203
|
*
|
|
2324
3204
|
* @private
|
|
2325
3205
|
*/
|
|
2326
3206
|
let _defaultLogger = null;
|
|
2327
3207
|
/**
|
|
2328
|
-
*
|
|
3208
|
+
* Crea el singleton del Logger por defecto de forma lazy.
|
|
2329
3209
|
*
|
|
2330
|
-
*
|
|
2331
|
-
*
|
|
2332
|
-
*
|
|
3210
|
+
* El singleton se construye solo en la primera llamada, de modo que
|
|
3211
|
+
* importar el módulo nunca ejecuta `new Logger(...)` ni
|
|
3212
|
+
* `displayInitBanner()`. Así los imports del módulo quedan side-effect free.
|
|
2333
3213
|
*
|
|
2334
|
-
* @returns
|
|
3214
|
+
* @returns La instancia compartida de Logger
|
|
2335
3215
|
*/
|
|
2336
3216
|
function getDefaultLogger() {
|
|
2337
3217
|
if (!_defaultLogger) {
|
|
@@ -2354,12 +3234,12 @@ new Proxy({}, { get(_target, prop, receiver) {
|
|
|
2354
3234
|
return typeof value === "function" ? value.bind(instance) : value;
|
|
2355
3235
|
} });
|
|
2356
3236
|
/**
|
|
2357
|
-
*
|
|
2358
|
-
* `ILogAttributes
|
|
2359
|
-
*
|
|
3237
|
+
* Estrecha un contexto free-form `Record<string, unknown>` a un bag tipado
|
|
3238
|
+
* `ILogAttributes`. Los shapes desconocidos caen a strings JSON-encoded,
|
|
3239
|
+
* lo que mantiene conforme al transport OTLP (cada valor cae en un slot tipado).
|
|
2360
3240
|
*
|
|
2361
|
-
* @param input -
|
|
2362
|
-
* @returns
|
|
3241
|
+
* @param input - Contexto suministrado por el usuario (típicamente `Logger.context`).
|
|
3242
|
+
* @returns Un nuevo bag de attributes que satisface `ILogAttributes`.
|
|
2363
3243
|
*/
|
|
2364
3244
|
function toLogAttributes(input) {
|
|
2365
3245
|
const out = {};
|