[fix][elixir] faulty free-form object type spec (#21113)

* fix: faulty free-form object type spec

* add implicit free-form object example
This commit is contained in:
Enrique Fernández 2025-04-23 08:17:10 +02:00 committed by GitHub
parent 64d9719d39
commit 3233eff187
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 128 additions and 7 deletions

View File

@ -570,7 +570,11 @@ public class ElixirClientCodegen extends DefaultCodegen {
*/
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
if (ModelUtils.isAnyType(p)) {
return "any()";
} else if(ModelUtils.isFreeFormObject(p, null)) {
return "%{optional(String.t) => any()}";
} else if (ModelUtils.isArraySchema(p)) {
Schema inner = ModelUtils.getSchemaItems(p);
return "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
@ -856,6 +860,10 @@ public class ElixirClientCodegen extends DefaultCodegen {
private void buildTypespec(CodegenParameter param, StringBuilder sb) {
if (param.dataType == null) {
sb.append("nil");
} else if (param.isAnyType) {
sb.append("any()");
} else if(param.isFreeFormObject) {
sb.append("%{optional(String.t) => any()}");
} else if (param.isArray) {
// list(<subtype>)
sb.append("list(");
@ -875,6 +883,10 @@ public class ElixirClientCodegen extends DefaultCodegen {
if (property == null) {
LOGGER.error(
"CodegenProperty cannot be null. Please report the issue to https://github.com/openapitools/openapi-generator with the spec");
} else if (property.isAnyType) {
sb.append("any()");
} else if(property.isFreeFormObject) {
sb.append("%{optional(String.t) => any()}");
} else if (property.isArray) {
sb.append("list(");
buildTypespec(property.items, sb);

View File

@ -1012,6 +1012,40 @@ paths:
$ref: "#/components/schemas/FreeFormObject"
description: request body
required: true
/fake/implicitFreeFormObject:
post:
tags:
- fake
summary: test free form object with implicit additionalProperties
description: ""
operationId: testImplicitFreeFormObject
responses:
"200":
description: successful operation
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ImplicitFreeFormObject"
description: request body
required: true
/fake/anyTypeObject:
post:
tags:
- fake
summary: test any type object
description: ""
operationId: testAnyTypeObject
responses:
"200":
description: successful operation
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/AnyTypeObject"
description: request body
required: true
/fake/stringMap-reference:
post:
tags:
@ -1859,6 +1893,19 @@ components:
type: object
description: A schema consisting only of additional properties
additionalProperties: true
ImplicitFreeFormObject:
type: object
description: A schema consisting only of additional properties (implicit)
AnyTypeObject:
oneOf:
- type: string
- type: number
- type: integer
- type: boolean
- type: object
- type: array
items: {}
nullable: true
MapOfString:
type: object
description: A schema consisting only of additional properties of type string

View File

@ -304,6 +304,37 @@ defmodule OpenapiPetstore.Api.Fake do
])
end
@doc """
test any type object
### Parameters
- `connection` (OpenapiPetstore.Connection): Connection to server
- `body` (any()): request body
- `opts` (keyword): Optional parameters
### Returns
- `{:ok, nil}` on success
- `{:error, Tesla.Env.t}` on failure
"""
@spec test_any_type_object(Tesla.Env.client, any(), keyword()) :: {:ok, nil} | {:error, Tesla.Env.t}
def test_any_type_object(connection, body, _opts \\ []) do
request =
%{}
|> method(:post)
|> url("/fake/anyTypeObject")
|> add_param(:body, :body, body)
|> Enum.into([])
connection
|> Connection.request(request)
|> evaluate_response([
{200, false}
])
end
@doc """
For this test, the body has to be a binary file.
@ -585,6 +616,37 @@ defmodule OpenapiPetstore.Api.Fake do
])
end
@doc """
test free form object with implicit additionalProperties
### Parameters
- `connection` (OpenapiPetstore.Connection): Connection to server
- `body` (%{optional(String.t) => any()}): request body
- `opts` (keyword): Optional parameters
### Returns
- `{:ok, nil}` on success
- `{:error, Tesla.Env.t}` on failure
"""
@spec test_implicit_free_form_object(Tesla.Env.client, %{optional(String.t) => any()}, keyword()) :: {:ok, nil} | {:error, Tesla.Env.t}
def test_implicit_free_form_object(connection, body, _opts \\ []) do
request =
%{}
|> method(:post)
|> url("/fake/implicitFreeFormObject")
|> add_param(:body, :body, body)
|> Enum.into([])
connection
|> Connection.request(request)
|> evaluate_response([
{200, false}
])
end
@doc """
test inline additionalProperties

View File

@ -29,12 +29,12 @@ defmodule OpenapiPetstore.Model.NullableClass do
:string_prop => String.t | nil,
:date_prop => Date.t | nil,
:datetime_prop => DateTime.t | nil,
:array_nullable_prop => [map()] | nil,
:array_and_items_nullable_prop => [map()] | nil,
:array_items_nullable => [map()] | nil,
:object_nullable_prop => %{optional(String.t) => map()} | nil,
:object_and_items_nullable_prop => %{optional(String.t) => map()} | nil,
:object_items_nullable => %{optional(String.t) => map()} | nil
:array_nullable_prop => [%{optional(String.t) => any()}] | nil,
:array_and_items_nullable_prop => [%{optional(String.t) => any()}] | nil,
:array_items_nullable => [%{optional(String.t) => any()}] | nil,
:object_nullable_prop => %{optional(String.t) => any()} | nil,
:object_and_items_nullable_prop => %{optional(String.t) => any()} | nil,
:object_items_nullable => %{optional(String.t) => any()} | nil
}
alias OpenapiPetstore.Deserializer