( value: unknown, depth = 0, seen: WeakSet<object> = new WeakSet() )
| 100 | * downstream by `truncateString` and `capNormalizedValue`, not by depth. |
| 101 | */ |
| 102 | export function normalizeConsoleValue( |
| 103 | value: unknown, |
| 104 | depth = 0, |
| 105 | seen: WeakSet<object> = new WeakSet() |
| 106 | ): unknown { |
| 107 | if (value === null || value === undefined) { |
| 108 | return value |
| 109 | } |
| 110 | |
| 111 | if (typeof value === 'string') { |
| 112 | return truncateString(value) |
| 113 | } |
| 114 | |
| 115 | if (typeof value === 'number' || typeof value === 'boolean') { |
| 116 | return value |
| 117 | } |
| 118 | |
| 119 | if (typeof value === 'bigint') { |
| 120 | return `${value.toString()}n` |
| 121 | } |
| 122 | |
| 123 | if (typeof value === 'function') { |
| 124 | return `[Function ${value.name || 'anonymous'}]` |
| 125 | } |
| 126 | |
| 127 | if (typeof value === 'symbol') { |
| 128 | return value.toString() |
| 129 | } |
| 130 | |
| 131 | if (value instanceof Error) { |
| 132 | return { |
| 133 | name: value.name, |
| 134 | message: truncateString(value.message), |
| 135 | stack: value.stack ? truncateString(value.stack) : undefined, |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | if (depth >= TERMINAL_CONSOLE_LIMITS.MAX_DEPTH) { |
| 140 | return `[Truncated ${Array.isArray(value) ? 'array' : 'object'}]` |
| 141 | } |
| 142 | |
| 143 | const objectValue = value as object |
| 144 | |
| 145 | if (seen.has(objectValue)) { |
| 146 | return '[Circular]' |
| 147 | } |
| 148 | |
| 149 | seen.add(objectValue) |
| 150 | |
| 151 | try { |
| 152 | if (Array.isArray(value)) { |
| 153 | const normalizedItems = value |
| 154 | .slice(0, TERMINAL_CONSOLE_LIMITS.MAX_ARRAY_ITEMS) |
| 155 | .map((item) => normalizeConsoleValue(item, depth + 1, seen)) |
| 156 | |
| 157 | if (value.length > TERMINAL_CONSOLE_LIMITS.MAX_ARRAY_ITEMS) { |
| 158 | normalizedItems.push( |
| 159 | `[... truncated ${value.length - TERMINAL_CONSOLE_LIMITS.MAX_ARRAY_ITEMS} items]` |
no test coverage detected