redact.ts 1014 B

1234567891011121314151617181920212223242526
  1. const SECRET_PATTERN = /(authorization|api[-_]?key|token|password|secret|dsn|database_url|connection_string)/i;
  2. export function redact(value: unknown, depth = 0): unknown {
  3. if (depth > 8) return "[DEPTH_LIMIT]";
  4. if (Array.isArray(value)) return value.map((item) => redact(item, depth + 1));
  5. if (value && typeof value === "object") {
  6. return Object.fromEntries(
  7. Object.entries(value as Record<string, unknown>).map(([key, item]) => [
  8. key,
  9. SECRET_PATTERN.test(key) ? "[REDACTED]" : redact(item, depth + 1)
  10. ])
  11. );
  12. }
  13. if (typeof value === "string") {
  14. return value
  15. .replace(/Bearer\s+[A-Za-z0-9._~+\/-]+/gi, "Bearer [REDACTED]")
  16. .replace(/(postgres(?:ql)?:\/\/)[^\s@]+@/gi, "$1[REDACTED]@");
  17. }
  18. return value;
  19. }
  20. export function pretty(value: unknown): string {
  21. if (value === undefined || value === null || value === "") return "无记录";
  22. if (typeof value === "string") return String(redact(value));
  23. return JSON.stringify(redact(value), null, 2);
  24. }