@jmlq/logger 0.1.0-alpha.2 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +347 -0
  2. package/dist/application/use-cases/flush-buffers.d.ts +6 -0
  3. package/dist/application/use-cases/flush-buffers.js +13 -0
  4. package/dist/application/use-cases/get-logs.d.ts +7 -0
  5. package/dist/application/use-cases/get-logs.js +24 -0
  6. package/dist/application/use-cases/index.d.ts +3 -0
  7. package/dist/application/use-cases/index.js +19 -0
  8. package/dist/application/use-cases/save-log.d.ts +13 -0
  9. package/dist/application/use-cases/save-log.js +30 -0
  10. package/dist/domain/contracts/index.d.ts +3 -0
  11. package/dist/domain/contracts/index.js +19 -0
  12. package/dist/domain/contracts/log.datasource.d.ts +8 -0
  13. package/dist/{config/interfaces/index.js → domain/contracts/log.datasource.js} +0 -1
  14. package/dist/domain/contracts/logger.d.ts +19 -0
  15. package/dist/domain/contracts/logger.js +2 -0
  16. package/dist/domain/contracts/pii.d.ts +5 -0
  17. package/dist/domain/contracts/pii.js +2 -0
  18. package/dist/domain/services/pii-redactor.d.ts +7 -24
  19. package/dist/domain/services/pii-redactor.js +55 -117
  20. package/dist/domain/types/index.d.ts +1 -0
  21. package/dist/{presentation → domain/types}/index.js +1 -1
  22. package/dist/domain/types/log.types.d.ts +28 -0
  23. package/dist/domain/types/log.types.js +2 -0
  24. package/dist/domain/value-objects/index.d.ts +1 -0
  25. package/dist/domain/{index.js → value-objects/index.js} +1 -1
  26. package/dist/domain/value-objects/log-level.d.ts +9 -0
  27. package/dist/domain/value-objects/log-level.js +37 -0
  28. package/dist/index.d.ts +5 -4
  29. package/dist/index.js +8 -18
  30. package/dist/infrastructure/adapters/composite.datasource.d.ts +11 -0
  31. package/dist/infrastructure/adapters/composite.datasource.js +46 -0
  32. package/dist/infrastructure/adapters/index.d.ts +1 -0
  33. package/dist/{config → infrastructure/adapters}/index.js +1 -2
  34. package/dist/presentation/factory/create-logger.d.ts +2 -0
  35. package/dist/presentation/factory/create-logger.js +29 -0
  36. package/dist/presentation/factory/index.d.ts +1 -2
  37. package/dist/presentation/factory/index.js +15 -72
  38. package/package.json +14 -2
  39. package/dist/Composite/index.d.ts +0 -9
  40. package/dist/Composite/index.js +0 -54
  41. package/dist/Factory/index.d.ts +0 -5
  42. package/dist/Factory/index.js +0 -23
  43. package/dist/config/index.d.ts +0 -2
  44. package/dist/config/interfaces/index.d.ts +0 -67
  45. package/dist/config/types/index.d.ts +0 -10
  46. package/dist/config/types/index.js +0 -13
  47. package/dist/domain/index.d.ts +0 -1
  48. package/dist/interfaces/index.d.ts +0 -35
  49. package/dist/interfaces/index.js +0 -13
  50. package/dist/presentation/index.d.ts +0 -1
package/README.md ADDED
@@ -0,0 +1,347 @@
1
+ # @jmlq/logger
2
+
3
+ Paquete de `logging` extensible y desacoplado, diseñado con principios de Arquitectura Limpia.
4
+ Permite registrar logs en múltiples destinos (`archivos`, `MongoDB`, `PostgreSQL`) mediante **plugins** y soporta enmascarado de datos sensibles (PII).
5
+
6
+ ---
7
+
8
+ ## 📦 Instalación
9
+
10
+ ```bash
11
+ # Instalar el core
12
+ npm i @jmlq/logger
13
+
14
+ # Instalar plugins opcionales según el backend de persistencia
15
+ npm i @jmlq/logger-plugin-fs
16
+ npm i @jmlq/logger-plugin-mongo
17
+ npm i @jmlq/logger-plugin-postgres
18
+
19
+ ```
20
+
21
+ Si usas Mongo o Postgres en tu app cliente, instala además:
22
+
23
+ ```bash
24
+ npm i mongodb@^6.19.0
25
+ npm i pg@^8.16.3
26
+
27
+ ```
28
+
29
+ ### DOCUMENTACION
30
+
31
+ > - [`@jmlq/logger-plugin-fs`](https://www.npmjs.com/package/@jmlq/logger-plugin-fs)
32
+ > - [`@jmlq/logger-plugin-mongo`](https://www.npmjs.com/package/@jmlq/logger-plugin-mongo)
33
+ > - [`@jmlq/logger-plugin-postgres`](https://www.npmjs.com/package/@jmlq/logger-plugin-postgres)
34
+
35
+ ---
36
+
37
+ ## 🧱 Estructura del paquete
38
+
39
+ ### 📝 Resumen rápido
40
+
41
+ > - **`src/domain/`** — Reglas del negocio (sin dependencias de frameworks).
42
+ > > - **`value-objects/`**
43
+ > > > - `log-level.ts` — Define niveles (`TRACE…FATAL`) y `toLogLevel()` para convertir strings a nivel.
44
+ > > - **`types/`**
45
+ > > > - `log.types.ts` — Tipos puros del dominio: `ILog`, `IGetLogsFilter`, `PiiOptions`, etc.
46
+ > > - **`contracts/`**
47
+ > > > - `log.datasource.ts` — Puerto que debe implementar cualquier destino de logs (`save/find/flush/dispose`).
48
+ > > > - `logger.ts` — Contrato del logger público (`ILogger`, `ICreateLoggerOptions`).
49
+ > > > - `pii.ts` — Contrato del redactor de PII.
50
+ > > - **`services/`**
51
+ > > > - `pii-redactor.ts` — Enmascarado de datos sensibles (whitelist/blacklist, patrones, modo profundo).
52
+
53
+ > - **`src/application/`** — Orquestación de casos de uso (no depende de infraestructura).
54
+ > > - **`use-cases/`**
55
+ > > > - `save-log.ts` — Aplica `minLevel` + PII y delega a `datasource.save()`.
56
+ > > > - `get-logs.ts` — Recupera logs con filtros/paginación si el datasource lo soporta.
57
+ > > > - `flush-buffers.ts` — Ejecuta `flush()` en el datasource cuando exista.
58
+
59
+ > - **`src/infrastructure/`** — Adaptadores concretos (tecnología).
60
+ > > - **`adapters/`**
61
+ > > > - `composite.datasource.ts` — Fan-out: envía el log a varios datasources y no falla el todo si uno cae (avisa con `console.warn`).
62
+
63
+ > - **`src/presentation/`** — API pública y fábricas (cara del paquete).
64
+ > > - **`factory/`**
65
+ > > > - `create-logger.ts` — Crea el logger listo para usar (`trace…fatal`, `flush`, `dispose`) conectando casos de uso + PII.
66
+
67
+ > - **`src/index.ts`** — Barrel.
68
+ > > - Re-exporta lo público: `createLogger`, `LogLevel`, tipos/contratos y `CompositeDatasource`.
69
+
70
+ ### [](./ARQUITECTURA.md)
71
+
72
+ ---
73
+
74
+ ## 🧩 Configuración
75
+
76
+ ### 🔐 Variables de Entorno (.env)
77
+
78
+ ```ini
79
+ # --- MongoDB ---
80
+ MONGO_URL=mongodb://<usuario>:<password>@localhost:27017
81
+ # Dirección de conexión a MongoDB (usuario/contraseña opcionales)
82
+ MONGO_DB_NAME=my_database
83
+ # Nombre de la base de datos donde se guardarán los logs
84
+
85
+
86
+ # --- PostgreSQL ---
87
+ POSTGRES_URL=postgresql://<usuario>:<password>@localhost:5432/my_database
88
+ # URL de conexión a la base de datos principal
89
+ POSTGRES_DB=my_database
90
+ # Credenciales y nombre de la base de datos
91
+
92
+ # --- FileSystem ---
93
+ LOGGER_FS_PATH=./logs/app.log
94
+ # Ruta local donde se almacenarán los logs en formato JSONL
95
+
96
+ # --- Nivel de logging ---
97
+ LOGGER_LEVEL=debug
98
+ # Nivel mínimo de logs por entorno (dev: debug, prod: warn)
99
+
100
+ # --- PII (enmascarado de datos sensibles) ---
101
+ LOGGER_PII_ENABLED=true
102
+ # Activa/desactiva el redactor de datos sensibles
103
+
104
+ LOGGER_PII_INCLUDE_DEFAULTS=true
105
+ # Incluye los patrones de PII por defecto además de los definidos por el cliente
106
+
107
+ ```
108
+
109
+ ---
110
+
111
+ ### 🚀 Uso del paquete
112
+
113
+ El cliente (la aplicación que usa `@jmlq/logger`) es responsable de inicializar el logger, ensamblar los **datasources** (`FS`, `Mongo`, `Postgres`) y configurar el **redactor de PII**.
114
+
115
+ #### 1) Configuración de `pii.ts`
116
+
117
+ Se definen los patrones propios de la aplicación para enmascarar datos sensibles.
118
+ Estos se combinan con los patrones por defecto del core (`LOGGER_PII_INCLUDE_DEFAULTS=true`).
119
+
120
+ ```ts
121
+ // src/config/logger/pii.ts
122
+
123
+ import type { IPiiPattern } from "@jmlq/logger";
124
+
125
+ // Patrones PII propios del cliente
126
+ export const clientPiiPatterns: IPiiPattern[] = [
127
+ {
128
+ // Ejemplo: cédula ecuatoriana (10 dígitos con validaciones)
129
+ regex: /\b\d{10}\b/g,
130
+ replacement: "[REDACTED_CEDULA]",
131
+ },
132
+ {
133
+ // Ejemplo: token JWT simulado
134
+ regex: /\beyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]+\b/g,
135
+ replacement: "[REDACTED_JWT]",
136
+ },
137
+ ];
138
+
139
+ // Claves a redactar siempre (aunque no hagan match con regex)
140
+ export const redactKeys = ["password", "secret", "token"];
141
+
142
+ // Claves a preservar (no se enmascaran aunque coincidan con regex)
143
+ export const preserveKeys = ["city"];
144
+ ```
145
+
146
+ #### 2) Inicialización de `logger/index.ts`
147
+
148
+ El logger se ensambla en un archivo central, cargando variables de entorno y adaptadores según disponibilidad:
149
+
150
+ ```tsx
151
+ // src/config/logger/index.ts
152
+
153
+ // Importa las funciones y tipos principales del core del logger
154
+ import { createLogger, LogLevel, CompositeDatasource } from "@jmlq/logger";
155
+
156
+ // Importa los plugins disponibles para persistencia de logs
157
+ import { FileSystemDatasource } from "@jmlq/logger-plugin-fs";
158
+ import { MongoDatasource } from "@jmlq/logger-plugin-mongo";
159
+ import {
160
+ connectPostgres,
161
+ ensurePostgresSchema,
162
+ PostgresDatasource,
163
+ } from "@jmlq/logger-plugin-postgres";
164
+
165
+ // Configuración cargada desde variables de entorno (env-var + dotenv)
166
+ import { envs } from "../plugins/envs.plugin";
167
+
168
+ // Patrones propios de PII definidos en src/config/logger/pii.ts
169
+ import { clientPiiPatterns, redactKeys, preserveKeys } from "./pii";
170
+
171
+ // Utilidades de Node.js para manejo de directorios y archivos
172
+ import { mkdirSync, existsSync } from "node:fs";
173
+ import { dirname } from "node:path";
174
+
175
+ // Cliente oficial de MongoDB
176
+ import { MongoClient } from "mongodb";
177
+
178
+ // Se mantiene una referencia global al cliente de MongoDB para cerrarlo en dispose
179
+ let mongoClient: MongoClient | null = null;
180
+
181
+ // Convierte un string (ej. "debug") al enum LogLevel
182
+ function toMinLevel(level: string): LogLevel {
183
+ switch (level.toLowerCase()) {
184
+ case "trace":
185
+ return LogLevel.TRACE;
186
+ case "debug":
187
+ return LogLevel.DEBUG;
188
+ case "info":
189
+ return LogLevel.INFO;
190
+ case "warn":
191
+ return LogLevel.WARN;
192
+ case "error":
193
+ return LogLevel.ERROR;
194
+ case "fatal":
195
+ return LogLevel.FATAL;
196
+ default:
197
+ return LogLevel.INFO; // Valor por defecto
198
+ }
199
+ }
200
+
201
+ // Asegura que exista el directorio de logs para el datasource de FileSystem
202
+ function ensureDirFor(filePath: string) {
203
+ const dir = dirname(filePath);
204
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
205
+ }
206
+
207
+ // Inicializa el logger ensamblando los datasources configurados en .env
208
+ async function initLogger() {
209
+ const datasources = [];
210
+
211
+ // --- FileSystem ---
212
+ // Si está definido LOGGER_FS_PATH, se usa un datasource local de archivos
213
+ if (envs.logger.LOGGER_FS_PATH) {
214
+ ensureDirFor(envs.logger.LOGGER_FS_PATH);
215
+ datasources.push(
216
+ new FileSystemDatasource({ filePath: envs.logger.LOGGER_FS_PATH })
217
+ );
218
+ }
219
+
220
+ // --- MongoDB ---
221
+ // Si están configurados MONGO_URL y MONGO_DB_NAME, se conecta y usa la colección logs
222
+ if (envs.logger.MONGO_URL && envs.logger.MONGO_DB_NAME) {
223
+ mongoClient = new MongoClient(envs.logger.MONGO_URL);
224
+ await mongoClient.connect();
225
+ const coll = mongoClient.db(envs.logger.MONGO_DB_NAME).collection("logs");
226
+ datasources.push(new MongoDatasource(coll));
227
+ }
228
+
229
+ // --- PostgreSQL ---
230
+ // Si está configurado POSTGRES_URL, se conecta, asegura la tabla y crea el datasource
231
+ if (envs.logger.POSTGRES_URL) {
232
+ await connectPostgres(envs.logger.POSTGRES_URL);
233
+ await ensurePostgresSchema();
234
+ datasources.push(new PostgresDatasource("logs"));
235
+ }
236
+
237
+ // Si hay más de un datasource, se compone con CompositeDatasource (fan-out)
238
+ const datasource =
239
+ datasources.length === 1
240
+ ? datasources[0]
241
+ : new CompositeDatasource(datasources);
242
+
243
+ // Crea y retorna el logger con nivel mínimo y configuración de PII
244
+ return createLogger(datasource, {
245
+ minLevel: toMinLevel(envs.logger.LOGGER_LEVEL),
246
+ pii: {
247
+ enabled: envs.logger.LOGGER_PII_ENABLED,
248
+ includeDefaultPatterns: envs.logger.LOGGER_PII_INCLUDE_DEFAULTS,
249
+ patterns: clientPiiPatterns,
250
+ redactKeys,
251
+ preserveKeys,
252
+ },
253
+ });
254
+ }
255
+
256
+ // Exporta el logger como una Promise porque la inicialización es async
257
+ export const loggerReady = initLogger();
258
+
259
+ // --- Funciones de utilidad ---
260
+
261
+ // Fuerza un flush() de todos los datasources, útil para apagar servicios con logs pendientes
262
+ export async function flushLogs() {
263
+ const logger: any = await loggerReady;
264
+ if (typeof logger.flush === "function") await logger.flush();
265
+ }
266
+
267
+ // Cierra conexiones abiertas (ej. MongoClient) y libera recursos
268
+ export async function disposeLogs() {
269
+ const logger: any = await loggerReady;
270
+ if (typeof logger.dispose === "function") await logger.dispose();
271
+ if (mongoClient) await mongoClient.close();
272
+ }
273
+ ```
274
+
275
+ #### 3) Uso desde cualquier aplicación Node.js
276
+
277
+ En cualquier parte de la app se puede usar el logger así:
278
+
279
+ ```ts
280
+ import { loggerReady } from "./config/logger";
281
+
282
+ async function main() {
283
+ const logger = await loggerReady;
284
+
285
+ await logger.info("Aplicación iniciada", { pid: process.pid });
286
+
287
+ await logger.error("Error en proceso", {
288
+ password: "123456", // será redactado
289
+ city: "Quito", // se preserva
290
+ });
291
+ }
292
+
293
+ main();
294
+ ```
295
+
296
+ ### 🔎 Notas importantes
297
+
298
+ > - `loggerReady` es una Promise → debe resolverse con `await`.
299
+ > - `flushLogs()` y `disposeLogs()` deben usarse en procesos que cierran conexiones (ej. `SIGINT`, `SIGTERM`).
300
+ > - Los patrones definidos en `pii.ts` se combinan con los patrones por defecto cuando `LOGGER_PII_INCLUDE_DEFAULTS=true`.
301
+ > - El logger puede trabajar con **un único datasource** o con **CompositeDatasource** para múltiples.
302
+
303
+ ---
304
+
305
+ ### 🧪 Escenarios
306
+
307
+ > - **Solo FS** → logs locales en `./logs/app.log`.
308
+ > - **Solo MongoDB** → logs en colección `logs`.
309
+ > - **Solo PostgreSQL** → logs en tabla `logs`.
310
+ > - **Combinado** → fan-out a varios destinos simultáneamente.
311
+ > - **Extensión** → implementar `ILogDatasource`.
312
+
313
+ ---
314
+
315
+ ## 🧯 Troubleshooting
316
+
317
+ > - **No se inicializa ningún datasource** → definir al menos una variable (`LOGGER_FS_PATH`, `MONGO_URL`, `POSTGRES_URL`).
318
+ > - **MongoDB Auth** → incluir `authSource=admin` en la URL si se usan usuarios root.
319
+ > - **Postgres** → ejecutar `ensurePostgresSchema()` para crear tabla logs si no existe.
320
+ > - **Alto volumen de logs** → implementar `flush()` o batching en el datasource.
321
+
322
+ ---
323
+
324
+ ## 🧪 Tests
325
+
326
+ ```ts
327
+ import { createLogger, LogLevel } from "@jmlq/logger";
328
+ import { FileSystemDatasource } from "@jmlq/logger-plugin-fs";
329
+
330
+ test("logger redacta PII en FS", async () => {
331
+ const fsDs = new FileSystemDatasource({ filePath: "./logs/test.log" });
332
+ const logger = createLogger(fsDs, {
333
+ minLevel: LogLevel.DEBUG,
334
+ pii: { enabled: true },
335
+ });
336
+
337
+ await logger.info("Inicio de sesión", { user: "demo", password: "123456" });
338
+
339
+ // Luego verificar que el archivo test.log no contiene la contraseña en claro
340
+ });
341
+ ```
342
+
343
+ ---
344
+
345
+ ## 📄 Licencia
346
+
347
+ MIT © Mauricio Lahuasi
@@ -0,0 +1,6 @@
1
+ import { ILogDatasource } from "../../domain/contracts";
2
+ export declare class FlushBuffers {
3
+ private readonly ds;
4
+ constructor(ds: ILogDatasource);
5
+ execute(): Promise<void>;
6
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FlushBuffers = void 0;
4
+ class FlushBuffers {
5
+ constructor(ds) {
6
+ this.ds = ds;
7
+ }
8
+ async execute() {
9
+ // flush es opcional; si no está implementado, no hace nada
10
+ await this.ds.flush?.();
11
+ }
12
+ }
13
+ exports.FlushBuffers = FlushBuffers;
@@ -0,0 +1,7 @@
1
+ import { ILogDatasource } from "../../domain/contracts";
2
+ import { IGetLogsFilter, ILog } from "../../domain/types";
3
+ export declare class GetLogs {
4
+ private readonly ds;
5
+ constructor(ds: ILogDatasource);
6
+ execute(filter?: IGetLogsFilter): Promise<ILog[]>;
7
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetLogs = void 0;
4
+ class GetLogs {
5
+ constructor(ds) {
6
+ this.ds = ds;
7
+ }
8
+ async execute(filter) {
9
+ if (!this.ds.find)
10
+ return []; // si el datasource no lo soporta, retorna vacío
11
+ // Sanitiza límites (evita valores negativos o absurdos)
12
+ const safe = filter
13
+ ? {
14
+ ...filter,
15
+ limit: filter.limit && filter.limit > 0
16
+ ? Math.min(filter.limit, 5000)
17
+ : undefined,
18
+ offset: filter.offset && filter.offset >= 0 ? filter.offset : undefined,
19
+ }
20
+ : undefined;
21
+ return this.ds.find(safe);
22
+ }
23
+ }
24
+ exports.GetLogs = GetLogs;
@@ -0,0 +1,3 @@
1
+ export * from "./save-log";
2
+ export * from "./get-logs";
3
+ export * from "./flush-buffers";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./save-log"), exports);
18
+ __exportStar(require("./get-logs"), exports);
19
+ __exportStar(require("./flush-buffers"), exports);
@@ -0,0 +1,13 @@
1
+ import { ILogDatasource, IPiiRedactor } from "../../domain/contracts";
2
+ import { LogMessage } from "../../domain/types";
3
+ import { LogLevel } from "../../domain/value-objects";
4
+ export interface SaveLogDeps {
5
+ ds: ILogDatasource;
6
+ minLevel: LogLevel;
7
+ redactor: IPiiRedactor;
8
+ }
9
+ export declare class SaveLog {
10
+ private readonly deps;
11
+ constructor(deps: SaveLogDeps);
12
+ execute(level: LogLevel, message: LogMessage, meta?: unknown): Promise<void>;
13
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SaveLog = void 0;
4
+ // Normaliza el mensaje: si es función, la evalúa; si es objeto, se redacta; si es string, se redacta
5
+ function normalizeMessage(message, redactor) {
6
+ const resolved = typeof message === "function" ? message() : message; // eval laziness
7
+ return redactor.redact(resolved);
8
+ }
9
+ class SaveLog {
10
+ constructor(deps) {
11
+ this.deps = deps;
12
+ }
13
+ async execute(level, message, meta) {
14
+ // 1) Filtro por nivel (evita hacer trabajo innecesario)
15
+ if (level < this.deps.minLevel)
16
+ return; // no se loggea
17
+ // 2) Normalización + PII
18
+ const normalized = normalizeMessage(message, this.deps.redactor);
19
+ // 3) Construcción del evento
20
+ const log = {
21
+ level,
22
+ message: normalized,
23
+ meta: meta === undefined ? undefined : this.deps.redactor.redact(meta),
24
+ timestamp: Date.now(),
25
+ };
26
+ // 4) Persistencia (fan-out lo maneja el ds si es composite)
27
+ await this.deps.ds.save(log);
28
+ }
29
+ }
30
+ exports.SaveLog = SaveLog;
@@ -0,0 +1,3 @@
1
+ export * from "./log.datasource";
2
+ export * from "./logger";
3
+ export * from "./pii";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./log.datasource"), exports);
18
+ __exportStar(require("./logger"), exports);
19
+ __exportStar(require("./pii"), exports);
@@ -0,0 +1,8 @@
1
+ import { IGetLogsFilter, ILog } from "../types";
2
+ export interface ILogDatasource {
3
+ save(log: ILog): Promise<void>;
4
+ find?(filter?: IGetLogsFilter): Promise<ILog[]>;
5
+ flush?(): Promise<void>;
6
+ dispose?(): Promise<void>;
7
+ readonly name?: string;
8
+ }
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // ---- Contratos ----
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,19 @@
1
+ import { ILogDatasource } from ".";
2
+ import { PiiOptions } from "../types";
3
+ import { LogLevel } from "../value-objects";
4
+ export interface ICreateLoggerOptions {
5
+ minLevel?: LogLevel;
6
+ redactPII?: boolean;
7
+ pii?: PiiOptions;
8
+ }
9
+ export interface ILogger {
10
+ trace: (message: unknown, meta?: unknown) => void | Promise<void>;
11
+ debug: (message: unknown, meta?: unknown) => void | Promise<void>;
12
+ info: (message: unknown, meta?: unknown) => void | Promise<void>;
13
+ warn: (message: unknown, meta?: unknown) => void | Promise<void>;
14
+ error: (message: unknown, meta?: unknown) => void | Promise<void>;
15
+ fatal: (message: unknown, meta?: unknown) => void | Promise<void>;
16
+ flush?: () => Promise<void>;
17
+ dispose?: () => Promise<void>;
18
+ }
19
+ export type { ILogDatasource as LogDatasourcePort };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ import { PiiOptions } from "../types";
2
+ export interface IPiiRedactor {
3
+ redact<T = unknown>(value: T): T;
4
+ updateOptions?(opts: PiiOptions): void;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,27 +1,10 @@
1
- /**
2
- * Domain Service: PiiRedactor
3
- *
4
- * Propósito:
5
- * - Redactar/anonimizar PII en strings, objetos y arrays (deep).
6
- * - Permitir que el cliente pase patrones adicionales/propios.
7
- * - Controlar redacción por nombre de clave (whitelist/blacklist).
8
- */
9
- import { IPiiPattern, IPiiRedactorOptions } from "../../config";
10
- export declare class PiiRedactor {
11
- private readonly enabled;
12
- private readonly patterns;
13
- private readonly redactKeys;
14
- private readonly preserveKeys;
15
- constructor(opts?: IPiiRedactorOptions);
16
- /** Patrones por defecto (seguros y genéricos). Ajusta según tu dominio/región si lo deseas. */
17
- static defaultPatterns(): IPiiPattern[];
18
- /** Punto de entrada público: redacción deep de cualquier estructura */
1
+ import { IPiiRedactor } from "../contracts";
2
+ import { PiiOptions } from "../types";
3
+ export declare class PiiRedactor implements IPiiRedactor {
4
+ private options;
5
+ constructor(options?: PiiOptions);
6
+ updateOptions(opts: PiiOptions): void;
19
7
  redact<T = unknown>(value: T): T;
20
- /** === Internos === */
21
- private redactValue;
22
8
  private applyPatterns;
23
- private isRedactedKey;
24
- private isPreservedKey;
25
- private keyRedactionReplacement;
26
- private clone;
9
+ private redactDeep;
27
10
  }