diff --git a/preprocess_schemas.py b/preprocess_schemas.py index 69df1f6..36579d9 100644 --- a/preprocess_schemas.py +++ b/preprocess_schemas.py @@ -381,6 +381,14 @@ def _create_single_variant( variant["properties"] = new_props variant["required"] = new_required + + # Rewrite all external $refs in the variant schema to point to their + # corresponding request variants where applicable. This covers top-level + # oneOf/anyOf/allOf branches as well as array items. + rewrite_refs_to_variants( + variant, op, file_path, global_variant_requirements + ) + return variant @@ -437,19 +445,28 @@ def normalize_metadata_schemas(schemas, target_dir): def extract_external_refs(schema, path): - """Finds all relative external file references in the schema properties.""" + """Finds all relative external file references in the schema.""" refs = [] - props = schema.get("properties", {}) - if not isinstance(props, dict): - return refs - for name, data in props.items(): + def _scan(name, data): for node in iter_nodes(data): if isinstance(node, dict) and "$ref" in node: ref = node["$ref"] if "#" not in ref: abs_path = str((path.parent / ref).resolve()) refs.append((name, abs_path)) + + props = schema.get("properties", {}) + if isinstance(props, dict): + for name, data in props.items(): + _scan(name, data) + + # Also scan top-level composition keywords (oneOf, anyOf, allOf, items) + for key in ["oneOf", "anyOf", "allOf"]: + if key in schema: + _scan(key, schema[key]) + if "items" in schema: + _scan("items", schema["items"]) return refs @@ -466,23 +483,28 @@ def propagate_needs_transitive(variant_needs, schema_refs, schemas): continue for op in list(variant_needs[path]): - for prop_name, child_path in refs: + for ref_name, child_path in refs: if child_path not in schemas: continue - # Only propagate if the property isn't 'omit'ted for this op - data = ( - schemas[path].get("properties", {}).get(prop_name, {}) - ) - include, _ = eval_prop_inclusion( - prop_name, data, op, schemas[path].get("required", []) - ) - - if include: - target_set = variant_needs.setdefault(child_path, set()) - if op not in target_set: - target_set.add(op) - changed = True + # For property refs, check if the property is included for this op. + # For non-property refs (oneOf, anyOf, allOf, items), always propagate. + props = schemas[path].get("properties", {}) + if ref_name in props: + data = props[ref_name] + include, _ = eval_prop_inclusion( + ref_name, + data, + op, + schemas[path].get("required", []), + ) + if not include: + continue + + target_set = variant_needs.setdefault(child_path, set()) + if op not in target_set: + target_set.add(op) + changed = True # --- Main Flow --- diff --git a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_create_request.py b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_create_request.py index bb6f986..83cdd56 100644 --- a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_create_request.py +++ b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_create_request.py @@ -20,21 +20,24 @@ from pydantic import ConfigDict, Field, RootModel -from . import retail_location, shipping_destination +from . import ( + retail_location_create_request, + shipping_destination_create_request, +) class FulfillmentDestinationCreateRequest( RootModel[ - shipping_destination.ShippingDestination - | retail_location.RetailLocation + shipping_destination_create_request.ShippingDestinationCreateRequest + | retail_location_create_request.RetailLocationCreateRequest ] ): model_config = ConfigDict( frozen=True, ) root: ( - shipping_destination.ShippingDestination - | retail_location.RetailLocation + shipping_destination_create_request.ShippingDestinationCreateRequest + | retail_location_create_request.RetailLocationCreateRequest ) = Field(..., title="Fulfillment Destination Create Request") """ A destination for fulfillment. diff --git a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_update_request.py b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_update_request.py index 4bcc34c..32db211 100644 --- a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_update_request.py +++ b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_destination_update_request.py @@ -20,21 +20,24 @@ from pydantic import ConfigDict, Field, RootModel -from . import retail_location, shipping_destination +from . import ( + retail_location_update_request, + shipping_destination_update_request, +) class FulfillmentDestinationUpdateRequest( RootModel[ - shipping_destination.ShippingDestination - | retail_location.RetailLocation + shipping_destination_update_request.ShippingDestinationUpdateRequest + | retail_location_update_request.RetailLocationUpdateRequest ] ): model_config = ConfigDict( frozen=True, ) root: ( - shipping_destination.ShippingDestination - | retail_location.RetailLocation + shipping_destination_update_request.ShippingDestinationUpdateRequest + | retail_location_update_request.RetailLocationUpdateRequest ) = Field(..., title="Fulfillment Destination Update Request") """ A destination for fulfillment. diff --git a/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_create_request.py b/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_create_request.py index 169dfa6..05ddf80 100644 --- a/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_create_request.py +++ b/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_create_request.py @@ -20,10 +20,10 @@ from pydantic import ConfigDict -from .postal_address import PostalAddress +from .postal_address_create_request import PostalAddressCreateRequest -class ShippingDestinationCreateRequest(PostalAddress): +class ShippingDestinationCreateRequest(PostalAddressCreateRequest): """ Shipping destination. """ diff --git a/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_update_request.py b/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_update_request.py index 7712dea..79556e1 100644 --- a/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_update_request.py +++ b/src/ucp_sdk/models/schemas/shopping/types/shipping_destination_update_request.py @@ -20,10 +20,10 @@ from pydantic import ConfigDict -from .postal_address import PostalAddress +from .postal_address_update_request import PostalAddressUpdateRequest -class ShippingDestinationUpdateRequest(PostalAddress): +class ShippingDestinationUpdateRequest(PostalAddressUpdateRequest): """ Shipping destination. """