@@ -949,6 +949,7 @@ if Code.ensure_loaded?(OpenApiSpex) do
949
949
# We're in a recursive loop, return $ref and warn
950
950
# Recursive type detected, using $ref instead of inline definition
951
951
require Logger
952
+
952
953
Logger . warning (
953
954
"Detected recursive embedded type with JSON API type: #{ inspect ( instance_of ) } "
954
955
)
@@ -1079,12 +1080,12 @@ if Code.ensure_loaded?(OpenApiSpex) do
1079
1080
# Generate the schema name based on parent context when needed
1080
1081
parent_type = AshJsonApi.Resource.Info . type ( parent_resource )
1081
1082
attribute_name = Map . get ( attribute , :name )
1082
-
1083
+
1083
1084
# Check if this embedded resource has a JSON API type for input schema naming
1084
1085
json_api_type = AshJsonApi.Resource.Info . type ( embedded_resource )
1085
1086
1086
1087
# Generate schema name - use parent context for embedded resources without their own type
1087
- input_schema_name =
1088
+ input_schema_name =
1088
1089
if json_api_type do
1089
1090
"#{ json_api_type } -input-#{ action_type } "
1090
1091
else
@@ -1111,7 +1112,7 @@ if Code.ensure_loaded?(OpenApiSpex) do
1111
1112
1112
1113
# Create a minimal schema for the recursive type if it doesn't exist
1113
1114
# This ensures the $ref has something to point to
1114
- acc_with_schema =
1115
+ acc_with_schema =
1115
1116
if Map . has_key? ( acc . schemas , input_schema_name ) do
1116
1117
acc
1117
1118
else
@@ -1122,6 +1123,7 @@ if Code.ensure_loaded?(OpenApiSpex) do
1122
1123
properties: % { } ,
1123
1124
description: "Recursive embedded type - see parent schema for structure"
1124
1125
}
1126
+
1125
1127
% { acc | schemas: Map . put ( acc . schemas , input_schema_name , minimal_schema ) }
1126
1128
end
1127
1129
@@ -1155,10 +1157,19 @@ if Code.ensure_loaded?(OpenApiSpex) do
1155
1157
properties: % { } ,
1156
1158
description: "Recursive embedded type"
1157
1159
}
1160
+
1158
1161
{ minimal_schema , acc }
1159
1162
else
1160
1163
new_acc = % { acc | seen_input_types: [ type_key | acc . seen_input_types ] }
1161
- embedded_type_input_impl ( attribute , embedded_resource , action_type , new_acc , format , nil )
1164
+
1165
+ embedded_type_input_impl (
1166
+ attribute ,
1167
+ embedded_resource ,
1168
+ action_type ,
1169
+ new_acc ,
1170
+ format ,
1171
+ nil
1172
+ )
1162
1173
end
1163
1174
end
1164
1175
end
@@ -1581,10 +1592,10 @@ if Code.ensure_loaded?(OpenApiSpex) do
1581
1592
1582
1593
# Get request body and any generated schemas
1583
1594
{ request_body_result , request_schemas } = request_body ( route , resource )
1584
-
1595
+
1585
1596
# Merge request schemas into accumulator
1586
1597
acc_with_request_schemas = % { acc | schemas: Map . merge ( acc . schemas , request_schemas ) }
1587
-
1598
+
1588
1599
operation = % Operation {
1589
1600
description: action_description ( action , route , resource ) ,
1590
1601
operationId: route . name ,
@@ -2046,53 +2057,58 @@ if Code.ensure_loaded?(OpenApiSpex) do
2046
2057
2047
2058
{ multipart_body_schema , multipart_acc } =
2048
2059
request_body_schema ( route , resource , :multipart , empty_acc ( ) )
2049
-
2060
+
2050
2061
# Collect all generated schemas
2051
2062
all_schemas = Map . merge ( json_acc . schemas , multipart_acc . schemas )
2052
2063
2053
- body = if route . type == :route &&
2054
- ( route . method == :delete || Enum . empty? ( json_body_schema . properties . data . properties ) ) do
2055
- nil
2056
- else
2057
- body_required =
2058
- cond do
2059
- route . type in [ :post_to_relationship , :delete_from_relationship , :patch_relationship ] ->
2060
- true
2064
+ body =
2065
+ if route . type == :route &&
2066
+ ( route . method == :delete || Enum . empty? ( json_body_schema . properties . data . properties ) ) do
2067
+ nil
2068
+ else
2069
+ body_required =
2070
+ cond do
2071
+ route . type in [
2072
+ :post_to_relationship ,
2073
+ :delete_from_relationship ,
2074
+ :patch_relationship
2075
+ ] ->
2076
+ true
2061
2077
2062
- route . type == :route ->
2063
- json_body_schema . properties . data . required != [ ]
2078
+ route . type == :route ->
2079
+ json_body_schema . properties . data . required != [ ]
2064
2080
2065
- true ->
2066
- json_body_schema . properties . data . properties . attributes . required != [ ] ||
2067
- json_body_schema . properties . data . properties . relationships . required != [ ]
2068
- end
2081
+ true ->
2082
+ json_body_schema . properties . data . properties . attributes . required != [ ] ||
2083
+ json_body_schema . properties . data . properties . relationships . required != [ ]
2084
+ end
2069
2085
2070
- content =
2071
- if json_body_schema == multipart_body_schema do
2072
- # No file inputs declared, multipart is not necessary
2073
- % {
2074
- "application/vnd.api+json" => % MediaType { schema: json_body_schema }
2075
- }
2076
- else
2077
- % {
2078
- "application/vnd.api+json" => % MediaType { schema: json_body_schema } ,
2079
- "multipart/x.ash+form-data" => % MediaType {
2080
- schema: % Schema {
2081
- multipart_body_schema
2082
- | additionalProperties: % { type: :string , format: :binary }
2086
+ content =
2087
+ if json_body_schema == multipart_body_schema do
2088
+ # No file inputs declared, multipart is not necessary
2089
+ % {
2090
+ "application/vnd.api+json" => % MediaType { schema: json_body_schema }
2091
+ }
2092
+ else
2093
+ % {
2094
+ "application/vnd.api+json" => % MediaType { schema: json_body_schema } ,
2095
+ "multipart/x.ash+form-data" => % MediaType {
2096
+ schema: % Schema {
2097
+ multipart_body_schema
2098
+ | additionalProperties: % { type: :string , format: :binary }
2099
+ }
2083
2100
}
2084
2101
}
2085
- }
2086
- end
2102
+ end
2103
+
2104
+ % RequestBody {
2105
+ description:
2106
+ "Request body for the #{ route . name || route . route } operation on #{ AshJsonApi.Resource.Info . type ( resource ) } resource" ,
2107
+ required: body_required ,
2108
+ content: content
2109
+ }
2110
+ end
2087
2111
2088
- % RequestBody {
2089
- description:
2090
- "Request body for the #{ route . name || route . route } operation on #{ AshJsonApi.Resource.Info . type ( resource ) } resource" ,
2091
- required: body_required ,
2092
- content: content
2093
- }
2094
- end
2095
-
2096
2112
# Return both the body and any generated schemas
2097
2113
{ body , all_schemas }
2098
2114
end
0 commit comments