(ctx: LogContext)
| 52 | } |
| 53 | |
| 54 | export function redactCtx(ctx: LogContext): LogContext { |
| 55 | const seen = new WeakSet<object>(); |
| 56 | const walk = (value: unknown, depth: number): unknown => { |
| 57 | if (depth > REDACT_MAX_DEPTH) return '[REDACTED:depth]'; |
| 58 | if (value === null || typeof value !== 'object') return value; |
| 59 | if (seen.has(value)) return '[REDACTED:cycle]'; |
| 60 | seen.add(value); |
| 61 | if (Array.isArray(value)) { |
| 62 | return value.map((item) => walk(item, depth + 1)); |
| 63 | } |
| 64 | const out: Record<string, unknown> = {}; |
| 65 | for (const [key, raw] of Object.entries(value as Record<string, unknown>)) { |
| 66 | out[key] = REDACTED_KEYS.has(normalizeKey(key)) |
| 67 | ? REDACTED |
| 68 | : walk(raw, depth + 1); |
| 69 | } |
| 70 | return out; |
| 71 | }; |
| 72 | return walk(ctx, 0) as LogContext; |
| 73 | } |
| 74 | |
| 75 | export interface FormatOptions { |
| 76 | readonly ansi?: boolean | undefined; |
no test coverage detected