(left: InferredShape, right: InferredShape)
| 131 | * `anyOf`, degrading to unknown past `MAX_ANYOF` branches. |
| 132 | */ |
| 133 | export const mergeShapes = (left: InferredShape, right: InferredShape): InferredShape => { |
| 134 | if (isUnknown(left) || isUnknown(right)) return UNKNOWN; |
| 135 | |
| 136 | if (left.anyOf !== undefined || right.anyOf !== undefined) { |
| 137 | const branches = [...(left.anyOf ?? [left]), ...(right.anyOf ?? [right])]; |
| 138 | return branches.reduce((merged, branch) => addUnionBranch(merged, branch), { |
| 139 | anyOf: [], |
| 140 | } as InferredShape); |
| 141 | } |
| 142 | |
| 143 | if (left.type !== right.type) return addUnionBranch({ anyOf: [left] }, right); |
| 144 | |
| 145 | if (left.type === "object") return mergeObjectShapes(left, right); |
| 146 | if (left.type === "array") { |
| 147 | if (left.items === undefined) return right; |
| 148 | if (right.items === undefined) return left; |
| 149 | return { type: "array", items: mergeShapes(left.items, right.items) }; |
| 150 | } |
| 151 | return left; |
| 152 | }; |
| 153 | |
| 154 | const addUnionBranch = (union: InferredShape, branch: InferredShape): InferredShape => { |
| 155 | if (isUnknown(union) || isUnknown(branch)) return UNKNOWN; |
no test coverage detected