@geekmidas/logger 0.3.0 → 1.0.0
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/CHANGELOG.md +7 -0
- package/dist/console.cjs.map +1 -1
- package/dist/console.d.cts +2 -1
- package/dist/console.d.cts.map +1 -0
- package/dist/console.d.mts +2 -1
- package/dist/console.d.mts.map +1 -0
- package/dist/console.mjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/pino.cjs.map +1 -1
- package/dist/pino.d.cts +3 -2
- package/dist/pino.d.cts.map +1 -0
- package/dist/pino.d.mts +3 -2
- package/dist/pino.d.mts.map +1 -0
- package/dist/pino.mjs.map +1 -1
- package/dist/{redact-paths-Br-tI2GZ.d.cts → redact-paths-CsK0_uz-.d.cts} +2 -1
- package/dist/redact-paths-CsK0_uz-.d.cts.map +1 -0
- package/dist/{redact-paths-CIsuxHH7.d.mts → redact-paths-D07eTMlH.d.mts} +2 -1
- package/dist/redact-paths-D07eTMlH.d.mts.map +1 -0
- package/dist/redact-paths-D0m0DIuQ.cjs.map +1 -1
- package/dist/redact-paths-DQoIXhkS.mjs.map +1 -1
- package/dist/redact-paths.d.cts +1 -1
- package/dist/redact-paths.d.mts +1 -1
- package/dist/{types-Bga8WDuP.d.mts → types-BDdpcrpy.d.mts} +2 -1
- package/dist/types-BDdpcrpy.d.mts.map +1 -0
- package/dist/{types-JxCFymH0.d.cts → types-Dk_k2-f_.d.cts} +2 -1
- package/dist/types-Dk_k2-f_.d.cts.map +1 -0
- package/dist/types-ag_0Cvbg.cjs.map +1 -1
- package/dist/types-yQ6XOihF.mjs.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +1 -1
- package/src/__tests__/console.spec.ts +648 -648
- package/src/__tests__/pino-redaction.integration.spec.ts +270 -270
- package/src/__tests__/pino.spec.ts +305 -305
- package/src/console.ts +100 -100
- package/src/index.ts +5 -5
- package/src/pino.ts +50 -50
- package/src/redact-paths.ts +52 -52
- package/src/types.ts +87 -87
- package/tsconfig.json +9 -0
|
@@ -4,352 +4,352 @@ import { LogLevel } from '../types';
|
|
|
4
4
|
|
|
5
5
|
// Mock pino module
|
|
6
6
|
vi.mock('pino', () => ({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
pino: vi.fn((options) => ({
|
|
8
|
+
_options: options,
|
|
9
|
+
debug: vi.fn(),
|
|
10
|
+
info: vi.fn(),
|
|
11
|
+
warn: vi.fn(),
|
|
12
|
+
error: vi.fn(),
|
|
13
|
+
fatal: vi.fn(),
|
|
14
|
+
trace: vi.fn(),
|
|
15
|
+
})),
|
|
16
16
|
}));
|
|
17
17
|
|
|
18
18
|
describe('Pino Logger', () => {
|
|
19
|
-
|
|
19
|
+
let pinoMock: any;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
beforeEach(async () => {
|
|
22
|
+
vi.clearAllMocks();
|
|
23
|
+
const pinoModule = await import('pino');
|
|
24
|
+
pinoMock = pinoModule.pino;
|
|
25
|
+
});
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
describe('createLogger', () => {
|
|
28
|
+
it('should create pino logger with default options', async () => {
|
|
29
|
+
const { createLogger } = await import('../pino');
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
const logger = createLogger({});
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
expect(pinoMock).toHaveBeenCalled();
|
|
34
|
+
expect(logger).toBeDefined();
|
|
35
|
+
});
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
it('should create logger with pretty formatting in development', async () => {
|
|
38
|
+
const { createLogger } = await import('../pino');
|
|
39
|
+
const originalEnv = process.env.NODE_ENV;
|
|
40
|
+
process.env.NODE_ENV = 'development';
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
createLogger({ pretty: true });
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
expect(pinoMock).toHaveBeenCalledWith(
|
|
45
|
+
expect.objectContaining({
|
|
46
|
+
transport: {
|
|
47
|
+
target: 'pino-pretty',
|
|
48
|
+
options: { colorize: true },
|
|
49
|
+
},
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
process.env.NODE_ENV = originalEnv;
|
|
54
|
+
});
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
it('should not use pretty formatting when pretty is false', async () => {
|
|
57
|
+
const { createLogger } = await import('../pino');
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
createLogger({ pretty: false });
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
62
|
+
expect(callArgs.transport).toBeUndefined();
|
|
63
|
+
});
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
it('should configure formatters', async () => {
|
|
66
|
+
const { createLogger } = await import('../pino');
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
createLogger({});
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
71
|
+
expect(callArgs.formatters).toBeDefined();
|
|
72
|
+
expect(callArgs.formatters.bindings).toBeInstanceOf(Function);
|
|
73
|
+
expect(callArgs.formatters.level).toBeInstanceOf(Function);
|
|
74
|
+
});
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
it('should format bindings with node version', async () => {
|
|
77
|
+
const { createLogger } = await import('../pino');
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
createLogger({});
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
82
|
+
const bindings = callArgs.formatters.bindings();
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
expect(bindings).toEqual({
|
|
85
|
+
nodeVersion: process.version,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
it('should format level labels to uppercase', async () => {
|
|
90
|
+
const { createLogger } = await import('../pino');
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
createLogger({});
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
95
|
+
const levelFormatter = callArgs.formatters.level;
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
expect(levelFormatter('info')).toEqual({ level: 'INFO' });
|
|
98
|
+
expect(levelFormatter('debug')).toEqual({ level: 'DEBUG' });
|
|
99
|
+
expect(levelFormatter('error')).toEqual({ level: 'ERROR' });
|
|
100
|
+
expect(levelFormatter('warn')).toEqual({ level: 'WARN' });
|
|
101
|
+
});
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
it('should accept log level option', async () => {
|
|
104
|
+
const { createLogger } = await import('../pino');
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
const logger = createLogger({ level: LogLevel.Debug });
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
expect(logger).toBeDefined();
|
|
109
|
+
// Note: The actual level setting depends on pino's implementation
|
|
110
|
+
});
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
it('should handle undefined options', async () => {
|
|
113
|
+
const { createLogger } = await import('../pino');
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
const logger = createLogger({});
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
expect(logger).toBeDefined();
|
|
118
|
+
expect(pinoMock).toHaveBeenCalled();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
describe('Logger options', () => {
|
|
123
|
+
it('should support pretty option', async () => {
|
|
124
|
+
const { createLogger } = await import('../pino');
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
const logger1 = createLogger({ pretty: true });
|
|
127
|
+
const logger2 = createLogger({ pretty: false });
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
expect(logger1).toBeDefined();
|
|
130
|
+
expect(logger2).toBeDefined();
|
|
131
|
+
});
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
it('should support level option', async () => {
|
|
134
|
+
const { createLogger } = await import('../pino');
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
const logger1 = createLogger({ level: LogLevel.Info });
|
|
137
|
+
const logger2 = createLogger({ level: LogLevel.Debug });
|
|
138
|
+
const logger3 = createLogger({ level: LogLevel.Error });
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
expect(logger1).toBeDefined();
|
|
141
|
+
expect(logger2).toBeDefined();
|
|
142
|
+
expect(logger3).toBeDefined();
|
|
143
|
+
});
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
it('should support combined options', async () => {
|
|
146
|
+
const { createLogger } = await import('../pino');
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
const logger = createLogger({
|
|
149
|
+
pretty: true,
|
|
150
|
+
level: LogLevel.Debug,
|
|
151
|
+
});
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
expect(logger).toBeDefined();
|
|
154
|
+
expect(pinoMock).toHaveBeenCalled();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
describe('Redaction', () => {
|
|
159
|
+
it('should not configure redaction when redact is undefined', async () => {
|
|
160
|
+
const { createLogger } = await import('../pino');
|
|
161
|
+
|
|
162
|
+
createLogger({});
|
|
163
163
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
165
|
+
expect(callArgs.redact).toBeUndefined();
|
|
166
|
+
});
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
168
|
+
it('should not configure redaction when redact is false', async () => {
|
|
169
|
+
const { createLogger } = await import('../pino');
|
|
170
|
+
|
|
171
|
+
createLogger({ redact: false });
|
|
172
|
+
|
|
173
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
174
|
+
expect(callArgs.redact).toBeUndefined();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should use default redact paths when redact is true', async () => {
|
|
178
|
+
const { createLogger } = await import('../pino');
|
|
179
|
+
|
|
180
|
+
createLogger({ redact: true });
|
|
181
|
+
|
|
182
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
183
|
+
expect(callArgs.redact).toEqual(DEFAULT_REDACT_PATHS);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should merge custom paths with defaults when redact is an array', async () => {
|
|
187
|
+
const { createLogger } = await import('../pino');
|
|
188
|
+
const customPaths = ['custom.field', 'user.ssn'];
|
|
189
|
+
|
|
190
|
+
createLogger({ redact: customPaths });
|
|
191
|
+
|
|
192
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
193
|
+
// Should include both defaults and custom paths
|
|
194
|
+
expect(callArgs.redact).toEqual([
|
|
195
|
+
...DEFAULT_REDACT_PATHS,
|
|
196
|
+
...customPaths,
|
|
197
|
+
]);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should merge object config paths with defaults by default', async () => {
|
|
201
|
+
const { createLogger } = await import('../pino');
|
|
202
|
+
const customPaths = ['custom.field'];
|
|
203
|
+
|
|
204
|
+
createLogger({
|
|
205
|
+
redact: {
|
|
206
|
+
paths: customPaths,
|
|
207
|
+
censor: '***HIDDEN***',
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
212
|
+
expect(callArgs.redact.paths).toEqual([
|
|
213
|
+
...DEFAULT_REDACT_PATHS,
|
|
214
|
+
...customPaths,
|
|
215
|
+
]);
|
|
216
|
+
expect(callArgs.redact.censor).toBe('***HIDDEN***');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should override defaults when resolution is override', async () => {
|
|
220
|
+
const { createLogger } = await import('../pino');
|
|
221
|
+
const customPaths = ['only.this.path'];
|
|
222
|
+
|
|
223
|
+
createLogger({
|
|
224
|
+
redact: {
|
|
225
|
+
paths: customPaths,
|
|
226
|
+
resolution: 'override',
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
231
|
+
expect(callArgs.redact.paths).toEqual(customPaths);
|
|
232
|
+
// Should not include defaults
|
|
233
|
+
expect(callArgs.redact.paths).not.toContain('password');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('should merge with defaults when resolution is merge', async () => {
|
|
237
|
+
const { createLogger } = await import('../pino');
|
|
238
|
+
const customPaths = ['extra.secret'];
|
|
239
|
+
|
|
240
|
+
createLogger({
|
|
241
|
+
redact: {
|
|
242
|
+
paths: customPaths,
|
|
243
|
+
resolution: 'merge',
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
248
|
+
expect(callArgs.redact.paths).toEqual([
|
|
249
|
+
...DEFAULT_REDACT_PATHS,
|
|
250
|
+
...customPaths,
|
|
251
|
+
]);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should support remove option in redact config', async () => {
|
|
255
|
+
const { createLogger } = await import('../pino');
|
|
256
|
+
|
|
257
|
+
createLogger({
|
|
258
|
+
redact: {
|
|
259
|
+
paths: ['temp.data'],
|
|
260
|
+
remove: true,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
265
|
+
expect(callArgs.redact.remove).toBe(true);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should support censor function in redact config', async () => {
|
|
269
|
+
const { createLogger } = await import('../pino');
|
|
270
|
+
const censorFn = () => '***';
|
|
271
|
+
|
|
272
|
+
createLogger({
|
|
273
|
+
redact: {
|
|
274
|
+
paths: ['secret'],
|
|
275
|
+
censor: censorFn,
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
280
|
+
expect(callArgs.redact.censor).toBe(censorFn);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('should not include resolution field in pino config', async () => {
|
|
284
|
+
const { createLogger } = await import('../pino');
|
|
285
|
+
|
|
286
|
+
createLogger({
|
|
287
|
+
redact: {
|
|
288
|
+
paths: ['secret'],
|
|
289
|
+
resolution: 'override',
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
294
|
+
expect(callArgs.redact).not.toHaveProperty('resolution');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should combine redact with other options', async () => {
|
|
298
|
+
const { createLogger } = await import('../pino');
|
|
299
|
+
|
|
300
|
+
createLogger({
|
|
301
|
+
level: LogLevel.Debug,
|
|
302
|
+
redact: true,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const callArgs = pinoMock.mock.calls[pinoMock.mock.calls.length - 1][0];
|
|
306
|
+
expect(callArgs.level).toBe(LogLevel.Debug);
|
|
307
|
+
expect(callArgs.redact).toEqual(DEFAULT_REDACT_PATHS);
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe('DEFAULT_REDACT_PATHS', () => {
|
|
312
|
+
it('should include common password fields', () => {
|
|
313
|
+
expect(DEFAULT_REDACT_PATHS).toContain('password');
|
|
314
|
+
expect(DEFAULT_REDACT_PATHS).toContain('pass');
|
|
315
|
+
expect(DEFAULT_REDACT_PATHS).toContain('passwd');
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('should include token fields', () => {
|
|
319
|
+
expect(DEFAULT_REDACT_PATHS).toContain('token');
|
|
320
|
+
expect(DEFAULT_REDACT_PATHS).toContain('accessToken');
|
|
321
|
+
expect(DEFAULT_REDACT_PATHS).toContain('refreshToken');
|
|
322
|
+
expect(DEFAULT_REDACT_PATHS).toContain('idToken');
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should include API key variations', () => {
|
|
326
|
+
expect(DEFAULT_REDACT_PATHS).toContain('apiKey');
|
|
327
|
+
expect(DEFAULT_REDACT_PATHS).toContain('api_key');
|
|
328
|
+
expect(DEFAULT_REDACT_PATHS).toContain('apikey');
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('should include authorization headers', () => {
|
|
332
|
+
expect(DEFAULT_REDACT_PATHS).toContain('headers.authorization');
|
|
333
|
+
expect(DEFAULT_REDACT_PATHS).toContain('headers.Authorization');
|
|
334
|
+
expect(DEFAULT_REDACT_PATHS).toContain('headers.cookie');
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it('should include wildcard patterns for nested fields', () => {
|
|
338
|
+
expect(DEFAULT_REDACT_PATHS).toContain('*.password');
|
|
339
|
+
expect(DEFAULT_REDACT_PATHS).toContain('*.secret');
|
|
340
|
+
expect(DEFAULT_REDACT_PATHS).toContain('*.token');
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('should include sensitive personal data fields', () => {
|
|
344
|
+
expect(DEFAULT_REDACT_PATHS).toContain('ssn');
|
|
345
|
+
expect(DEFAULT_REDACT_PATHS).toContain('creditCard');
|
|
346
|
+
expect(DEFAULT_REDACT_PATHS).toContain('cardNumber');
|
|
347
|
+
expect(DEFAULT_REDACT_PATHS).toContain('cvv');
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('should include database connection strings', () => {
|
|
351
|
+
expect(DEFAULT_REDACT_PATHS).toContain('connectionString');
|
|
352
|
+
expect(DEFAULT_REDACT_PATHS).toContain('databaseUrl');
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
355
|
});
|