@jmlq/logger 0.1.0-alpha.0 → 0.1.0-alpha.10
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 +307 -0
- package/architecture.md +171 -0
- package/dist/examples/data-source-service.example.d.ts +3 -0
- package/dist/examples/data-source-service.example.js +174 -0
- package/dist/examples/flush-buffers-use-case.example.d.ts +3 -0
- package/dist/examples/flush-buffers-use-case.example.js +60 -0
- package/dist/examples/get-logs-use-case.example.d.ts +3 -0
- package/dist/examples/get-logs-use-case.example.js +110 -0
- package/dist/examples/index.example.d.ts +8 -0
- package/dist/examples/index.example.js +116 -0
- package/dist/examples/logger-factory.example.d.ts +39 -0
- package/dist/examples/logger-factory.example.js +158 -0
- package/dist/examples/normalize-message.example.d.ts +3 -0
- package/dist/examples/normalize-message.example.js +80 -0
- package/dist/examples/pii-redactor.example.d.ts +3 -0
- package/dist/examples/pii-redactor.example.js +129 -0
- package/dist/examples/save-log-use-case.example.d.ts +3 -0
- package/dist/examples/save-log-use-case.example.js +150 -0
- package/dist/examples/to-log-level.example.d.ts +3 -0
- package/dist/examples/to-log-level.example.js +49 -0
- package/dist/examples/to-pii-regex.example.d.ts +3 -0
- package/dist/examples/to-pii-regex.example.js +75 -0
- package/dist/src/application/factory/create-logger.d.ts +2 -0
- package/dist/src/application/factory/create-logger.js +29 -0
- package/dist/src/application/factory/index.d.ts +1 -0
- package/dist/{index.js → src/application/factory/index.js} +1 -3
- package/dist/src/application/factory/logger.factory.d.ts +12 -0
- package/dist/src/application/factory/logger.factory.js +74 -0
- package/dist/src/application/index.d.ts +2 -0
- package/dist/src/application/index.js +18 -0
- package/dist/src/application/use-cases/flush-buffers.use-case.d.ts +6 -0
- package/dist/src/application/use-cases/flush-buffers.use-case.js +13 -0
- package/dist/src/application/use-cases/get-logs.use-case.d.ts +8 -0
- package/dist/src/application/use-cases/get-logs.use-case.js +24 -0
- package/dist/src/application/use-cases/index.d.ts +3 -0
- package/dist/src/application/use-cases/index.js +19 -0
- package/dist/src/application/use-cases/save-log.use-case.d.ts +8 -0
- package/dist/src/application/use-cases/save-log.use-case.js +26 -0
- package/dist/src/domain/index.d.ts +6 -0
- package/dist/src/domain/index.js +22 -0
- package/dist/src/domain/ports/create-logger-options.port.d.ts +7 -0
- package/dist/src/domain/ports/create-logger-options.port.js +2 -0
- package/dist/src/domain/ports/index.d.ts +6 -0
- package/dist/src/domain/ports/index.js +22 -0
- package/dist/src/domain/ports/log-datasource.port.d.ts +9 -0
- package/dist/src/domain/ports/log-datasource.port.js +2 -0
- package/dist/src/domain/ports/logger-factory-config.port.d.ts +28 -0
- package/dist/src/domain/ports/logger-factory-config.port.js +2 -0
- package/dist/src/domain/ports/logger-service.port.d.ts +19 -0
- package/dist/src/domain/ports/logger-service.port.js +2 -0
- package/dist/src/domain/ports/logger.port.d.ts +10 -0
- package/dist/src/domain/ports/logger.port.js +2 -0
- package/dist/src/domain/ports/pii-redactor.port.d.ts +5 -0
- package/dist/src/domain/ports/pii-redactor.port.js +2 -0
- package/dist/src/domain/request/get-logs-filter.props.d.ts +9 -0
- package/dist/src/domain/request/get-logs-filter.props.js +2 -0
- package/dist/src/domain/request/index.d.ts +5 -0
- package/dist/src/domain/request/index.js +21 -0
- package/dist/src/domain/request/log.props.d.ts +7 -0
- package/dist/src/domain/request/log.props.js +2 -0
- package/dist/src/domain/request/pii-options.props.d.ts +8 -0
- package/dist/src/domain/request/pii-options.props.js +2 -0
- package/dist/src/domain/request/pii-replacement.props.d.ts +5 -0
- package/dist/src/domain/request/pii-replacement.props.js +2 -0
- package/dist/src/domain/request/save-log.props.d.ts +7 -0
- package/dist/src/domain/request/save-log.props.js +2 -0
- package/dist/src/domain/response/index.d.ts +1 -0
- package/dist/src/domain/response/index.js +17 -0
- package/dist/src/domain/response/log.response.d.ts +7 -0
- package/dist/src/domain/response/log.response.js +2 -0
- package/dist/src/domain/services/index.d.ts +4 -0
- package/dist/src/domain/services/index.js +20 -0
- package/dist/src/domain/services/log-level.service.d.ts +2 -0
- package/dist/src/domain/services/log-level.service.js +27 -0
- package/dist/src/domain/services/message-normalizer.service.d.ts +3 -0
- package/dist/src/domain/services/message-normalizer.service.js +8 -0
- package/dist/src/domain/services/pii-pattern.service.d.ts +2 -0
- package/dist/src/domain/services/pii-pattern.service.js +13 -0
- package/dist/src/domain/services/pii-redactor.d.ts +10 -0
- package/dist/src/domain/services/pii-redactor.js +68 -0
- package/dist/src/domain/services/pii-redactor.service.d.ts +10 -0
- package/dist/src/domain/services/pii-redactor.service.js +68 -0
- package/dist/src/domain/types/index.d.ts +1 -0
- package/dist/src/domain/types/index.js +17 -0
- package/dist/src/domain/types/log-message.type.d.ts +1 -0
- package/dist/src/domain/types/log-message.type.js +2 -0
- package/dist/src/domain/value-objects/index.d.ts +1 -0
- package/dist/src/domain/value-objects/index.js +17 -0
- package/dist/src/domain/value-objects/log-level.vo.d.ts +8 -0
- package/dist/src/domain/value-objects/log-level.vo.js +13 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +22 -0
- package/dist/src/infrastructure/datasources/in-memory-log.datasource.d.ts +1 -0
- package/dist/src/infrastructure/datasources/in-memory-log.datasource.js +2 -0
- package/dist/src/infrastructure/datasources/index.d.ts +1 -0
- package/dist/src/infrastructure/datasources/index.js +17 -0
- package/dist/src/infrastructure/index.d.ts +1 -0
- package/dist/src/infrastructure/index.js +17 -0
- package/dist/src/infrastructure/services/data-source-error-handler.type.d.ts +5 -0
- package/dist/src/infrastructure/services/data-source-error-handler.type.js +2 -0
- package/dist/src/infrastructure/services/datasource.service.d.ts +15 -0
- package/dist/src/infrastructure/services/datasource.service.js +63 -0
- package/dist/src/infrastructure/services/index.d.ts +2 -0
- package/dist/src/infrastructure/services/index.js +18 -0
- package/dist/tests/application/factory/logger-factory.spec.d.ts +1 -0
- package/dist/tests/application/factory/logger-factory.spec.js +161 -0
- package/dist/tests/application/use-cases/flush-buffers.use-case.spec.d.ts +1 -0
- package/dist/tests/application/use-cases/flush-buffers.use-case.spec.js +38 -0
- package/dist/tests/application/use-cases/get-logs.use-case.spec.d.ts +1 -0
- package/dist/tests/application/use-cases/get-logs.use-case.spec.js +114 -0
- package/dist/tests/application/use-cases/save-log.use-case.spec.d.ts +1 -0
- package/dist/tests/application/use-cases/save-log.use-case.spec.js +138 -0
- package/dist/tests/domain/services/log-level.service.spec.d.ts +1 -0
- package/dist/tests/domain/services/log-level.service.spec.js +68 -0
- package/dist/tests/domain/services/normalize-message.spec.d.ts +1 -0
- package/dist/tests/domain/services/normalize-message.spec.js +83 -0
- package/dist/tests/domain/services/pii-redactor.spec.d.ts +1 -0
- package/dist/tests/domain/services/pii-redactor.spec.js +170 -0
- package/dist/tests/domain/services/to-pii-regex.spec.d.ts +1 -0
- package/dist/tests/domain/services/to-pii-regex.spec.js +82 -0
- package/dist/tests/infrastructure/services/datasource.service.spec.d.ts +1 -0
- package/dist/tests/infrastructure/services/datasource.service.spec.js +128 -0
- package/dist/tests/test-utils/create-pii-redactor-mock.d.ts +5 -0
- package/dist/tests/test-utils/create-pii-redactor-mock.js +10 -0
- package/install.md +367 -0
- package/package.json +33 -10
- package/dist/Composite/index.d.ts +0 -9
- package/dist/Composite/index.js +0 -23
- package/dist/Factory/index.d.ts +0 -5
- package/dist/Factory/index.js +0 -23
- package/dist/index.d.ts +0 -3
- package/dist/interfaces/index.d.ts +0 -35
- package/dist/interfaces/index.js +0 -13
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// examples/flush-buffers-use-case.example.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FlushBuffersUseCaseExample = void 0;
|
|
5
|
+
const flush_buffers_use_case_1 = require("../src/application/use-cases/flush-buffers.use-case");
|
|
6
|
+
const value_objects_1 = require("../src/domain/value-objects");
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Ejemplo de un datasource simple con buffer en memoria
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
class BufferedInMemoryDatasource {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.name = "buffered-memory";
|
|
13
|
+
this.buffer = [];
|
|
14
|
+
this.store = [];
|
|
15
|
+
}
|
|
16
|
+
async save(log) {
|
|
17
|
+
// Guarda en buffer para escritura diferida
|
|
18
|
+
this.buffer.push(log);
|
|
19
|
+
}
|
|
20
|
+
async flush() {
|
|
21
|
+
// Simula un flush: vacía buffer hacia el almacenamiento persistente
|
|
22
|
+
this.store.push(...this.buffer);
|
|
23
|
+
this.buffer = [];
|
|
24
|
+
console.log("🧹 Buffer flushed →", this.store.length, "eventos persistidos");
|
|
25
|
+
}
|
|
26
|
+
async find() {
|
|
27
|
+
return this.store;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Ejemplo de uso real del caso de uso FlushBuffersUseCase
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
class FlushBuffersUseCaseExample {
|
|
34
|
+
static async Main() {
|
|
35
|
+
console.log("\n=== 🧪 Ejemplo de uso: FlushBuffersUseCase ===\n");
|
|
36
|
+
// 1️⃣ Creamos un datasource con buffer
|
|
37
|
+
const ds = new BufferedInMemoryDatasource();
|
|
38
|
+
// 2️⃣ Creamos el caso de uso
|
|
39
|
+
const flushUseCase = new flush_buffers_use_case_1.FlushBuffersUseCase(ds);
|
|
40
|
+
// 3️⃣ Simulamos guardar logs antes del flush
|
|
41
|
+
console.log("➕ Guardando eventos en buffer...\n");
|
|
42
|
+
await ds.save({
|
|
43
|
+
level: value_objects_1.LogLevel.INFO,
|
|
44
|
+
message: "Primer evento",
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
});
|
|
47
|
+
await ds.save({
|
|
48
|
+
level: value_objects_1.LogLevel.ERROR,
|
|
49
|
+
message: { error: "Algo falló" },
|
|
50
|
+
timestamp: Date.now(),
|
|
51
|
+
});
|
|
52
|
+
// 4️⃣ Ejecutamos el flush manualmente (ej: al cerrar la app)
|
|
53
|
+
console.log("🚀 Ejecutando flush...\n");
|
|
54
|
+
await flushUseCase.execute();
|
|
55
|
+
// 5️⃣ Verificamos que los eventos están persistidos
|
|
56
|
+
const logs = await ds.find();
|
|
57
|
+
console.log("📦 Logs almacenados:", logs);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.FlushBuffersUseCaseExample = FlushBuffersUseCaseExample;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// examples/get-logs-use-case.example.ts
|
|
3
|
+
// 🔧 Ajusta los imports según tu estructura
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.GetLogsUseCaseExample = void 0;
|
|
6
|
+
const get_logs_use_case_1 = require("../src/application/use-cases/get-logs.use-case");
|
|
7
|
+
const value_objects_1 = require("../src/domain/value-objects");
|
|
8
|
+
// -----------------------------------------------------------------------------
|
|
9
|
+
// 1️⃣ Implementación simple de un datasource en memoria con soporte de find()
|
|
10
|
+
// -----------------------------------------------------------------------------
|
|
11
|
+
class InMemoryLogDatasource {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.name = "in-memory-ds";
|
|
14
|
+
this.store = [];
|
|
15
|
+
}
|
|
16
|
+
async save(log) {
|
|
17
|
+
this.store.push(log);
|
|
18
|
+
}
|
|
19
|
+
async find(filter) {
|
|
20
|
+
let results = [...this.store];
|
|
21
|
+
if (filter?.levelMin !== undefined) {
|
|
22
|
+
results = results.filter((log) => log.level >= filter.levelMin);
|
|
23
|
+
}
|
|
24
|
+
if (filter?.since !== undefined) {
|
|
25
|
+
results = results.filter((log) => log.timestamp >= filter.since);
|
|
26
|
+
}
|
|
27
|
+
if (filter?.until !== undefined) {
|
|
28
|
+
results = results.filter((log) => log.timestamp <= filter.until);
|
|
29
|
+
}
|
|
30
|
+
if (filter?.query) {
|
|
31
|
+
const q = filter.query.toLowerCase();
|
|
32
|
+
results = results.filter((log) => {
|
|
33
|
+
if (typeof log.message === "string") {
|
|
34
|
+
return log.message.toLowerCase().includes(q);
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const offset = filter?.offset ?? 0;
|
|
40
|
+
const limit = filter?.limit ?? results.length;
|
|
41
|
+
return results.slice(offset, offset + limit);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// -----------------------------------------------------------------------------
|
|
45
|
+
// 2️⃣ Ejemplo de uso real de GetLogsUseCase
|
|
46
|
+
// -----------------------------------------------------------------------------
|
|
47
|
+
class GetLogsUseCaseExample {
|
|
48
|
+
static async Main() {
|
|
49
|
+
console.log("\n=== 📜 Ejemplo de uso: GetLogsUseCase ===\n");
|
|
50
|
+
const ds = new InMemoryLogDatasource();
|
|
51
|
+
const useCase = new get_logs_use_case_1.GetLogsUseCase(ds);
|
|
52
|
+
// Seed de logs de ejemplo
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
await ds.save({
|
|
55
|
+
level: value_objects_1.LogLevel.INFO,
|
|
56
|
+
message: "Servicio iniciado correctamente",
|
|
57
|
+
timestamp: now - 60000, // hace 1 minuto
|
|
58
|
+
});
|
|
59
|
+
await ds.save({
|
|
60
|
+
level: value_objects_1.LogLevel.WARN,
|
|
61
|
+
message: "Latencia alta en endpoint /api/users",
|
|
62
|
+
timestamp: now - 30000, // hace 30s
|
|
63
|
+
});
|
|
64
|
+
await ds.save({
|
|
65
|
+
level: value_objects_1.LogLevel.ERROR,
|
|
66
|
+
message: "Error al conectar con base de datos",
|
|
67
|
+
timestamp: now - 10000, // hace 10s
|
|
68
|
+
meta: { retryCount: 3 },
|
|
69
|
+
});
|
|
70
|
+
// 1) Obtener todos los logs sin filtro
|
|
71
|
+
console.log("🔹 1) Todos los logs (sin filtro):\n");
|
|
72
|
+
const allLogs = await useCase.execute();
|
|
73
|
+
console.dir(allLogs, { depth: 5 });
|
|
74
|
+
// 2) Filtrar por nivel mínimo (levelMin = WARN)
|
|
75
|
+
console.log("\n🔹 2) Logs con level >= WARN:\n");
|
|
76
|
+
const warnAndAbove = await useCase.execute({
|
|
77
|
+
levelMin: value_objects_1.LogLevel.WARN,
|
|
78
|
+
});
|
|
79
|
+
console.dir(warnAndAbove, { depth: 5 });
|
|
80
|
+
// 3) Filtrar por ventana de tiempo (since / until)
|
|
81
|
+
console.log("\n🔹 3) Logs en los últimos 20 segundos:\n");
|
|
82
|
+
const last20Seconds = await useCase.execute({
|
|
83
|
+
since: now - 20000,
|
|
84
|
+
until: now,
|
|
85
|
+
});
|
|
86
|
+
console.dir(last20Seconds, { depth: 5 });
|
|
87
|
+
// 4) Búsqueda por texto (query)
|
|
88
|
+
console.log('\n🔹 4) Logs que contienen "error":\n');
|
|
89
|
+
const errorLogs = await useCase.execute({
|
|
90
|
+
query: "error",
|
|
91
|
+
levelMin: value_objects_1.LogLevel.INFO,
|
|
92
|
+
});
|
|
93
|
+
console.dir(errorLogs, { depth: 5 });
|
|
94
|
+
// 5) Paginación simple (limit / offset)
|
|
95
|
+
console.log("\n🔹 5) Primer log (limit = 1):\n");
|
|
96
|
+
const page1 = await useCase.execute({
|
|
97
|
+
limit: 1,
|
|
98
|
+
offset: 0,
|
|
99
|
+
});
|
|
100
|
+
console.dir(page1, { depth: 5 });
|
|
101
|
+
console.log("\n🔹 6) Segundo log (limit = 1, offset = 1):\n");
|
|
102
|
+
const page2 = await useCase.execute({
|
|
103
|
+
limit: 1,
|
|
104
|
+
offset: 1,
|
|
105
|
+
});
|
|
106
|
+
console.dir(page2, { depth: 5 });
|
|
107
|
+
console.log("\n✅ Ejemplo GetLogsUseCase finalizado.\n");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.GetLogsUseCaseExample = GetLogsUseCaseExample;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class MainExample {
|
|
2
|
+
runExampleUseCases(): Promise<void>;
|
|
3
|
+
runExampleDomainServices(): Promise<void>;
|
|
4
|
+
runExampleServices(): Promise<void>;
|
|
5
|
+
runExampleFactories(): Promise<void>;
|
|
6
|
+
runAllExamples(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export default MainExample;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MainExample = void 0;
|
|
4
|
+
const data_source_service_example_1 = require("./data-source-service.example");
|
|
5
|
+
const flush_buffers_use_case_example_1 = require("./flush-buffers-use-case.example");
|
|
6
|
+
const get_logs_use_case_example_1 = require("./get-logs-use-case.example");
|
|
7
|
+
const logger_factory_example_1 = require("./logger-factory.example");
|
|
8
|
+
const normalize_message_example_1 = require("./normalize-message.example");
|
|
9
|
+
const pii_redactor_example_1 = require("./pii-redactor.example");
|
|
10
|
+
const save_log_use_case_example_1 = require("./save-log-use-case.example");
|
|
11
|
+
const to_log_level_example_1 = require("./to-log-level.example");
|
|
12
|
+
const to_pii_regex_example_1 = require("./to-pii-regex.example");
|
|
13
|
+
class MainExample {
|
|
14
|
+
async runExampleUseCases() {
|
|
15
|
+
console.log("-".repeat(80) + "\n");
|
|
16
|
+
console.log("🎯 Ejecutando Use Case: FlushBuffersUseCase que empuja a almacenamiento final lo que ya está en un buffer interno.s\n");
|
|
17
|
+
await flush_buffers_use_case_example_1.FlushBuffersUseCaseExample.Main();
|
|
18
|
+
console.log("-".repeat(80) + "\n");
|
|
19
|
+
console.log("🎯 Ejecutando Use Case: SaveLogUseCase (guarda logs con filtros)\n");
|
|
20
|
+
await save_log_use_case_example_1.SaveLogUseCaseExample.Main();
|
|
21
|
+
console.log("-".repeat(80) + "\n");
|
|
22
|
+
console.log("🎯 Ejecutando Use Case: GetLogsUseCase (recupera logs con filtros)\n");
|
|
23
|
+
await get_logs_use_case_example_1.GetLogsUseCaseExample.Main();
|
|
24
|
+
console.log("-".repeat(80) + "\n");
|
|
25
|
+
}
|
|
26
|
+
async runExampleDomainServices() {
|
|
27
|
+
console.log("-".repeat(80) + "\n");
|
|
28
|
+
console.log("🎯 Ejecutando Service: ToLogLevel (valida el nivel de log)\n");
|
|
29
|
+
to_log_level_example_1.ToLogLevelExample.Main();
|
|
30
|
+
console.log("-".repeat(80) + "\n");
|
|
31
|
+
console.log("🎯 Ejecutando Service: NormalizeMessage\n");
|
|
32
|
+
normalize_message_example_1.NormalizeMessageExample.Main();
|
|
33
|
+
console.log("-".repeat(80) + "\n");
|
|
34
|
+
console.log("🎯 Ejecutando Service: ToPiiRegex (genera regex para PII)\n");
|
|
35
|
+
to_pii_regex_example_1.ToPiiRegexExample.Main();
|
|
36
|
+
console.log("-".repeat(80) + "\n");
|
|
37
|
+
console.log("🎯 Ejecutando Service: PiiRedactor (redacta información sensible)\n");
|
|
38
|
+
pii_redactor_example_1.PiiRedactorExample.Main();
|
|
39
|
+
console.log("-".repeat(80) + "\n");
|
|
40
|
+
}
|
|
41
|
+
//
|
|
42
|
+
async runExampleServices() {
|
|
43
|
+
console.log("-".repeat(80) + "\n");
|
|
44
|
+
console.log("🎯 Ejecutando Service: DataSourceService (Composite Logger):\n");
|
|
45
|
+
await data_source_service_example_1.DataSourceServiceExample.Main();
|
|
46
|
+
console.log("-".repeat(80) + "\n");
|
|
47
|
+
}
|
|
48
|
+
async runExampleFactories() {
|
|
49
|
+
console.log("-".repeat(80) + "\n");
|
|
50
|
+
console.log("🎯 Ejecutando Factory: LoggerFactory\n");
|
|
51
|
+
await logger_factory_example_1.LoggerFactoryExample.Main();
|
|
52
|
+
console.log("-".repeat(80) + "\n");
|
|
53
|
+
}
|
|
54
|
+
async runAllExamples() {
|
|
55
|
+
try {
|
|
56
|
+
console.log("-".repeat(80) + "\n");
|
|
57
|
+
console.log("🚀 Domain Services - Ejemplos Completos\n");
|
|
58
|
+
await this.runExampleDomainServices();
|
|
59
|
+
console.log("-".repeat(80) + "\n");
|
|
60
|
+
console.log("🚀 Services - Ejemplos Completos\n");
|
|
61
|
+
await this.runExampleServices();
|
|
62
|
+
console.log("-".repeat(80) + "\n");
|
|
63
|
+
console.log("🚀 Use Cases - Ejemplos Completos\n");
|
|
64
|
+
await this.runExampleUseCases();
|
|
65
|
+
console.log("-".repeat(80) + "\n");
|
|
66
|
+
console.log("🚀 Factories - Ejemplos Completos\n");
|
|
67
|
+
await this.runExampleFactories();
|
|
68
|
+
console.log("-".repeat(80) + "\n");
|
|
69
|
+
console.log("🎉 ¡Todos los ejemplos completados exitosamente!");
|
|
70
|
+
console.log("\n📚 Para más información consulta el README.md");
|
|
71
|
+
console.log("-".repeat(80) + "\n");
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error("❌ Error ejecutando ejemplos:", error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.MainExample = MainExample;
|
|
79
|
+
// Función de ayuda para mostrar opciones
|
|
80
|
+
function showHelp() {
|
|
81
|
+
console.log("📖 JWT Auth Package - Ejemplos Disponibles\n");
|
|
82
|
+
console.log("Comandos disponibles:");
|
|
83
|
+
console.log(" npm run example:domain-services - Ejemplos uso domain services");
|
|
84
|
+
console.log(" npm run example:services - Ejemplos uso services");
|
|
85
|
+
console.log(" npm run example:use-cases - Ejemplos uso use-cases");
|
|
86
|
+
console.log(" npm run example:factories - Ejemplos uso factories");
|
|
87
|
+
console.log(" npm run example:all - Todos los ejemplos");
|
|
88
|
+
console.log("\nO ejecuta directamente:");
|
|
89
|
+
console.log(" tsx examples/jwt.examples.ts");
|
|
90
|
+
console.log(" tsx examples/index.example.ts");
|
|
91
|
+
}
|
|
92
|
+
// Ejecutar según el argumento
|
|
93
|
+
if (require.main === module) {
|
|
94
|
+
const mainExample = new MainExample();
|
|
95
|
+
const command = process.argv[2];
|
|
96
|
+
switch (command) {
|
|
97
|
+
case "domain-services":
|
|
98
|
+
mainExample.runExampleDomainServices();
|
|
99
|
+
break;
|
|
100
|
+
case "use-cases":
|
|
101
|
+
mainExample.runExampleUseCases();
|
|
102
|
+
break;
|
|
103
|
+
case "services":
|
|
104
|
+
mainExample.runExampleServices();
|
|
105
|
+
break;
|
|
106
|
+
case "factories":
|
|
107
|
+
mainExample.runExampleFactories();
|
|
108
|
+
break;
|
|
109
|
+
case "help":
|
|
110
|
+
showHelp();
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
mainExample.runAllExamples();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.default = MainExample;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ILogResponse } from "../src/domain/response";
|
|
2
|
+
import { ILogDatasource } from "../src/domain/ports";
|
|
3
|
+
import { IGetLogsFilterProps, ILogProps } from "../src/domain/request";
|
|
4
|
+
/**
|
|
5
|
+
* InMemoryLogDatasource
|
|
6
|
+
*
|
|
7
|
+
* Implementación **completa** y **visual** para demos, tests e integración.
|
|
8
|
+
* Aplica todos los filtros definidos en IGetLogsFilterProps.
|
|
9
|
+
*/
|
|
10
|
+
export declare class InMemoryLogDatasource implements ILogDatasource {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
private logs;
|
|
13
|
+
private idCounter;
|
|
14
|
+
constructor(name?: string);
|
|
15
|
+
/**
|
|
16
|
+
* 🔵 Guarda un log en memoria con un ID incremental.
|
|
17
|
+
*/
|
|
18
|
+
save(log: ILogProps): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* 🔍 Aplica todos los filtros para recuperar logs:
|
|
21
|
+
* - levelMin
|
|
22
|
+
* - since / until
|
|
23
|
+
* - query
|
|
24
|
+
* - limit
|
|
25
|
+
* - offset
|
|
26
|
+
*/
|
|
27
|
+
find(filter?: IGetLogsFilterProps): Promise<ILogResponse[]>;
|
|
28
|
+
/**
|
|
29
|
+
* 🧹 Limpia todos los logs almacenados.
|
|
30
|
+
*/
|
|
31
|
+
flush(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* 🗑 Libera recursos (igual que flush, pero preparado para crecer).
|
|
34
|
+
*/
|
|
35
|
+
dispose(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export declare class LoggerFactoryExample {
|
|
38
|
+
static Main(): Promise<void>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// examples/logger-factory.example.ts
|
|
3
|
+
// Ajusta los imports según tu estructura real
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.LoggerFactoryExample = exports.InMemoryLogDatasource = void 0;
|
|
6
|
+
const logger_factory_1 = require("../src/application/factory/logger.factory");
|
|
7
|
+
const value_objects_1 = require("../src/domain/value-objects");
|
|
8
|
+
/**
|
|
9
|
+
* InMemoryLogDatasource
|
|
10
|
+
*
|
|
11
|
+
* Implementación **completa** y **visual** para demos, tests e integración.
|
|
12
|
+
* Aplica todos los filtros definidos en IGetLogsFilterProps.
|
|
13
|
+
*/
|
|
14
|
+
class InMemoryLogDatasource {
|
|
15
|
+
constructor(name = "in-memory") {
|
|
16
|
+
this.logs = [];
|
|
17
|
+
this.idCounter = 1;
|
|
18
|
+
this.name = name;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 🔵 Guarda un log en memoria con un ID incremental.
|
|
22
|
+
*/
|
|
23
|
+
async save(log) {
|
|
24
|
+
this.logs.push({
|
|
25
|
+
id: this.idCounter++,
|
|
26
|
+
...log,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 🔍 Aplica todos los filtros para recuperar logs:
|
|
31
|
+
* - levelMin
|
|
32
|
+
* - since / until
|
|
33
|
+
* - query
|
|
34
|
+
* - limit
|
|
35
|
+
* - offset
|
|
36
|
+
*/
|
|
37
|
+
async find(filter) {
|
|
38
|
+
let results = [...this.logs];
|
|
39
|
+
if (filter?.levelMin !== undefined) {
|
|
40
|
+
results = results.filter((log) => log.level >= filter.levelMin);
|
|
41
|
+
}
|
|
42
|
+
if (filter?.since !== undefined) {
|
|
43
|
+
results = results.filter((log) => log.timestamp >= filter.since);
|
|
44
|
+
}
|
|
45
|
+
if (filter?.until !== undefined) {
|
|
46
|
+
results = results.filter((log) => log.timestamp <= filter.until);
|
|
47
|
+
}
|
|
48
|
+
if (filter?.query) {
|
|
49
|
+
const q = filter.query.toLowerCase();
|
|
50
|
+
results = results.filter((log) => {
|
|
51
|
+
const msg = typeof log.message === "string"
|
|
52
|
+
? log.message.toLowerCase()
|
|
53
|
+
: JSON.stringify(log.message).toLowerCase();
|
|
54
|
+
return msg.includes(q);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Ordenar por timestamp ascendente (opcional pero útil para visualizar)
|
|
58
|
+
results.sort((a, b) => a.timestamp - b.timestamp);
|
|
59
|
+
// Paginación
|
|
60
|
+
const offset = filter?.offset ?? 0;
|
|
61
|
+
const limit = filter?.limit ?? results.length;
|
|
62
|
+
return results.slice(offset, offset + limit);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 🧹 Limpia todos los logs almacenados.
|
|
66
|
+
*/
|
|
67
|
+
async flush() {
|
|
68
|
+
this.logs = [];
|
|
69
|
+
this.idCounter = 1;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 🗑 Libera recursos (igual que flush, pero preparado para crecer).
|
|
73
|
+
*/
|
|
74
|
+
async dispose() {
|
|
75
|
+
await this.flush();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.InMemoryLogDatasource = InMemoryLogDatasource;
|
|
79
|
+
class LoggerFactoryExample {
|
|
80
|
+
static async Main() {
|
|
81
|
+
console.log("=== 🧪 Ejemplo real de uso: LoggerFactory ===\n");
|
|
82
|
+
// -------------------------------------------------------------------------
|
|
83
|
+
// 1️⃣ Crear datasources
|
|
84
|
+
// -------------------------------------------------------------------------
|
|
85
|
+
const dsA = new InMemoryLogDatasource();
|
|
86
|
+
const dsB = new InMemoryLogDatasource();
|
|
87
|
+
// -------------------------------------------------------------------------
|
|
88
|
+
// 2️⃣ Construir logger vía Factory
|
|
89
|
+
// -------------------------------------------------------------------------
|
|
90
|
+
const logger = logger_factory_1.LoggerFactory.create({
|
|
91
|
+
datasources: [dsA, dsB], // fan-out
|
|
92
|
+
minLevel: value_objects_1.LogLevel.INFO, // DEBUG/TRACE serán ignorados
|
|
93
|
+
redactorOptions: {
|
|
94
|
+
enabled: true,
|
|
95
|
+
deep: true,
|
|
96
|
+
patterns: [
|
|
97
|
+
{
|
|
98
|
+
pattern: "\\b\\d{4}-\\d{4}-\\d{4}-\\d{4}\\b",
|
|
99
|
+
replaceWith: "****-****-****-****",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
pattern: "[\\w.-]+@[\\w.-]+",
|
|
103
|
+
replaceWith: "***@***",
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
console.log("✅ Logger creado correctamente.\n");
|
|
109
|
+
// -------------------------------------------------------------------------
|
|
110
|
+
// 3️⃣ Generar algunos logs de ejemplo
|
|
111
|
+
// -------------------------------------------------------------------------
|
|
112
|
+
console.log("→ DEBUG (no debe persistirse por minLevel=INFO)");
|
|
113
|
+
await logger.debug("Debug interno que NO debería guardarse");
|
|
114
|
+
console.log("→ INFO");
|
|
115
|
+
await logger.info("Servicio iniciado correctamente");
|
|
116
|
+
console.log("→ WARN");
|
|
117
|
+
await logger.warn("Latencia alta en /api/orders", {
|
|
118
|
+
endpoint: "/api/orders",
|
|
119
|
+
durationMs: 987,
|
|
120
|
+
});
|
|
121
|
+
console.log("→ ERROR con PII en message + meta");
|
|
122
|
+
await logger.error("Error al procesar tarjeta 4111-1111-1111-1111 para john.doe@example.com", {
|
|
123
|
+
userId: "u-123",
|
|
124
|
+
email: "john.doe@example.com",
|
|
125
|
+
card: "4111-1111-1111-1111",
|
|
126
|
+
nested: {
|
|
127
|
+
phone: "0999999999",
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
// -------------------------------------------------------------------------
|
|
131
|
+
// 4️⃣ Consultar logs usando getLogs
|
|
132
|
+
// -------------------------------------------------------------------------
|
|
133
|
+
console.log("\n=== 📄 getLogs(): todos los logs ===");
|
|
134
|
+
const all = await logger.getLogs();
|
|
135
|
+
console.dir(all, { depth: 10 });
|
|
136
|
+
console.log("\n=== 📄 getLogs({ levelMin: ERROR }) ===");
|
|
137
|
+
const errors = await logger.getLogs({ levelMin: value_objects_1.LogLevel.ERROR });
|
|
138
|
+
console.dir(errors, { depth: 10 });
|
|
139
|
+
console.log("\n=== 📄 getLogs({ query: 'tarjeta' }) ===");
|
|
140
|
+
const tarjeta = await logger.getLogs({ query: "tarjeta" });
|
|
141
|
+
console.dir(tarjeta, { depth: 10 });
|
|
142
|
+
// -------------------------------------------------------------------------
|
|
143
|
+
// 5️⃣ Flush explícito (útil si algún datasource usa buffers / batch)
|
|
144
|
+
// -------------------------------------------------------------------------
|
|
145
|
+
console.log("\n=== 🧹 flush() ===");
|
|
146
|
+
await logger.flush();
|
|
147
|
+
console.log("Flush completado.\n");
|
|
148
|
+
// -------------------------------------------------------------------------
|
|
149
|
+
// 6️⃣ Ver estado interno de cada datasource (fan-out)
|
|
150
|
+
// -------------------------------------------------------------------------
|
|
151
|
+
console.log("\n=== 🗂 Logs en dsA (memory-A) ===");
|
|
152
|
+
console.dir(await dsA.find(), { depth: 10 });
|
|
153
|
+
console.log("\n=== 🗂 Logs en dsB (memory-B) ===");
|
|
154
|
+
console.dir(await dsB.find(), { depth: 10 });
|
|
155
|
+
console.log("\n✔ LoggerFactoryExample finalizado.\n");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.LoggerFactoryExample = LoggerFactoryExample;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NormalizeMessageExample = void 0;
|
|
4
|
+
const services_1 = require("src/domain/services");
|
|
5
|
+
// -----------------------------------------------------------------------------
|
|
6
|
+
// Mock simple de redactor PII para demostrar comportamiento real
|
|
7
|
+
// En una aplicación real este sería reemplazado por un redactor robusto.
|
|
8
|
+
// -----------------------------------------------------------------------------
|
|
9
|
+
class SimplePiiRedactor {
|
|
10
|
+
redact(value) {
|
|
11
|
+
if (typeof value === "string") {
|
|
12
|
+
// Ejemplo tonto: censura emails y números
|
|
13
|
+
return value
|
|
14
|
+
.replace(/\b[\w.-]+@[\w.-]+\.\w+\b/g, "[REDACTED_EMAIL]")
|
|
15
|
+
.replace(/\d+/g, "[NUM]");
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === "object" && value !== null) {
|
|
18
|
+
const clone = {};
|
|
19
|
+
for (const key of Object.keys(value)) {
|
|
20
|
+
const v = value[key];
|
|
21
|
+
clone[key] = typeof v === "string" ? v.replace(/\d+/g, "[NUM]") : v;
|
|
22
|
+
}
|
|
23
|
+
return clone;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// -----------------------------------------------------------------------------
|
|
29
|
+
// Clase Example tal como lo haría un cliente del paquete
|
|
30
|
+
// -----------------------------------------------------------------------------
|
|
31
|
+
class NormalizeMessageExample {
|
|
32
|
+
static Main() {
|
|
33
|
+
console.log("=== 🧩 Ejemplo de uso: normalizeMessage ===\n");
|
|
34
|
+
const redactor = new SimplePiiRedactor();
|
|
35
|
+
// -------------------------------------------------------------------------
|
|
36
|
+
// 1️⃣ Mensaje de tipo string
|
|
37
|
+
// -------------------------------------------------------------------------
|
|
38
|
+
const msg1 = "Usuario juan@example.com realizó pago 12345";
|
|
39
|
+
const norm1 = (0, services_1.normalizeMessage)(msg1, redactor);
|
|
40
|
+
console.log("→ String redactado:");
|
|
41
|
+
console.log(" Entrada:", msg1);
|
|
42
|
+
console.log(" Salida:", norm1, "\n");
|
|
43
|
+
// -------------------------------------------------------------------------
|
|
44
|
+
// 2️⃣ Mensaje de tipo objeto
|
|
45
|
+
// -------------------------------------------------------------------------
|
|
46
|
+
const msg2 = {
|
|
47
|
+
user: "john@example.com",
|
|
48
|
+
amount: "1500",
|
|
49
|
+
action: "login",
|
|
50
|
+
};
|
|
51
|
+
const norm2 = (0, services_1.normalizeMessage)(msg2, redactor);
|
|
52
|
+
console.log("→ Objeto redactado:");
|
|
53
|
+
console.log(" Entrada:", msg2);
|
|
54
|
+
console.log(" Salida:", norm2, "\n");
|
|
55
|
+
// -------------------------------------------------------------------------
|
|
56
|
+
// 3️⃣ Mensaje como función (lazy evaluation)
|
|
57
|
+
// -------------------------------------------------------------------------
|
|
58
|
+
const msg3 = () => ({
|
|
59
|
+
email: "cliente@test.com",
|
|
60
|
+
phone: "0987654321",
|
|
61
|
+
});
|
|
62
|
+
const norm3 = (0, services_1.normalizeMessage)(msg3, redactor);
|
|
63
|
+
console.log("→ Función perezosa redactada:");
|
|
64
|
+
console.log(" Entrada: función que retorna datos sensibles");
|
|
65
|
+
console.log(" Salida:", norm3, "\n");
|
|
66
|
+
// -------------------------------------------------------------------------
|
|
67
|
+
// 4️⃣ Escenario real de logging
|
|
68
|
+
// -------------------------------------------------------------------------
|
|
69
|
+
const logMessage = () => `Intento de acceso por usuario admin@example.com desde IP 192.168.50.10`;
|
|
70
|
+
const result = (0, services_1.normalizeMessage)(logMessage, redactor);
|
|
71
|
+
console.log("→ Caso real de logging:");
|
|
72
|
+
console.log(" Log con PII:", result, "\n");
|
|
73
|
+
console.log("=== ✔ Fin del ejemplo normalizeMessage ===");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.NormalizeMessageExample = NormalizeMessageExample;
|
|
77
|
+
// Ejecutar directamente: ts-node src/examples/normalize-message.example.ts
|
|
78
|
+
if (require.main === module) {
|
|
79
|
+
NormalizeMessageExample.Main();
|
|
80
|
+
}
|