| 21 | } |
| 22 | |
| 23 | function flatten( |
| 24 | input: Record<string, unknown>, |
| 25 | prefix = "", |
| 26 | seen = new WeakSet<object>(), |
| 27 | ): Array<readonly [string, unknown]> { |
| 28 | if (seen.has(input)) return [[prefix, "[Circular]"]] |
| 29 | seen.add(input) |
| 30 | const entries = Object.entries(input) |
| 31 | if (entries.length === 0 && prefix) return [[prefix, input]] |
| 32 | return entries.flatMap(([key, value]) => { |
| 33 | const path = prefix ? `${prefix}.${key}` : key |
| 34 | return plain(value) ? flatten(value, path, seen) : [[path, value] as const] |
| 35 | }) |
| 36 | } |
| 37 | |
| 38 | function plain(input: unknown): input is Record<string, unknown> { |
| 39 | if (input === null || typeof input !== "object" || Array.isArray(input)) return false |