@jmlq/logger 0.1.0-alpha.2 → 0.1.0-alpha.21
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 +639 -0
- package/architecture.md +193 -0
- package/assets/mongo-log.png +0 -0
- package/assets/pg-log.png +0 -0
- package/dist/application/factory/index.d.ts +1 -0
- package/dist/{config → application/factory}/index.js +1 -2
- package/dist/application/factory/logger.factory.d.ts +11 -0
- package/dist/application/factory/logger.factory.js +71 -0
- package/dist/application/index.d.ts +2 -0
- package/dist/{presentation → application}/index.js +1 -0
- package/dist/application/types/index.d.ts +1 -0
- package/dist/application/types/index.js +17 -0
- package/dist/application/types/logger-factory-config.type.d.ts +28 -0
- package/dist/{config/interfaces/index.js → application/types/logger-factory-config.type.js} +0 -1
- package/dist/application/use-cases/flush-buffers.use-case.d.ts +6 -0
- package/dist/application/use-cases/flush-buffers.use-case.js +13 -0
- package/dist/application/use-cases/get-logs.use-case.d.ts +8 -0
- package/dist/application/use-cases/get-logs.use-case.js +24 -0
- package/dist/application/use-cases/index.d.ts +3 -0
- package/dist/application/use-cases/index.js +19 -0
- package/dist/application/use-cases/save-log/index.d.ts +1 -0
- package/dist/application/use-cases/save-log/index.js +17 -0
- package/dist/application/use-cases/save-log/save-log.props.d.ts +7 -0
- package/dist/application/use-cases/save-log/save-log.props.js +2 -0
- package/dist/application/use-cases/save-log.use-case.d.ts +8 -0
- package/dist/application/use-cases/save-log.use-case.js +27 -0
- package/dist/domain/index.d.ts +7 -0
- package/dist/domain/index.js +7 -0
- package/dist/domain/model/index.d.ts +3 -0
- package/dist/domain/model/index.js +19 -0
- package/dist/domain/model/log-entry.model.d.ts +8 -0
- package/dist/domain/model/log-entry.model.js +2 -0
- package/dist/domain/model/pii-options.model.d.ts +8 -0
- package/dist/domain/model/pii-options.model.js +2 -0
- package/dist/domain/model/pii-replacement-rule.d.ts +5 -0
- package/dist/domain/model/pii-replacement-rule.js +2 -0
- package/dist/domain/ports/create-logger-options.port.d.ts +7 -0
- package/dist/domain/ports/create-logger-options.port.js +2 -0
- package/dist/domain/ports/index.d.ts +4 -0
- package/dist/domain/ports/index.js +20 -0
- package/dist/domain/ports/log-datasource.port.d.ts +10 -0
- package/dist/domain/ports/log-datasource.port.js +2 -0
- package/dist/domain/ports/logger.port.d.ts +15 -0
- package/dist/domain/ports/logger.port.js +2 -0
- package/dist/domain/ports/pii-redactor.port.d.ts +5 -0
- package/dist/domain/ports/pii-redactor.port.js +2 -0
- package/dist/domain/request/index.d.ts +1 -0
- package/dist/domain/request/index.js +17 -0
- package/dist/domain/request/log-filter.request.d.ts +9 -0
- package/dist/domain/request/log-filter.request.js +2 -0
- package/dist/domain/response/index.d.ts +1 -0
- package/dist/domain/response/index.js +17 -0
- package/dist/domain/response/log.response.d.ts +8 -0
- package/dist/domain/response/log.response.js +2 -0
- package/dist/domain/services/index.d.ts +1 -1
- package/dist/domain/services/index.js +1 -1
- package/dist/domain/services/pii-redactor.service.d.ts +10 -0
- package/dist/domain/services/pii-redactor.service.js +68 -0
- package/dist/domain/types/index.d.ts +1 -0
- package/dist/domain/types/index.js +17 -0
- package/dist/domain/types/log-message.type.d.ts +1 -0
- package/dist/domain/types/log-message.type.js +2 -0
- package/dist/domain/utils/index.d.ts +3 -0
- package/dist/domain/utils/index.js +19 -0
- package/dist/domain/utils/normalize-message.util.d.ts +3 -0
- package/dist/domain/utils/normalize-message.util.js +8 -0
- package/dist/domain/utils/parse-log-level.util.d.ts +2 -0
- package/dist/domain/utils/parse-log-level.util.js +27 -0
- package/dist/domain/utils/pii-regex.util.d.ts +2 -0
- package/dist/domain/utils/pii-regex.util.js +13 -0
- package/dist/domain/value-objects/index.d.ts +1 -0
- package/dist/domain/value-objects/index.js +17 -0
- package/dist/domain/value-objects/log-level.vo.d.ts +8 -0
- package/dist/domain/value-objects/log-level.vo.js +13 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +32 -7
- package/dist/infrastructure/index.d.ts +1 -0
- package/dist/infrastructure/index.js +17 -0
- package/dist/infrastructure/services/datasource.service.d.ts +18 -0
- package/dist/infrastructure/services/datasource.service.js +102 -0
- package/dist/infrastructure/services/index.d.ts +1 -0
- package/dist/infrastructure/services/index.js +17 -0
- package/dist/infrastructure/types/index.d.ts +1 -0
- package/dist/infrastructure/types/index.js +17 -0
- package/dist/infrastructure/types/on-data-source-error.type.d.ts +5 -0
- package/dist/infrastructure/types/on-data-source-error.type.js +2 -0
- package/package.json +37 -11
- package/dist/Composite/index.d.ts +0 -9
- package/dist/Composite/index.js +0 -54
- package/dist/Factory/index.d.ts +0 -5
- package/dist/Factory/index.js +0 -23
- package/dist/config/index.d.ts +0 -2
- package/dist/config/interfaces/index.d.ts +0 -67
- package/dist/config/types/index.d.ts +0 -10
- package/dist/config/types/index.js +0 -13
- package/dist/domain/services/pii-redactor.d.ts +0 -27
- package/dist/domain/services/pii-redactor.js +0 -139
- package/dist/interfaces/index.d.ts +0 -35
- package/dist/interfaces/index.js +0 -13
- package/dist/presentation/factory/index.d.ts +0 -2
- package/dist/presentation/factory/index.js +0 -74
- package/dist/presentation/index.d.ts +0 -1
package/package.json
CHANGED
|
@@ -1,19 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmlq/logger",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"description": "logger package with clean architecture",
|
|
4
|
+
"version": "0.1.0-alpha.21",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
],
|
|
10
7
|
"scripts": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
8
|
+
"dev": "rimraf dist && mkdir dist && tsc -p tsconfig.json",
|
|
9
|
+
"build": "rimraf dist && mkdir dist && tsc -p tsconfig.build.json",
|
|
10
|
+
"prepublishOnly": "npm run build",
|
|
11
|
+
"test": "jest --passWithNoTests",
|
|
12
|
+
"test:watch": "jest --watch",
|
|
13
|
+
"test:coverage": "jest --coverage",
|
|
14
|
+
"example:help": "tsx examples/index.example.ts help",
|
|
15
|
+
"example:all": "tsx examples/index.example.ts",
|
|
16
|
+
"example:domain-services": "tsx examples/index.example.ts domain-services",
|
|
17
|
+
"example:services": "tsx examples/index.example.ts services",
|
|
18
|
+
"example:use-cases": "tsx examples/index.example.ts use-cases",
|
|
19
|
+
"example:factories": "tsx examples/index.example.ts factories"
|
|
13
20
|
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"logger",
|
|
23
|
+
"clean-architecture",
|
|
24
|
+
"typescript"
|
|
25
|
+
],
|
|
26
|
+
"author": "MLahuasi",
|
|
27
|
+
"license": "MIT",
|
|
14
28
|
"devDependencies": {
|
|
15
|
-
"@
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
29
|
+
"@swc/core": "^1.3.95",
|
|
30
|
+
"@swc/jest": "^0.2.29",
|
|
31
|
+
"@types/bcryptjs": "^2.4.5",
|
|
32
|
+
"@types/jest": "^29.5.8",
|
|
33
|
+
"@types/node": "^20.8.10",
|
|
34
|
+
"jest": "^29.7.0",
|
|
35
|
+
"rimraf": "^6.1.2",
|
|
36
|
+
"tsx": "^4.1.4",
|
|
37
|
+
"typescript": "^5.2.2"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md",
|
|
42
|
+
"architecture.md",
|
|
43
|
+
"assets"
|
|
44
|
+
]
|
|
19
45
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { IGetLogsFilter, ILogDatasource, ILog } from "../config";
|
|
2
|
-
export declare class CompositeDatasource implements ILogDatasource {
|
|
3
|
-
private readonly datasources;
|
|
4
|
-
constructor(datasources: ILogDatasource[]);
|
|
5
|
-
save(log: ILog): Promise<void>;
|
|
6
|
-
find(filter?: IGetLogsFilter): Promise<ILog[]>;
|
|
7
|
-
flush(): Promise<void>;
|
|
8
|
-
dispose(): Promise<void>;
|
|
9
|
-
}
|
package/dist/Composite/index.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CompositeDatasource = void 0;
|
|
4
|
-
// ---- Composite fan-out ----
|
|
5
|
-
class CompositeDatasource {
|
|
6
|
-
constructor(datasources) {
|
|
7
|
-
this.datasources = datasources;
|
|
8
|
-
}
|
|
9
|
-
async save(log) {
|
|
10
|
-
const results = await Promise.allSettled(this.datasources.map((ds) => ds.save(log)));
|
|
11
|
-
for (const r of results) {
|
|
12
|
-
if (r.status === "rejected") {
|
|
13
|
-
// Evita romper el flujo si un destino falla.
|
|
14
|
-
// Aquí podrías enrutar a "dead-letter", métricas, etc.
|
|
15
|
-
// eslint-disable-next-line no-console
|
|
16
|
-
console.warn("[CompositeDatasource] save failed:", r.reason);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
async find(filter = {}) {
|
|
21
|
-
for (const ds of this.datasources) {
|
|
22
|
-
if (typeof ds.find === "function") {
|
|
23
|
-
try {
|
|
24
|
-
return await ds.find(filter);
|
|
25
|
-
}
|
|
26
|
-
catch (e) {
|
|
27
|
-
// eslint-disable-next-line no-console
|
|
28
|
-
console.warn("[CompositeDatasource] find failed on a datasource:", e);
|
|
29
|
-
// probar siguiente datasource
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
async flush() {
|
|
36
|
-
const results = await Promise.allSettled(this.datasources.map((ds) => ds.flush?.() ?? Promise.resolve()));
|
|
37
|
-
for (const r of results) {
|
|
38
|
-
if (r.status === "rejected") {
|
|
39
|
-
// eslint-disable-next-line no-console
|
|
40
|
-
console.warn("[CompositeDatasource] flush failed:", r.reason);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
async dispose() {
|
|
45
|
-
const results = await Promise.allSettled(this.datasources.map((ds) => ds.dispose?.() ?? Promise.resolve()));
|
|
46
|
-
for (const r of results) {
|
|
47
|
-
if (r.status === "rejected") {
|
|
48
|
-
// eslint-disable-next-line no-console
|
|
49
|
-
console.warn("[CompositeDatasource] dispose failed:", r.reason);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.CompositeDatasource = CompositeDatasource;
|
package/dist/Factory/index.d.ts
DELETED
package/dist/Factory/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createLogger = createLogger;
|
|
4
|
-
const __1 = require("..");
|
|
5
|
-
function createLogger(ds, opts) {
|
|
6
|
-
const write = async (level, message, meta) => {
|
|
7
|
-
if (level < opts.minLevel)
|
|
8
|
-
return;
|
|
9
|
-
// (Opcional) redactor PII aquí si opts.redactPII === true
|
|
10
|
-
await ds.save({ level, message, meta, timestamp: Date.now() });
|
|
11
|
-
};
|
|
12
|
-
const logger = {
|
|
13
|
-
trace: (m, meta) => write(__1.LogLevel.TRACE, m, meta),
|
|
14
|
-
debug: (m, meta) => write(__1.LogLevel.DEBUG, m, meta),
|
|
15
|
-
info: (m, meta) => write(__1.LogLevel.INFO, m, meta),
|
|
16
|
-
warn: (m, meta) => write(__1.LogLevel.WARN, m, meta),
|
|
17
|
-
error: (m, meta) => write(__1.LogLevel.ERROR, m, meta),
|
|
18
|
-
fatal: (m, meta) => write(__1.LogLevel.FATAL, m, meta),
|
|
19
|
-
flush: () => ds.flush?.() ?? Promise.resolve(),
|
|
20
|
-
dispose: () => ds.dispose?.() ?? Promise.resolve(),
|
|
21
|
-
};
|
|
22
|
-
return logger;
|
|
23
|
-
}
|
package/dist/config/index.d.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { LogLevel, LogMessage, PiiReplacement } from "..";
|
|
2
|
-
export interface ILog {
|
|
3
|
-
level: LogLevel;
|
|
4
|
-
message: string;
|
|
5
|
-
meta?: unknown;
|
|
6
|
-
timestamp: number;
|
|
7
|
-
}
|
|
8
|
-
export interface IGetLogsFilter {
|
|
9
|
-
levelMin?: LogLevel;
|
|
10
|
-
since?: number;
|
|
11
|
-
until?: number;
|
|
12
|
-
}
|
|
13
|
-
export interface ILogDatasource {
|
|
14
|
-
save(log: ILog): Promise<void>;
|
|
15
|
-
find?(filter?: IGetLogsFilter): Promise<ILog[]>;
|
|
16
|
-
flush?(): Promise<void>;
|
|
17
|
-
dispose?(): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
export interface ILogger {
|
|
20
|
-
trace: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
21
|
-
debug: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
22
|
-
info: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
23
|
-
warn: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
24
|
-
error: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
25
|
-
fatal: (msg: LogMessage, meta?: unknown) => Promise<void>;
|
|
26
|
-
flush?: () => Promise<void>;
|
|
27
|
-
dispose?: () => Promise<void>;
|
|
28
|
-
}
|
|
29
|
-
export interface IPiiPattern {
|
|
30
|
-
/** (Opcional) Nombre del patrón para debug/telemetría */
|
|
31
|
-
name?: string;
|
|
32
|
-
/** Expresión regular a aplicar sobre strings */
|
|
33
|
-
regex: RegExp;
|
|
34
|
-
/** Reemplazo, por defecto "[REDACTED]" si no se provee */
|
|
35
|
-
replacement?: PiiReplacement;
|
|
36
|
-
}
|
|
37
|
-
export interface IPiiRedactorOptions {
|
|
38
|
-
/** Habilita/deshabilita redacción (permite control fino además del flag redactPII) */
|
|
39
|
-
enabled?: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Incluye patrones default (true) y fusiona con los custom. Si false, usa solo los personalizados
|
|
42
|
-
* por el cliente.
|
|
43
|
-
*/
|
|
44
|
-
includeDefaultPatterns?: boolean;
|
|
45
|
-
/** Patrones adicionales o propios del cliente */
|
|
46
|
-
patterns?: IPiiPattern[];
|
|
47
|
-
/**
|
|
48
|
-
* Redactar por nombre de clave (deep). Cualquier key que haga match será redacatada
|
|
49
|
-
* con "[REDACTED]". Acepta exacto o RegExp.
|
|
50
|
-
*/
|
|
51
|
-
redactKeys?: Array<string | RegExp>;
|
|
52
|
-
/**
|
|
53
|
-
* Claves que NO se deben redactar aunque coincidan con patrones o redactKeys.
|
|
54
|
-
* Prioridad: preserveKeys > redactKeys > patterns.
|
|
55
|
-
*/
|
|
56
|
-
preserveKeys?: Array<string | RegExp>;
|
|
57
|
-
}
|
|
58
|
-
export interface ICreateLoggerOptions {
|
|
59
|
-
minLevel?: LogLevel;
|
|
60
|
-
/** compatibilidad con lo que ya tienes */
|
|
61
|
-
redactPII?: boolean;
|
|
62
|
-
/** NUEVO: bloque de configuración PII */
|
|
63
|
-
pii?: IPiiRedactorOptions & {
|
|
64
|
-
/** atajo para permitir que el cliente mande solo patterns sin escribir PiiRedactorOptions */
|
|
65
|
-
patterns?: IPiiPattern[];
|
|
66
|
-
};
|
|
67
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare enum LogLevel {
|
|
2
|
-
TRACE = 0,
|
|
3
|
-
DEBUG = 1,
|
|
4
|
-
INFO = 2,
|
|
5
|
-
WARN = 3,
|
|
6
|
-
ERROR = 4,
|
|
7
|
-
FATAL = 5
|
|
8
|
-
}
|
|
9
|
-
export type PiiReplacement = string | ((match: string, keyPath: string[]) => string);
|
|
10
|
-
export type LogMessage = string | Record<string, unknown> | Error;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogLevel = void 0;
|
|
4
|
-
// ---- Types ----
|
|
5
|
-
var LogLevel;
|
|
6
|
-
(function (LogLevel) {
|
|
7
|
-
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
|
|
8
|
-
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
|
|
9
|
-
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
10
|
-
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
11
|
-
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
12
|
-
LogLevel[LogLevel["FATAL"] = 5] = "FATAL";
|
|
13
|
-
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
@@ -1,27 +0,0 @@
|
|
|
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 */
|
|
19
|
-
redact<T = unknown>(value: T): T;
|
|
20
|
-
/** === Internos === */
|
|
21
|
-
private redactValue;
|
|
22
|
-
private applyPatterns;
|
|
23
|
-
private isRedactedKey;
|
|
24
|
-
private isPreservedKey;
|
|
25
|
-
private keyRedactionReplacement;
|
|
26
|
-
private clone;
|
|
27
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Domain Service: PiiRedactor
|
|
4
|
-
*
|
|
5
|
-
* Propósito:
|
|
6
|
-
* - Redactar/anonimizar PII en strings, objetos y arrays (deep).
|
|
7
|
-
* - Permitir que el cliente pase patrones adicionales/propios.
|
|
8
|
-
* - Controlar redacción por nombre de clave (whitelist/blacklist).
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.PiiRedactor = void 0;
|
|
12
|
-
class PiiRedactor {
|
|
13
|
-
constructor(opts = {}) {
|
|
14
|
-
const { enabled = true, includeDefaultPatterns = true, patterns = [], redactKeys = [], preserveKeys = [], } = opts;
|
|
15
|
-
this.enabled = enabled;
|
|
16
|
-
this.patterns = includeDefaultPatterns
|
|
17
|
-
? [...PiiRedactor.defaultPatterns(), ...patterns]
|
|
18
|
-
: [...patterns];
|
|
19
|
-
this.redactKeys = redactKeys;
|
|
20
|
-
this.preserveKeys = preserveKeys;
|
|
21
|
-
}
|
|
22
|
-
/** Patrones por defecto (seguros y genéricos). Ajusta según tu dominio/región si lo deseas. */
|
|
23
|
-
static defaultPatterns() {
|
|
24
|
-
return [
|
|
25
|
-
// Tarjetas (13–19 dígitos con espacios o guiones) — patrón simple
|
|
26
|
-
{
|
|
27
|
-
name: "credit_card",
|
|
28
|
-
regex: /\b(?:\d[ -]*?){13,19}\b/g,
|
|
29
|
-
replacement: "[REDACTED_CARD]",
|
|
30
|
-
},
|
|
31
|
-
// Emails
|
|
32
|
-
{
|
|
33
|
-
name: "email",
|
|
34
|
-
regex: /\b[\w._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
|
|
35
|
-
replacement: "[REDACTED_EMAIL]",
|
|
36
|
-
},
|
|
37
|
-
// Teléfonos: 10+ dígitos (ajusta a tu región si hace falta)
|
|
38
|
-
{
|
|
39
|
-
name: "phone",
|
|
40
|
-
regex: /\b\d{10,}\b/g,
|
|
41
|
-
replacement: "[REDACTED_PHONE]",
|
|
42
|
-
},
|
|
43
|
-
// Documento genérico: ABC-123456… o similar
|
|
44
|
-
{
|
|
45
|
-
name: "document_id",
|
|
46
|
-
regex: /\b[A-Z]{1,3}-?\d{6,10}\b/g,
|
|
47
|
-
replacement: "[REDACTED_ID]",
|
|
48
|
-
},
|
|
49
|
-
// IPv4
|
|
50
|
-
{
|
|
51
|
-
name: "ipv4",
|
|
52
|
-
regex: /\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.|$)){4}\b/g,
|
|
53
|
-
replacement: "[REDACTED_IP]",
|
|
54
|
-
},
|
|
55
|
-
];
|
|
56
|
-
}
|
|
57
|
-
/** Punto de entrada público: redacción deep de cualquier estructura */
|
|
58
|
-
redact(value) {
|
|
59
|
-
if (!this.enabled)
|
|
60
|
-
return value;
|
|
61
|
-
return this.redactValue(value, []);
|
|
62
|
-
}
|
|
63
|
-
/** === Internos === */
|
|
64
|
-
redactValue(value, keyPath) {
|
|
65
|
-
// Strings → aplicar patrones
|
|
66
|
-
if (typeof value === "string") {
|
|
67
|
-
return this.applyPatterns(value, keyPath);
|
|
68
|
-
}
|
|
69
|
-
// Números / boolean / null / undefined → retornar tal cual
|
|
70
|
-
if (typeof value === "number" ||
|
|
71
|
-
typeof value === "boolean" ||
|
|
72
|
-
value === null ||
|
|
73
|
-
typeof value === "undefined") {
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
|
-
// Arrays → deep
|
|
77
|
-
if (Array.isArray(value)) {
|
|
78
|
-
return value.map((v, i) => this.redactValue(v, [...keyPath, String(i)]));
|
|
79
|
-
}
|
|
80
|
-
// Objetos → deep + reglas por nombre de clave
|
|
81
|
-
if (typeof value === "object") {
|
|
82
|
-
const src = value;
|
|
83
|
-
const out = {};
|
|
84
|
-
for (const [k, v] of Object.entries(src)) {
|
|
85
|
-
const path = [...keyPath, k];
|
|
86
|
-
if (this.isPreservedKey(k)) {
|
|
87
|
-
out[k] = this.clone(v); // explícitamente preservado
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (this.isRedactedKey(k)) {
|
|
91
|
-
out[k] = this.keyRedactionReplacement(k, path);
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
out[k] = this.redactValue(v, path);
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
// funciones, símbolos, etc.
|
|
99
|
-
return value;
|
|
100
|
-
}
|
|
101
|
-
applyPatterns(text, keyPath) {
|
|
102
|
-
let result = text;
|
|
103
|
-
for (const p of this.patterns) {
|
|
104
|
-
const replacement = p.replacement ?? "[REDACTED]";
|
|
105
|
-
// Soporta función de reemplazo con contexto (ruta de claves)
|
|
106
|
-
if (typeof replacement === "function") {
|
|
107
|
-
result = result.replace(p.regex, (m) => replacement(m, keyPath));
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
result = result.replace(p.regex, replacement);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return result;
|
|
114
|
-
}
|
|
115
|
-
isRedactedKey(key) {
|
|
116
|
-
return this.redactKeys.some((r) => typeof r === "string" ? r === key : r.test(key));
|
|
117
|
-
}
|
|
118
|
-
isPreservedKey(key) {
|
|
119
|
-
return this.preserveKeys.some((r) => typeof r === "string" ? r === key : r.test(key));
|
|
120
|
-
}
|
|
121
|
-
keyRedactionReplacement(_key, _path) {
|
|
122
|
-
return "[REDACTED]";
|
|
123
|
-
}
|
|
124
|
-
clone(v) {
|
|
125
|
-
if (v && typeof v === "object") {
|
|
126
|
-
try {
|
|
127
|
-
return JSON.parse(JSON.stringify(v));
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
// fallback shallow
|
|
131
|
-
if (Array.isArray(v))
|
|
132
|
-
return [...v];
|
|
133
|
-
return { ...v };
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return v;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
exports.PiiRedactor = PiiRedactor;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
export declare enum LogLevel {
|
|
2
|
-
TRACE = 0,
|
|
3
|
-
DEBUG = 1,
|
|
4
|
-
INFO = 2,
|
|
5
|
-
WARN = 3,
|
|
6
|
-
ERROR = 4,
|
|
7
|
-
FATAL = 5
|
|
8
|
-
}
|
|
9
|
-
export interface Log {
|
|
10
|
-
level: LogLevel;
|
|
11
|
-
message: string;
|
|
12
|
-
meta?: unknown;
|
|
13
|
-
timestamp: number;
|
|
14
|
-
}
|
|
15
|
-
export interface GetLogsFilter {
|
|
16
|
-
levelMin?: LogLevel;
|
|
17
|
-
since?: number;
|
|
18
|
-
until?: number;
|
|
19
|
-
}
|
|
20
|
-
export interface ILogDatasource {
|
|
21
|
-
save(log: Log): Promise<void>;
|
|
22
|
-
find?(filter?: GetLogsFilter): Promise<Log[]>;
|
|
23
|
-
flush?(): Promise<void>;
|
|
24
|
-
dispose?(): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
export interface Logger {
|
|
27
|
-
trace: (msg: string, meta?: unknown) => Promise<void>;
|
|
28
|
-
debug: (msg: string, meta?: unknown) => Promise<void>;
|
|
29
|
-
info: (msg: string, meta?: unknown) => Promise<void>;
|
|
30
|
-
warn: (msg: string, meta?: unknown) => Promise<void>;
|
|
31
|
-
error: (msg: string, meta?: unknown) => Promise<void>;
|
|
32
|
-
fatal: (msg: string, meta?: unknown) => Promise<void>;
|
|
33
|
-
flush?: () => Promise<void>;
|
|
34
|
-
dispose?: () => Promise<void>;
|
|
35
|
-
}
|
package/dist/interfaces/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogLevel = void 0;
|
|
4
|
-
// ---- Types & contratos ----
|
|
5
|
-
var LogLevel;
|
|
6
|
-
(function (LogLevel) {
|
|
7
|
-
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
|
|
8
|
-
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
|
|
9
|
-
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
10
|
-
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
11
|
-
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
12
|
-
LogLevel[LogLevel["FATAL"] = 5] = "FATAL";
|
|
13
|
-
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createLogger = createLogger;
|
|
4
|
-
const __1 = require("../..");
|
|
5
|
-
/**
|
|
6
|
-
* Normaliza cualquier LogMessage a string, aplicando PII (si procede) ANTES de serializar.
|
|
7
|
-
*/
|
|
8
|
-
function normalizeLogMessage(value, redactEnabled, redactor) {
|
|
9
|
-
const v = redactEnabled ? redactor.redact(value) : value;
|
|
10
|
-
if (typeof v === "string")
|
|
11
|
-
return v;
|
|
12
|
-
// Si soportas Error en LogMessage, lo serializamos “bonito”
|
|
13
|
-
if (v instanceof Error) {
|
|
14
|
-
const err = v;
|
|
15
|
-
const obj = {
|
|
16
|
-
error: err.name || "Error",
|
|
17
|
-
message: err.message,
|
|
18
|
-
stack: err.stack,
|
|
19
|
-
code: err.code,
|
|
20
|
-
cause: err.cause,
|
|
21
|
-
};
|
|
22
|
-
try {
|
|
23
|
-
return JSON.stringify(obj);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return `${obj.error}: ${obj.message}`;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// Objeto → JSON
|
|
30
|
-
try {
|
|
31
|
-
return JSON.stringify(v);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// fallback ultra defensivo
|
|
35
|
-
return String(v);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function createLogger(ds, opts = {}) {
|
|
39
|
-
const minLevel = opts.minLevel ?? __1.LogLevel.INFO;
|
|
40
|
-
// Compatibilidad: redactPII (boolean) o pii.enabled
|
|
41
|
-
const redactEnabled = (opts.redactPII ?? false) || (opts.pii?.enabled ?? false);
|
|
42
|
-
// Inicializa redactor con opciones del cliente (incluye defaults por defecto)
|
|
43
|
-
const redactor = new __1.PiiRedactor({
|
|
44
|
-
enabled: redactEnabled,
|
|
45
|
-
includeDefaultPatterns: opts.pii?.includeDefaultPatterns ?? true,
|
|
46
|
-
patterns: opts.pii?.patterns,
|
|
47
|
-
redactKeys: opts.pii?.redactKeys,
|
|
48
|
-
preserveKeys: opts.pii?.preserveKeys,
|
|
49
|
-
});
|
|
50
|
-
const emit = async (level, message, meta) => {
|
|
51
|
-
if (level < minLevel)
|
|
52
|
-
return;
|
|
53
|
-
const msgStr = normalizeLogMessage(message, redactEnabled, redactor);
|
|
54
|
-
const metaVal = redactEnabled ? redactor.redact(meta) : meta;
|
|
55
|
-
const payload = {
|
|
56
|
-
level,
|
|
57
|
-
timestamp: Date.now(),
|
|
58
|
-
message: msgStr, // <- garantizamos string
|
|
59
|
-
meta: metaVal,
|
|
60
|
-
};
|
|
61
|
-
await ds.save(payload);
|
|
62
|
-
};
|
|
63
|
-
const logger = {
|
|
64
|
-
trace: (m, meta) => emit(__1.LogLevel.TRACE, m, meta),
|
|
65
|
-
debug: (m, meta) => emit(__1.LogLevel.DEBUG, m, meta),
|
|
66
|
-
info: (m, meta) => emit(__1.LogLevel.INFO, m, meta),
|
|
67
|
-
warn: (m, meta) => emit(__1.LogLevel.WARN, m, meta),
|
|
68
|
-
error: (m, meta) => emit(__1.LogLevel.ERROR, m, meta),
|
|
69
|
-
fatal: (m, meta) => emit(__1.LogLevel.FATAL, m, meta),
|
|
70
|
-
flush: () => ds.flush?.() ?? Promise.resolve(),
|
|
71
|
-
dispose: () => ds.dispose?.() ?? Promise.resolve(),
|
|
72
|
-
};
|
|
73
|
-
return logger;
|
|
74
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./factory";
|