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