@jmlq/logger 0.1.0-alpha.11 → 0.1.0-alpha.13

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 (125) hide show
  1. package/dist/{src/application → application}/factory/logger.factory.d.ts +2 -2
  2. package/dist/{src/domain → domain}/ports/index.d.ts +0 -1
  3. package/dist/{src/domain → domain}/ports/index.js +1 -1
  4. package/dist/{src/domain/ports/logger-service.port.d.ts → domain/ports/logger.port.d.ts} +1 -5
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +20 -0
  7. package/package.json +5 -2
  8. package/dist/examples/data-source-service.example.d.ts +0 -3
  9. package/dist/examples/data-source-service.example.js +0 -174
  10. package/dist/examples/flush-buffers-use-case.example.d.ts +0 -3
  11. package/dist/examples/flush-buffers-use-case.example.js +0 -60
  12. package/dist/examples/get-logs-use-case.example.d.ts +0 -3
  13. package/dist/examples/get-logs-use-case.example.js +0 -110
  14. package/dist/examples/index.example.d.ts +0 -8
  15. package/dist/examples/index.example.js +0 -116
  16. package/dist/examples/logger-factory.example.d.ts +0 -39
  17. package/dist/examples/logger-factory.example.js +0 -158
  18. package/dist/examples/normalize-message.example.d.ts +0 -3
  19. package/dist/examples/normalize-message.example.js +0 -80
  20. package/dist/examples/pii-redactor.example.d.ts +0 -3
  21. package/dist/examples/pii-redactor.example.js +0 -129
  22. package/dist/examples/save-log-use-case.example.d.ts +0 -3
  23. package/dist/examples/save-log-use-case.example.js +0 -150
  24. package/dist/examples/to-log-level.example.d.ts +0 -3
  25. package/dist/examples/to-log-level.example.js +0 -49
  26. package/dist/examples/to-pii-regex.example.d.ts +0 -3
  27. package/dist/examples/to-pii-regex.example.js +0 -75
  28. package/dist/src/application/factory/create-logger.d.ts +0 -2
  29. package/dist/src/application/factory/create-logger.js +0 -29
  30. package/dist/src/domain/ports/logger-service.port.js +0 -2
  31. package/dist/src/domain/ports/logger.port.d.ts +0 -10
  32. package/dist/src/domain/services/pii-redactor.d.ts +0 -10
  33. package/dist/src/domain/services/pii-redactor.js +0 -68
  34. package/dist/src/index.d.ts +0 -6
  35. package/dist/src/index.js +0 -22
  36. package/dist/src/infrastructure/datasources/in-memory-log.datasource.d.ts +0 -1
  37. package/dist/src/infrastructure/datasources/in-memory-log.datasource.js +0 -2
  38. package/dist/src/infrastructure/datasources/index.d.ts +0 -1
  39. package/dist/src/infrastructure/datasources/index.js +0 -17
  40. package/dist/tests/application/factory/logger-factory.spec.d.ts +0 -1
  41. package/dist/tests/application/factory/logger-factory.spec.js +0 -161
  42. package/dist/tests/application/use-cases/flush-buffers.use-case.spec.d.ts +0 -1
  43. package/dist/tests/application/use-cases/flush-buffers.use-case.spec.js +0 -38
  44. package/dist/tests/application/use-cases/get-logs.use-case.spec.d.ts +0 -1
  45. package/dist/tests/application/use-cases/get-logs.use-case.spec.js +0 -114
  46. package/dist/tests/application/use-cases/save-log.use-case.spec.d.ts +0 -1
  47. package/dist/tests/application/use-cases/save-log.use-case.spec.js +0 -138
  48. package/dist/tests/domain/services/log-level.service.spec.d.ts +0 -1
  49. package/dist/tests/domain/services/log-level.service.spec.js +0 -68
  50. package/dist/tests/domain/services/normalize-message.spec.d.ts +0 -1
  51. package/dist/tests/domain/services/normalize-message.spec.js +0 -83
  52. package/dist/tests/domain/services/pii-redactor.spec.d.ts +0 -1
  53. package/dist/tests/domain/services/pii-redactor.spec.js +0 -170
  54. package/dist/tests/domain/services/to-pii-regex.spec.d.ts +0 -1
  55. package/dist/tests/domain/services/to-pii-regex.spec.js +0 -82
  56. package/dist/tests/infrastructure/services/datasource.service.spec.d.ts +0 -1
  57. package/dist/tests/infrastructure/services/datasource.service.spec.js +0 -128
  58. package/dist/tests/test-utils/create-pii-redactor-mock.d.ts +0 -5
  59. package/dist/tests/test-utils/create-pii-redactor-mock.js +0 -10
  60. /package/dist/{src/application → application}/factory/index.d.ts +0 -0
  61. /package/dist/{src/application → application}/factory/index.js +0 -0
  62. /package/dist/{src/application → application}/factory/logger.factory.js +0 -0
  63. /package/dist/{src/application → application}/index.d.ts +0 -0
  64. /package/dist/{src/application → application}/index.js +0 -0
  65. /package/dist/{src/application → application}/use-cases/flush-buffers.use-case.d.ts +0 -0
  66. /package/dist/{src/application → application}/use-cases/flush-buffers.use-case.js +0 -0
  67. /package/dist/{src/application → application}/use-cases/get-logs.use-case.d.ts +0 -0
  68. /package/dist/{src/application → application}/use-cases/get-logs.use-case.js +0 -0
  69. /package/dist/{src/application → application}/use-cases/index.d.ts +0 -0
  70. /package/dist/{src/application → application}/use-cases/index.js +0 -0
  71. /package/dist/{src/application → application}/use-cases/save-log.use-case.d.ts +0 -0
  72. /package/dist/{src/application → application}/use-cases/save-log.use-case.js +0 -0
  73. /package/dist/{src/domain → domain}/index.d.ts +0 -0
  74. /package/dist/{src/domain → domain}/index.js +0 -0
  75. /package/dist/{src/domain → domain}/ports/create-logger-options.port.d.ts +0 -0
  76. /package/dist/{src/domain → domain}/ports/create-logger-options.port.js +0 -0
  77. /package/dist/{src/domain → domain}/ports/log-datasource.port.d.ts +0 -0
  78. /package/dist/{src/domain → domain}/ports/log-datasource.port.js +0 -0
  79. /package/dist/{src/domain → domain}/ports/logger-factory-config.port.d.ts +0 -0
  80. /package/dist/{src/domain → domain}/ports/logger-factory-config.port.js +0 -0
  81. /package/dist/{src/domain → domain}/ports/logger.port.js +0 -0
  82. /package/dist/{src/domain → domain}/ports/pii-redactor.port.d.ts +0 -0
  83. /package/dist/{src/domain → domain}/ports/pii-redactor.port.js +0 -0
  84. /package/dist/{src/domain → domain}/request/get-logs-filter.props.d.ts +0 -0
  85. /package/dist/{src/domain → domain}/request/get-logs-filter.props.js +0 -0
  86. /package/dist/{src/domain → domain}/request/index.d.ts +0 -0
  87. /package/dist/{src/domain → domain}/request/index.js +0 -0
  88. /package/dist/{src/domain → domain}/request/log.props.d.ts +0 -0
  89. /package/dist/{src/domain → domain}/request/log.props.js +0 -0
  90. /package/dist/{src/domain → domain}/request/pii-options.props.d.ts +0 -0
  91. /package/dist/{src/domain → domain}/request/pii-options.props.js +0 -0
  92. /package/dist/{src/domain → domain}/request/pii-replacement.props.d.ts +0 -0
  93. /package/dist/{src/domain → domain}/request/pii-replacement.props.js +0 -0
  94. /package/dist/{src/domain → domain}/request/save-log.props.d.ts +0 -0
  95. /package/dist/{src/domain → domain}/request/save-log.props.js +0 -0
  96. /package/dist/{src/domain → domain}/response/index.d.ts +0 -0
  97. /package/dist/{src/domain → domain}/response/index.js +0 -0
  98. /package/dist/{src/domain → domain}/response/log.response.d.ts +0 -0
  99. /package/dist/{src/domain → domain}/response/log.response.js +0 -0
  100. /package/dist/{src/domain → domain}/services/index.d.ts +0 -0
  101. /package/dist/{src/domain → domain}/services/index.js +0 -0
  102. /package/dist/{src/domain → domain}/services/log-level.service.d.ts +0 -0
  103. /package/dist/{src/domain → domain}/services/log-level.service.js +0 -0
  104. /package/dist/{src/domain → domain}/services/message-normalizer.service.d.ts +0 -0
  105. /package/dist/{src/domain → domain}/services/message-normalizer.service.js +0 -0
  106. /package/dist/{src/domain → domain}/services/pii-pattern.service.d.ts +0 -0
  107. /package/dist/{src/domain → domain}/services/pii-pattern.service.js +0 -0
  108. /package/dist/{src/domain → domain}/services/pii-redactor.service.d.ts +0 -0
  109. /package/dist/{src/domain → domain}/services/pii-redactor.service.js +0 -0
  110. /package/dist/{src/domain → domain}/types/index.d.ts +0 -0
  111. /package/dist/{src/domain → domain}/types/index.js +0 -0
  112. /package/dist/{src/domain → domain}/types/log-message.type.d.ts +0 -0
  113. /package/dist/{src/domain → domain}/types/log-message.type.js +0 -0
  114. /package/dist/{src/domain → domain}/value-objects/index.d.ts +0 -0
  115. /package/dist/{src/domain → domain}/value-objects/index.js +0 -0
  116. /package/dist/{src/domain → domain}/value-objects/log-level.vo.d.ts +0 -0
  117. /package/dist/{src/domain → domain}/value-objects/log-level.vo.js +0 -0
  118. /package/dist/{src/infrastructure → infrastructure}/index.d.ts +0 -0
  119. /package/dist/{src/infrastructure → infrastructure}/index.js +0 -0
  120. /package/dist/{src/infrastructure → infrastructure}/services/data-source-error-handler.type.d.ts +0 -0
  121. /package/dist/{src/infrastructure → infrastructure}/services/data-source-error-handler.type.js +0 -0
  122. /package/dist/{src/infrastructure → infrastructure}/services/datasource.service.d.ts +0 -0
  123. /package/dist/{src/infrastructure → infrastructure}/services/datasource.service.js +0 -0
  124. /package/dist/{src/infrastructure → infrastructure}/services/index.d.ts +0 -0
  125. /package/dist/{src/infrastructure → infrastructure}/services/index.js +0 -0
@@ -1,68 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const domain_1 = require("src/domain");
4
- describe("toLogLevel()", () => {
5
- // --------------------------------------------------------------------------
6
- // 1. Strings válidos
7
- // --------------------------------------------------------------------------
8
- it("debe convertir strings válidos al LogLevel correcto", () => {
9
- expect((0, domain_1.toLogLevel)("trace")).toBe(domain_1.LogLevel.TRACE);
10
- expect((0, domain_1.toLogLevel)("debug")).toBe(domain_1.LogLevel.DEBUG);
11
- expect((0, domain_1.toLogLevel)("info")).toBe(domain_1.LogLevel.INFO);
12
- expect((0, domain_1.toLogLevel)("warn")).toBe(domain_1.LogLevel.WARN);
13
- expect((0, domain_1.toLogLevel)("error")).toBe(domain_1.LogLevel.ERROR);
14
- expect((0, domain_1.toLogLevel)("fatal")).toBe(domain_1.LogLevel.FATAL);
15
- });
16
- // --------------------------------------------------------------------------
17
- // 2. Insensibilidad a mayúsculas/minúsculas
18
- // --------------------------------------------------------------------------
19
- it("debe aceptar strings en cualquier tipo de casing", () => {
20
- expect((0, domain_1.toLogLevel)("TRACE")).toBe(domain_1.LogLevel.TRACE);
21
- expect((0, domain_1.toLogLevel)("DeBuG")).toBe(domain_1.LogLevel.DEBUG);
22
- expect((0, domain_1.toLogLevel)("Warn")).toBe(domain_1.LogLevel.WARN);
23
- });
24
- // --------------------------------------------------------------------------
25
- // 3. Valores numéricos válidos
26
- // --------------------------------------------------------------------------
27
- it("debe aceptar valores numéricos válidos del enum", () => {
28
- expect((0, domain_1.toLogLevel)(domain_1.LogLevel.TRACE)).toBe(domain_1.LogLevel.TRACE);
29
- expect((0, domain_1.toLogLevel)(domain_1.LogLevel.FATAL)).toBe(domain_1.LogLevel.FATAL);
30
- });
31
- // --------------------------------------------------------------------------
32
- // 4. Valores numéricos inválidos
33
- // --------------------------------------------------------------------------
34
- it("debe retornar el valor por defecto si el número no pertenece al enum", () => {
35
- expect((0, domain_1.toLogLevel)(999)).toBe(domain_1.LogLevel.INFO); // default implícito
36
- expect((0, domain_1.toLogLevel)(999, domain_1.LogLevel.ERROR)).toBe(domain_1.LogLevel.ERROR); // default explícito
37
- });
38
- // --------------------------------------------------------------------------
39
- // 5. Valores undefined o null
40
- // --------------------------------------------------------------------------
41
- it("debe usar el valor por defecto si el valor es undefined o null", () => {
42
- expect((0, domain_1.toLogLevel)(undefined)).toBe(domain_1.LogLevel.INFO);
43
- expect((0, domain_1.toLogLevel)(null)).toBe(domain_1.LogLevel.INFO);
44
- expect((0, domain_1.toLogLevel)(undefined, domain_1.LogLevel.WARN)).toBe(domain_1.LogLevel.WARN);
45
- });
46
- // --------------------------------------------------------------------------
47
- // 6. Strings desconocidos
48
- // --------------------------------------------------------------------------
49
- it("debe retornar el default si recibe un string no reconocido", () => {
50
- expect((0, domain_1.toLogLevel)("unknown")).toBe(domain_1.LogLevel.INFO);
51
- expect((0, domain_1.toLogLevel)("invalid-level", domain_1.LogLevel.ERROR)).toBe(domain_1.LogLevel.ERROR);
52
- });
53
- // --------------------------------------------------------------------------
54
- // 7. Otros tipos no soportados
55
- // --------------------------------------------------------------------------
56
- it("debe retornar el default si recibe objetos, booleanos u otros tipos", () => {
57
- expect((0, domain_1.toLogLevel)({})).toBe(domain_1.LogLevel.INFO);
58
- expect((0, domain_1.toLogLevel)([])).toBe(domain_1.LogLevel.INFO);
59
- expect((0, domain_1.toLogLevel)(true)).toBe(domain_1.LogLevel.INFO);
60
- });
61
- // --------------------------------------------------------------------------
62
- // 8. Verifica que el default param funciona correctamente
63
- // --------------------------------------------------------------------------
64
- it("debe aplicar correctamente el default proporcionado", () => {
65
- expect((0, domain_1.toLogLevel)("something", domain_1.LogLevel.WARN)).toBe(domain_1.LogLevel.WARN);
66
- expect((0, domain_1.toLogLevel)(undefined, domain_1.LogLevel.FATAL)).toBe(domain_1.LogLevel.FATAL);
67
- });
68
- });
@@ -1,83 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const domain_1 = require("src/domain");
4
- describe("normalizeMessage()", () => {
5
- let redactorMock;
6
- beforeEach(() => {
7
- redactorMock = {
8
- redact: jest.fn((value) => value), // por defecto retorna lo mismo
9
- };
10
- });
11
- // -----------------------------------------------------------------------
12
- // 1️⃣ Si el mensaje es string
13
- // -----------------------------------------------------------------------
14
- it("debe redactor un mensaje tipo string", () => {
15
- const msg = "hello world";
16
- const result = (0, domain_1.normalizeMessage)(msg, redactorMock);
17
- expect(redactorMock.redact).toHaveBeenCalledWith("hello world");
18
- expect(result).toBe("hello world");
19
- });
20
- // -----------------------------------------------------------------------
21
- // 2️⃣ Si el mensaje es objeto
22
- // -----------------------------------------------------------------------
23
- it("debe redactor un objeto", () => {
24
- const msg = { user: "test", email: "a@b.com" };
25
- const redactedObj = { user: "test", email: "***" };
26
- // Redactor retorna un valor distinto
27
- redactorMock.redact.mockReturnValue(redactedObj);
28
- const result = (0, domain_1.normalizeMessage)(msg, redactorMock);
29
- expect(redactorMock.redact).toHaveBeenCalledWith(msg);
30
- expect(result).toEqual(redactedObj);
31
- });
32
- // -----------------------------------------------------------------------
33
- // 3️⃣ Si el mensaje es una función perezosa
34
- // -----------------------------------------------------------------------
35
- it("debe evaluar funciones perezosas y redactor su resultado", () => {
36
- const lazyFn = jest.fn(() => "lazy-result");
37
- const result = (0, domain_1.normalizeMessage)(lazyFn, redactorMock);
38
- expect(lazyFn).toHaveBeenCalledTimes(1);
39
- expect(redactorMock.redact).toHaveBeenCalledWith("lazy-result");
40
- expect(result).toBe("lazy-result");
41
- });
42
- // -----------------------------------------------------------------------
43
- // 4️⃣ Función perezosa retornando un objeto
44
- // -----------------------------------------------------------------------
45
- it("debe procesar funciones perezosas que retornan objetos", () => {
46
- const lazyObj = jest.fn(() => ({ ok: true }));
47
- const result = (0, domain_1.normalizeMessage)(lazyObj, redactorMock);
48
- expect(lazyObj).toHaveBeenCalledTimes(1);
49
- expect(redactorMock.redact).toHaveBeenCalledWith({ ok: true });
50
- expect(result).toEqual({ ok: true });
51
- });
52
- // -----------------------------------------------------------------------
53
- // 5️⃣ El redactor puede transformar el valor
54
- // -----------------------------------------------------------------------
55
- it("debe retornar el valor transformado por el redactor", () => {
56
- redactorMock.redact.mockReturnValue("***redacted***");
57
- const result = (0, domain_1.normalizeMessage)("secret", redactorMock);
58
- expect(result).toBe("***redacted***");
59
- });
60
- // -----------------------------------------------------------------------
61
- // 6️⃣ Verifica que no ejecuta funciones más de una vez
62
- // -----------------------------------------------------------------------
63
- it("solo debe evaluar una vez la función perezosa", () => {
64
- const lazyFn = jest.fn(() => "value");
65
- (0, domain_1.normalizeMessage)(lazyFn, redactorMock);
66
- (0, domain_1.normalizeMessage)(lazyFn, redactorMock);
67
- // Cada llamada a normalizeMessage ejecuta UNA vez la función
68
- expect(lazyFn).toHaveBeenCalledTimes(2);
69
- });
70
- // -----------------------------------------------------------------------
71
- // 7️⃣ Mensajes complejos
72
- // -----------------------------------------------------------------------
73
- it("debe soportar objetos complejos anidados", () => {
74
- const complexObj = {
75
- user: {
76
- id: 1,
77
- profile: { email: "a@b.com", phone: "12345" },
78
- },
79
- };
80
- (0, domain_1.normalizeMessage)(complexObj, redactorMock);
81
- expect(redactorMock.redact).toHaveBeenCalledWith(complexObj);
82
- });
83
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,170 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const services_1 = require("../../../src/domain/services");
4
- describe("PiiRedactor", () => {
5
- // -------------------------------------------------------------------------
6
- // 1️⃣ Desactivado: debe retornar el valor sin modificar
7
- // -------------------------------------------------------------------------
8
- it("debe retornar el valor original si enabled=false", () => {
9
- const redactor = new services_1.PiiRedactor({ enabled: false });
10
- expect(redactor.redact("secret 123")).toBe("secret 123");
11
- expect(redactor.redact({ email: "a@b.com" })).toEqual({
12
- email: "a@b.com",
13
- });
14
- });
15
- // -------------------------------------------------------------------------
16
- // 2️⃣ Aplicación de patrones sobre strings
17
- // -------------------------------------------------------------------------
18
- it("debe aplicar patrones sobre strings cuando está enabled", () => {
19
- const patterns = [
20
- { pattern: "\\d+", replaceWith: "[NUM]" },
21
- { pattern: "[\\w.-]+@[\\w.-]+\\.[A-Za-z]{2,}", replaceWith: "[EMAIL]" },
22
- ];
23
- const redactor = new services_1.PiiRedactor({ enabled: true, patterns });
24
- const result = redactor.redact("Pago 123 por usuario test@example.com");
25
- expect(result).toBe("Pago [NUM] por usuario [EMAIL]");
26
- });
27
- // -------------------------------------------------------------------------
28
- // 3️⃣ Redacción profunda con objetos anidados
29
- // -------------------------------------------------------------------------
30
- it("debe aplicar redacción profunda en objetos con deep=true", () => {
31
- const patterns = [
32
- { pattern: "\\d{10}", replaceWith: "[PHONE]" },
33
- ];
34
- const redactor = new services_1.PiiRedactor({
35
- enabled: true,
36
- deep: true,
37
- patterns,
38
- });
39
- const input = {
40
- level1: {
41
- phone: "0987654321",
42
- nested: {
43
- phone2: "0987654321",
44
- },
45
- },
46
- };
47
- const output = redactor.redact(input);
48
- expect(output.level1.phone).toBe("[PHONE]");
49
- expect(output.level1.nested.phone2).toBe("[PHONE]");
50
- // Verifica que no muta el objeto original
51
- expect(input.level1.phone).toBe("0987654321");
52
- });
53
- // -------------------------------------------------------------------------
54
- // 4️⃣ whitelistKeys debe impedir redacción
55
- // -------------------------------------------------------------------------
56
- it("whitelistKeys debe evitar la redacción de claves específicas", () => {
57
- const patterns = [
58
- { pattern: "\\d+", replaceWith: "*" },
59
- ];
60
- const redactor = new services_1.PiiRedactor({
61
- enabled: true,
62
- patterns,
63
- whitelistKeys: ["safeField"],
64
- });
65
- const input = {
66
- safeField: "12345",
67
- normalField: "12345",
68
- };
69
- const result = redactor.redact(input);
70
- expect(result.safeField).toBe("12345"); // No redactor
71
- expect(result.normalField).toBe("*"); // Sí redactor
72
- });
73
- // -------------------------------------------------------------------------
74
- // 5️⃣ blacklistKeys debe forzar redacción total
75
- // -------------------------------------------------------------------------
76
- it("blacklistKeys debe forzar '[REDACTED]'", () => {
77
- const redactor = new services_1.PiiRedactor({
78
- enabled: true,
79
- blacklistKeys: ["password"],
80
- });
81
- const input = {
82
- password: "super-secret",
83
- other: "hello",
84
- };
85
- const result = redactor.redact(input);
86
- expect(result.password).toBe("[REDACTED]");
87
- expect(result.other).toBe("hello");
88
- });
89
- // -------------------------------------------------------------------------
90
- // 6️⃣ Redacción profunda con arrays
91
- // -------------------------------------------------------------------------
92
- it("debe procesar arrays de forma profunda", () => {
93
- const patterns = [
94
- { pattern: "\\d+", replaceWith: "X" },
95
- ];
96
- const redactor = new services_1.PiiRedactor({
97
- enabled: true,
98
- deep: true,
99
- patterns,
100
- });
101
- const input = {
102
- arr: ["123", "abc", { phone: "456" }],
103
- };
104
- const result = redactor.redact(input);
105
- expect(result.arr[0]).toBe("X");
106
- expect(result.arr[1]).toBe("abc");
107
- expect(result.arr[2]).toEqual({ phone: "X" });
108
- });
109
- // -------------------------------------------------------------------------
110
- // 7️⃣ deep=false → no debe entrar a objetos anidados
111
- // -------------------------------------------------------------------------
112
- it("deep=false no debe redactor objetos anidados", () => {
113
- const patterns = [
114
- { pattern: "\\d+", replaceWith: "*" },
115
- ];
116
- const redactor = new services_1.PiiRedactor({
117
- enabled: true,
118
- deep: false,
119
- patterns,
120
- });
121
- const input = {
122
- inner: {
123
- code: "123",
124
- },
125
- };
126
- const result = redactor.redact(input);
127
- expect(result.inner.code).toBe("123"); // No redactor en objetos internos
128
- });
129
- // -------------------------------------------------------------------------
130
- // 8️⃣ Patrón inválido → no debe romper procesamiento
131
- // -------------------------------------------------------------------------
132
- it("si un patrón es inválido debe usar fallback y no romper redacción", () => {
133
- const patterns = [
134
- { pattern: "[invalid", replaceWith: "X" }, // inválido
135
- { pattern: "\\d+", replaceWith: "#" },
136
- ];
137
- const redactor = new services_1.PiiRedactor({
138
- enabled: true,
139
- patterns,
140
- });
141
- const result = redactor.redact("abc123");
142
- expect(result).toBe("abc#"); // Se aplicó el patrón válido
143
- });
144
- // -------------------------------------------------------------------------
145
- // 9️⃣ updateOptions debe fusionar superficialmente props
146
- // -------------------------------------------------------------------------
147
- it("updateOptions debe fusionar opciones sin mutar referencia previa", () => {
148
- const redactor = new services_1.PiiRedactor({
149
- enabled: true,
150
- deep: false,
151
- });
152
- redactor.updateOptions({
153
- deep: true,
154
- whitelistKeys: ["email"],
155
- });
156
- const after = redactor.props;
157
- expect(after.enabled).toBe(true);
158
- expect(after.deep).toBe(true);
159
- expect(after.whitelistKeys).toEqual(["email"]);
160
- });
161
- // -------------------------------------------------------------------------
162
- // 🔟 Tipos no soportados (number, boolean, function) no se redactan
163
- // -------------------------------------------------------------------------
164
- it("no debe redactor tipos primitivos no string/objeto", () => {
165
- const redactor = new services_1.PiiRedactor({ enabled: true });
166
- expect(redactor.redact(123)).toBe(123);
167
- expect(redactor.redact(true)).toBe(true);
168
- expect(redactor.redact(() => "hi")).toBeInstanceOf(Function);
169
- });
170
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const services_1 = require("../../../src/domain/services");
4
- describe("toPiiRegex()", () => {
5
- // ---------------------------------------------------------------------------
6
- // 1️⃣ Patrón válido con flags por defecto (g)
7
- // ---------------------------------------------------------------------------
8
- it("debe crear un RegExp válido con flags 'g' por defecto", () => {
9
- const props = {
10
- pattern: "\\d+",
11
- replaceWith: "[NUM]",
12
- };
13
- const regex = (0, services_1.toPiiRegex)(props);
14
- expect(regex).toBeInstanceOf(RegExp);
15
- expect(regex.source).toBe("\\d+");
16
- expect(regex.flags).toBe("g");
17
- const result = "abc123def456".replace(regex, props.replaceWith);
18
- expect(result).toBe("abc[NUM]def[NUM]");
19
- });
20
- // ---------------------------------------------------------------------------
21
- // 2️⃣ Patrón válido con flags personalizados
22
- // ---------------------------------------------------------------------------
23
- it("debe respetar los flags personalizados si son válidos", () => {
24
- const props = {
25
- pattern: "test",
26
- flags: "gi",
27
- replaceWith: "X",
28
- };
29
- const regex = (0, services_1.toPiiRegex)(props);
30
- expect(regex.source).toBe("test");
31
- expect(regex.flags).toBe("gi");
32
- expect("TeSt 1, test 2".replace(regex, props.replaceWith)).toBe("X 1, X 2");
33
- });
34
- // ---------------------------------------------------------------------------
35
- // 3️⃣ Patrón inválido → debe retornar el RegExp fallback /$a/
36
- // ---------------------------------------------------------------------------
37
- it("debe retornar un RegExp imposible (/\\$a/) si el patrón es inválido", () => {
38
- const props = {
39
- pattern: "[unclosed",
40
- flags: "g",
41
- replaceWith: "X",
42
- };
43
- const regex = (0, services_1.toPiiRegex)(props);
44
- // El fallback esperado es /$a/
45
- expect(regex).toBeInstanceOf(RegExp);
46
- expect(regex.source).toBe("$a");
47
- expect(regex.test("cualquier texto")).toBe(false);
48
- });
49
- // ---------------------------------------------------------------------------
50
- // 4️⃣ Flags inválidos → también debe usar el fallback
51
- // ---------------------------------------------------------------------------
52
- it("debe usar el fallback si los flags son inválidos", () => {
53
- const props = {
54
- pattern: "\\d+",
55
- flags: "z", // flag inválido
56
- replaceWith: "X",
57
- };
58
- const regex = (0, services_1.toPiiRegex)(props);
59
- expect(regex.source).toBe("$a");
60
- expect(regex.test("123")).toBe(false);
61
- });
62
- // ---------------------------------------------------------------------------
63
- // 5️⃣ Asegura que el fallback nunca hace match con ejemplos comunes
64
- // ---------------------------------------------------------------------------
65
- it("el fallback nunca debe hacer match con strings comunes", () => {
66
- const props = {
67
- pattern: "\\", // clarísimamente inválido
68
- replaceWith: "X",
69
- };
70
- const regex = (0, services_1.toPiiRegex)(props);
71
- const samples = [
72
- "",
73
- "abc",
74
- "123",
75
- "user@test.com",
76
- "tarjeta 4111-1111-1111-1111",
77
- ];
78
- for (const s of samples) {
79
- expect(regex.test(s)).toBe(false);
80
- }
81
- });
82
- });
@@ -1,128 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const infrastructure_1 = require("src/infrastructure");
4
- const src_1 = require("../../../src");
5
- describe("DataSourceService", () => {
6
- const log = {
7
- level: src_1.LogLevel.INFO,
8
- message: "test log",
9
- timestamp: Date.now(),
10
- meta: {
11
- userId: "12345",
12
- },
13
- };
14
- const makeDsMock = () => ({
15
- name: "mock",
16
- save: jest.fn(),
17
- find: jest.fn(),
18
- flush: jest.fn(),
19
- dispose: jest.fn(),
20
- });
21
- beforeEach(() => {
22
- jest.clearAllMocks();
23
- });
24
- // -------------------------------------------------------------------------
25
- // SAVE
26
- // -------------------------------------------------------------------------
27
- test("save() debe ejecutar save en todos los datasources", async () => {
28
- const ds1 = makeDsMock();
29
- const ds2 = makeDsMock();
30
- const service = new infrastructure_1.DataSourceService([ds1, ds2]);
31
- await service.save(log);
32
- expect(ds1.save).toHaveBeenCalledWith(log);
33
- expect(ds2.save).toHaveBeenCalledWith(log);
34
- expect(ds1.save).toHaveBeenCalledTimes(1);
35
- expect(ds2.save).toHaveBeenCalledTimes(1);
36
- });
37
- test("save() debe continuar incluso si uno de los datasources falla y llamar al error handler", async () => {
38
- const ds1 = makeDsMock();
39
- const ds2 = makeDsMock();
40
- ds1.save.mockResolvedValue(undefined);
41
- ds2.save.mockRejectedValue(new Error("failure"));
42
- const onError = jest.fn();
43
- const service = new infrastructure_1.DataSourceService([ds1, ds2], onError);
44
- await service.save(log);
45
- expect(ds1.save).toHaveBeenCalled();
46
- expect(ds2.save).toHaveBeenCalled();
47
- expect(onError).toHaveBeenCalledTimes(1);
48
- expect(onError).toHaveBeenCalledWith(expect.objectContaining({
49
- operation: "save",
50
- datasourceName: "mock",
51
- }));
52
- // Opcional: validar que la razón sea el Error original
53
- expect(onError.mock.calls[0][0].reason).toBeInstanceOf(Error);
54
- expect(onError.mock.calls[0][0].reason.message).toBe("failure");
55
- });
56
- // -------------------------------------------------------------------------
57
- // FIND
58
- // -------------------------------------------------------------------------
59
- test("find() debe concatenar resultados de varios datasources y ordenarlos desc por timestamp", async () => {
60
- const ds1 = makeDsMock();
61
- const ds2 = makeDsMock();
62
- const logs1 = [
63
- { level: src_1.LogLevel.INFO, message: "a", timestamp: 100 },
64
- { level: src_1.LogLevel.WARN, message: "b", timestamp: 300 },
65
- ];
66
- const logs2 = [
67
- { level: src_1.LogLevel.ERROR, message: "c", timestamp: 200 },
68
- ];
69
- ds1.find.mockResolvedValue(logs1);
70
- ds2.find.mockResolvedValue(logs2);
71
- const service = new infrastructure_1.DataSourceService([ds1, ds2]);
72
- const result = await service.find();
73
- expect(result).toHaveLength(3);
74
- expect(result.map((l) => l.timestamp)).toEqual([300, 200, 100]);
75
- });
76
- test("find() ignora datasources que retornen error en find() y llama al error handler", async () => {
77
- const ds1 = makeDsMock();
78
- const ds2 = makeDsMock();
79
- ds1.find.mockRejectedValue(new Error("ds1 fail"));
80
- ds2.find.mockResolvedValue([
81
- { id: "1", level: src_1.LogLevel.INFO, message: "ok", timestamp: 123 },
82
- ]);
83
- const onError = jest.fn();
84
- const service = new infrastructure_1.DataSourceService([ds1, ds2], onError);
85
- const result = await service.find();
86
- // Sigue devolviendo solo los logs válidos
87
- expect(result).toHaveLength(1);
88
- expect(result[0].level).toBe(src_1.LogLevel.INFO);
89
- // Y registra el error del datasource que falló
90
- expect(onError).toHaveBeenCalledTimes(1);
91
- expect(onError).toHaveBeenCalledWith(expect.objectContaining({
92
- operation: "find",
93
- datasourceName: "mock",
94
- }));
95
- expect(onError.mock.calls[0][0].reason).toBeInstanceOf(Error);
96
- expect(onError.mock.calls[0][0].reason.message).toBe("ds1 fail");
97
- });
98
- // -------------------------------------------------------------------------
99
- // FLUSH
100
- // -------------------------------------------------------------------------
101
- test("flush() debe llamar flush en todos los datasources que implementen flush()", async () => {
102
- const ds1 = makeDsMock();
103
- const ds2 = makeDsMock();
104
- const service = new infrastructure_1.DataSourceService([ds1, ds2]);
105
- await service.flush();
106
- expect(ds1.flush).toHaveBeenCalledTimes(1);
107
- expect(ds2.flush).toHaveBeenCalledTimes(1);
108
- });
109
- // -------------------------------------------------------------------------
110
- // DISPOSE
111
- // -------------------------------------------------------------------------
112
- test("dispose() debe llamar dispose en todos los datasources", async () => {
113
- const ds1 = makeDsMock();
114
- const ds2 = makeDsMock();
115
- const service = new infrastructure_1.DataSourceService([ds1, ds2]);
116
- await service.dispose();
117
- expect(ds1.dispose).toHaveBeenCalledTimes(1);
118
- expect(ds2.dispose).toHaveBeenCalledTimes(1);
119
- });
120
- // -------------------------------------------------------------------------
121
- // CONSTRUCTOR DEFENSIVO
122
- // -------------------------------------------------------------------------
123
- test("constructor debe filtrar targets inválidos (null/undefined)", async () => {
124
- const ds1 = makeDsMock();
125
- const service = new infrastructure_1.DataSourceService([ds1, null, undefined]);
126
- expect(service.targets).toHaveLength(1);
127
- });
128
- });
@@ -1,5 +0,0 @@
1
- import { IPiiRedactor } from "../../src/domain/ports";
2
- export type PiiRedactorMock = IPiiRedactor & {
3
- redact: jest.Mock;
4
- };
5
- export declare function createPiiRedactorMock(): PiiRedactorMock;
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createPiiRedactorMock = createPiiRedactorMock;
4
- function createPiiRedactorMock() {
5
- const redact = jest.fn((value) => value);
6
- return {
7
- redact,
8
- updateOptions: jest.fn(),
9
- };
10
- }
File without changes
File without changes
File without changes
File without changes
File without changes