( obj: Record<string, unknown>, ctx: RedactionContext, currentPath: string, )
| 277 | } |
| 278 | |
| 279 | function redactObject( |
| 280 | obj: Record<string, unknown>, |
| 281 | ctx: RedactionContext, |
| 282 | currentPath: string, |
| 283 | ): Record<string, unknown> { |
| 284 | if (ctx.seen.has(obj)) return { _circular: REDACTED } |
| 285 | ctx.seen.add(obj) |
| 286 | |
| 287 | const result: Record<string, unknown> = {} |
| 288 | const sensitiveKeysLower = ctx.parsed.sensitiveKeysLower |
| 289 | const trackPaths = ctx.parsed.trackPaths |
| 290 | |
| 291 | for (const [key, value] of Object.entries(obj)) { |
| 292 | // Common case first — most keys aren't path-pattern matches. |
| 293 | if (sensitiveKeysLower.has(key.toLowerCase())) { |
| 294 | result[key] = REDACTED |
| 295 | continue |
| 296 | } |
| 297 | |
| 298 | if (trackPaths) { |
| 299 | const childPath = currentPath ? `${currentPath}.${key}` : key |
| 300 | if (matchesStatePath(childPath, ctx.parsed.statePathPatterns)) { |
| 301 | result[key] = REDACTED |
| 302 | continue |
| 303 | } |
| 304 | result[key] = redactValue(value, ctx, childPath) |
| 305 | } else { |
| 306 | result[key] = redactValue(value, ctx, "") |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | return result |
| 311 | } |
| 312 | |
| 313 | function redactStringValue(value: string, ctx: RedactionContext): string { |
| 314 | let result = value |
no test coverage detected