jspg union fixes

This commit is contained in:
2025-10-07 20:43:23 -04:00
parent 9ddc899411
commit 44cde90c3d
3 changed files with 250 additions and 2 deletions

View File

@ -265,8 +265,51 @@ fn walk_and_validate_refs(
}
if let Some(one_of_array) = schema.get("oneOf").and_then(|v| v.as_array()) {
for sub_schema in one_of_array {
walk_and_validate_refs(instance, sub_schema, cache, path_parts, type_validated, None, errors);
let is_clean_ref_union = one_of_array.iter().all(|s| s.get("$ref").is_some());
if is_clean_ref_union {
if let Some(actual_type) = instance.get("type").and_then(|v| v.as_str()) {
let mut match_found = false;
for sub_schema in one_of_array {
if let Some(ref_url) = sub_schema.get("$ref").and_then(|v| v.as_str()) {
if ref_url == actual_type {
walk_and_validate_refs(instance, sub_schema, cache, path_parts, type_validated, None, errors);
match_found = true;
break;
}
}
}
if !match_found {
let path = format!("/{}", path_parts.join("/"));
errors.push(json!({
"code": "TYPE_MISMATCH_IN_UNION",
"message": format!("Instance type '{}' does not match any of the allowed types in the union", actual_type),
"details": {
"path": path,
"context": instance,
"cause": {
"actual": actual_type,
"expected": one_of_array.iter()
.filter_map(|s| s.get("$ref").and_then(|r| r.as_str()))
.collect::<Vec<_>>()
},
"schema": top_level_id.unwrap_or("")
}
}));
}
} else {
let path = format!("/{}", path_parts.join("/"));
errors.push(json!({
"code": "TYPE_REQUIRED_FOR_UNION",
"message": "Instance is missing 'type' property required for union (oneOf) validation",
"details": { "path": path, "context": instance, "schema": top_level_id.unwrap_or("") }
}));
}
return;
} else {
for sub_schema in one_of_array {
walk_and_validate_refs(instance, sub_schema, cache, path_parts, type_validated, None, errors);
}
}
}