(value: unknown, options: JsonSafeOptions)
| 98 | } |
| 99 | |
| 100 | function toJsonSafe(value: unknown, options: JsonSafeOptions): unknown { |
| 101 | if (value === undefined) { |
| 102 | return null; |
| 103 | } |
| 104 | |
| 105 | if (value === null) { |
| 106 | return null; |
| 107 | } |
| 108 | |
| 109 | if (typeof value === "bigint") { |
| 110 | return value.toString(); |
| 111 | } |
| 112 | |
| 113 | if (typeof value === "function") { |
| 114 | return `[Function${value.name ? ` ${value.name}` : ""}]`; |
| 115 | } |
| 116 | |
| 117 | if (typeof value === "symbol") { |
| 118 | return value.toString(); |
| 119 | } |
| 120 | |
| 121 | if (value instanceof URL) { |
| 122 | return value.toString(); |
| 123 | } |
| 124 | |
| 125 | if (value instanceof Date) { |
| 126 | return value.toISOString(); |
| 127 | } |
| 128 | |
| 129 | if (value instanceof Error) { |
| 130 | return { |
| 131 | name: value.name, |
| 132 | message: value.message, |
| 133 | stack: value.stack, |
| 134 | cause: |
| 135 | options.depth > 0 |
| 136 | ? toJsonSafe(value.cause, { ...options, depth: options.depth - 1 }) |
| 137 | : undefined, |
| 138 | }; |
| 139 | } |
| 140 | |
| 141 | if (Array.isArray(value)) { |
| 142 | if (options.depth <= 0) { |
| 143 | return `Array(${value.length})`; |
| 144 | } |
| 145 | |
| 146 | return value |
| 147 | .slice(0, 100) |
| 148 | .map((entry) => toJsonSafe(entry, { ...options, depth: options.depth - 1 })); |
| 149 | } |
| 150 | |
| 151 | if (isPlainObject(value)) { |
| 152 | if (options.seen.has(value)) { |
| 153 | return "[Circular]"; |
| 154 | } |
| 155 | |
| 156 | if (options.depth <= 0) { |
| 157 | return `Object(${Object.keys(value).length})`; |
no test coverage detected