function isOptionalSchema(schema) {
    return schema.kind === "optional";
}
function getRequiredKeys(schema) {
    return Object.keys(schema.shape)
        .filter((key) => !isOptionalSchema(schema.shape[key]))
        .sort();
}
export function getRequiredKeyFingerprint(schema) {
    return getRequiredKeys(schema).join("+");
}
function assertUniqueRequiredKeyFingerprints(branches) {
    const fingerprints = new Map();
    branches.forEach((branch, index) => {
        const requiredKeys = getRequiredKeys(branch);
        const fingerprint = JSON.stringify(requiredKeys);
        const existing = fingerprints.get(fingerprint);
        if (existing === undefined) {
            fingerprints.set(fingerprint, {
                display: requiredKeys.join("+"),
                indices: [index],
            });
            return;
        }
        existing.indices.push(index);
    });
    for (const { display, indices } of fingerprints.values()) {
        if (indices.length > 1) {
            throw new Error(`Union branches [${indices.join(", ")}] share required-key fingerprint "${display}". Each branch must require a distinct set of keys.`);
        }
    }
}
function assertValidBranches(branches) {
    if (branches.length === 0) {
        throw new Error("Union schema requires at least one branch");
    }
    assertUniqueRequiredKeyFingerprints(branches);
}
export function Union(branches) {
    assertValidBranches(branches);
    return {
        kind: "union",
        branches,
    };
}
