Skip to content

Commit 3233eff

Browse files
authored
[fix][elixir] faulty free-form object type spec (#21113)
* fix: faulty free-form object type spec * add implicit free-form object example
1 parent 64d9719 commit 3233eff

File tree

4 files changed

+128
-7
lines changed

4 files changed

+128
-7
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,11 @@ public String toOperationId(String operationId) {
570570
*/
571571
@Override
572572
public String getTypeDeclaration(Schema p) {
573-
if (ModelUtils.isArraySchema(p)) {
573+
if (ModelUtils.isAnyType(p)) {
574+
return "any()";
575+
} else if(ModelUtils.isFreeFormObject(p, null)) {
576+
return "%{optional(String.t) => any()}";
577+
} else if (ModelUtils.isArraySchema(p)) {
574578
Schema inner = ModelUtils.getSchemaItems(p);
575579
return "[" + getTypeDeclaration(inner) + "]";
576580
} else if (ModelUtils.isMapSchema(p)) {
@@ -856,6 +860,10 @@ private String normalizeTypeName(String baseType, boolean isPrimitive) {
856860
private void buildTypespec(CodegenParameter param, StringBuilder sb) {
857861
if (param.dataType == null) {
858862
sb.append("nil");
863+
} else if (param.isAnyType) {
864+
sb.append("any()");
865+
} else if(param.isFreeFormObject) {
866+
sb.append("%{optional(String.t) => any()}");
859867
} else if (param.isArray) {
860868
// list(<subtype>)
861869
sb.append("list(");
@@ -875,6 +883,10 @@ private void buildTypespec(CodegenProperty property, StringBuilder sb) {
875883
if (property == null) {
876884
LOGGER.error(
877885
"CodegenProperty cannot be null. Please report the issue to https://github.com/openapitools/openapi-generator with the spec");
886+
} else if (property.isAnyType) {
887+
sb.append("any()");
888+
} else if(property.isFreeFormObject) {
889+
sb.append("%{optional(String.t) => any()}");
878890
} else if (property.isArray) {
879891
sb.append("list(");
880892
buildTypespec(property.items, sb);

modules/openapi-generator/src/test/resources/3_0/elixir/petstore-with-fake-endpoints-models-for-testing.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,40 @@ paths:
10121012
$ref: "#/components/schemas/FreeFormObject"
10131013
description: request body
10141014
required: true
1015+
/fake/implicitFreeFormObject:
1016+
post:
1017+
tags:
1018+
- fake
1019+
summary: test free form object with implicit additionalProperties
1020+
description: ""
1021+
operationId: testImplicitFreeFormObject
1022+
responses:
1023+
"200":
1024+
description: successful operation
1025+
requestBody:
1026+
content:
1027+
application/json:
1028+
schema:
1029+
$ref: "#/components/schemas/ImplicitFreeFormObject"
1030+
description: request body
1031+
required: true
1032+
/fake/anyTypeObject:
1033+
post:
1034+
tags:
1035+
- fake
1036+
summary: test any type object
1037+
description: ""
1038+
operationId: testAnyTypeObject
1039+
responses:
1040+
"200":
1041+
description: successful operation
1042+
requestBody:
1043+
content:
1044+
application/json:
1045+
schema:
1046+
$ref: "#/components/schemas/AnyTypeObject"
1047+
description: request body
1048+
required: true
10151049
/fake/stringMap-reference:
10161050
post:
10171051
tags:
@@ -1859,6 +1893,19 @@ components:
18591893
type: object
18601894
description: A schema consisting only of additional properties
18611895
additionalProperties: true
1896+
ImplicitFreeFormObject:
1897+
type: object
1898+
description: A schema consisting only of additional properties (implicit)
1899+
AnyTypeObject:
1900+
oneOf:
1901+
- type: string
1902+
- type: number
1903+
- type: integer
1904+
- type: boolean
1905+
- type: object
1906+
- type: array
1907+
items: {}
1908+
nullable: true
18621909
MapOfString:
18631910
type: object
18641911
description: A schema consisting only of additional properties of type string

samples/client/petstore/elixir/lib/openapi_petstore/api/fake.ex

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,37 @@ defmodule OpenapiPetstore.Api.Fake do
304304
])
305305
end
306306

307+
@doc """
308+
test any type object
309+
310+
311+
### Parameters
312+
313+
- `connection` (OpenapiPetstore.Connection): Connection to server
314+
- `body` (any()): request body
315+
- `opts` (keyword): Optional parameters
316+
317+
### Returns
318+
319+
- `{:ok, nil}` on success
320+
- `{:error, Tesla.Env.t}` on failure
321+
"""
322+
@spec test_any_type_object(Tesla.Env.client, any(), keyword()) :: {:ok, nil} | {:error, Tesla.Env.t}
323+
def test_any_type_object(connection, body, _opts \\ []) do
324+
request =
325+
%{}
326+
|> method(:post)
327+
|> url("/fake/anyTypeObject")
328+
|> add_param(:body, :body, body)
329+
|> Enum.into([])
330+
331+
connection
332+
|> Connection.request(request)
333+
|> evaluate_response([
334+
{200, false}
335+
])
336+
end
337+
307338
@doc """
308339
For this test, the body has to be a binary file.
309340
@@ -585,6 +616,37 @@ defmodule OpenapiPetstore.Api.Fake do
585616
])
586617
end
587618

619+
@doc """
620+
test free form object with implicit additionalProperties
621+
622+
623+
### Parameters
624+
625+
- `connection` (OpenapiPetstore.Connection): Connection to server
626+
- `body` (%{optional(String.t) => any()}): request body
627+
- `opts` (keyword): Optional parameters
628+
629+
### Returns
630+
631+
- `{:ok, nil}` on success
632+
- `{:error, Tesla.Env.t}` on failure
633+
"""
634+
@spec test_implicit_free_form_object(Tesla.Env.client, %{optional(String.t) => any()}, keyword()) :: {:ok, nil} | {:error, Tesla.Env.t}
635+
def test_implicit_free_form_object(connection, body, _opts \\ []) do
636+
request =
637+
%{}
638+
|> method(:post)
639+
|> url("/fake/implicitFreeFormObject")
640+
|> add_param(:body, :body, body)
641+
|> Enum.into([])
642+
643+
connection
644+
|> Connection.request(request)
645+
|> evaluate_response([
646+
{200, false}
647+
])
648+
end
649+
588650
@doc """
589651
test inline additionalProperties
590652

samples/client/petstore/elixir/lib/openapi_petstore/model/nullable_class.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ defmodule OpenapiPetstore.Model.NullableClass do
2929
:string_prop => String.t | nil,
3030
:date_prop => Date.t | nil,
3131
:datetime_prop => DateTime.t | nil,
32-
:array_nullable_prop => [map()] | nil,
33-
:array_and_items_nullable_prop => [map()] | nil,
34-
:array_items_nullable => [map()] | nil,
35-
:object_nullable_prop => %{optional(String.t) => map()} | nil,
36-
:object_and_items_nullable_prop => %{optional(String.t) => map()} | nil,
37-
:object_items_nullable => %{optional(String.t) => map()} | nil
32+
:array_nullable_prop => [%{optional(String.t) => any()}] | nil,
33+
:array_and_items_nullable_prop => [%{optional(String.t) => any()}] | nil,
34+
:array_items_nullable => [%{optional(String.t) => any()}] | nil,
35+
:object_nullable_prop => %{optional(String.t) => any()} | nil,
36+
:object_and_items_nullable_prop => %{optional(String.t) => any()} | nil,
37+
:object_items_nullable => %{optional(String.t) => any()} | nil
3838
}
3939

4040
alias OpenapiPetstore.Deserializer

0 commit comments

Comments
 (0)