mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-06 02:25:20 +00:00
parent
5b9e7db104
commit
69f37cea0b
@ -10,108 +10,81 @@
|
|||||||
|
|
||||||
-spec get() -> {{packageName}}:object().
|
-spec get() -> {{packageName}}:object().
|
||||||
get() ->
|
get() ->
|
||||||
ct_expand:term(enumerate_components(maps:with([?COMPONENTS], load_raw()))).
|
ct_expand:term(enumerate_components(load_raw())).
|
||||||
|
|
||||||
-spec enumerate_components(Schema :: map()) ->
|
-spec enumerate_components(Schema :: map()) ->
|
||||||
Schema :: map() | no_return().
|
Schema :: map() | no_return().
|
||||||
enumerate_components(Schema = #{?COMPONENTS := Components}) ->
|
enumerate_components(Schema = #{?COMPONENTS := Components}) ->
|
||||||
%@NOTICE only parents within the same component type are supported
|
Schema#{?COMPONENTS => enumerate_discriminator_children(Components)};
|
||||||
Schema#{?COMPONENTS => maps:map(fun enumerate_discriminator_children/2, Components)};
|
|
||||||
enumerate_components(Schema) ->
|
enumerate_components(Schema) ->
|
||||||
Schema.
|
Schema.
|
||||||
|
|
||||||
-spec enumerate_discriminator_children(ComponentType :: binary(), Schema :: map()) ->
|
%% When using the discriminator, inline schemas will not be considered.
|
||||||
|
-spec enumerate_discriminator_children(Schema :: map()) ->
|
||||||
Schema :: map() | no_return().
|
Schema :: map() | no_return().
|
||||||
enumerate_discriminator_children(_ComponentType, Defs) ->
|
enumerate_discriminator_children(#{<<"schemas">> := Defs}) ->
|
||||||
try
|
try
|
||||||
{Parents, _} = maps:fold(
|
maps:fold(fun correct_schema/3, Defs, build_hier(Defs))
|
||||||
fun(Name, Schema, Acc) ->
|
|
||||||
check_definition(Name, Schema, Acc)
|
|
||||||
end,
|
|
||||||
{#{}, #{}},
|
|
||||||
Defs
|
|
||||||
),
|
|
||||||
maps:fold(
|
|
||||||
fun(Parent, Children, Schema) ->
|
|
||||||
correct_schema(Parent, Children, Schema)
|
|
||||||
end,
|
|
||||||
Defs,
|
|
||||||
Parents
|
|
||||||
)
|
|
||||||
catch
|
catch
|
||||||
_:Error ->
|
_:Error ->
|
||||||
handle_error(Error)
|
handle_error(Error)
|
||||||
end.
|
end;
|
||||||
|
enumerate_discriminator_children(Schema) ->
|
||||||
|
Schema.
|
||||||
|
|
||||||
-spec handle_error(_) ->
|
-spec handle_error(_) ->
|
||||||
no_return().
|
no_return().
|
||||||
handle_error(Error) ->
|
handle_error(Error) ->
|
||||||
erlang:error({schema_invalid, Error}).
|
erlang:error({schema_invalid, Error}).
|
||||||
|
|
||||||
check_definition(Name, Schema, Acc) ->
|
build_hier(Defs) ->
|
||||||
Acc1 = check_discriminator(Name, Schema, Acc),
|
F = fun
|
||||||
check_backrefs(Name, Schema, Acc1).
|
(Name, #{<<"discriminator">> := _Type}, Acc) ->
|
||||||
|
insert_parent(Name, Acc);
|
||||||
|
|
||||||
check_discriminator(Name, Schema, {Parents, Candidates}) ->
|
(Name, #{<<"allOf">> := Props}, Acc) ->
|
||||||
case maps:get(<<"discriminator">>, Schema, undefined) of
|
lists:foldl(
|
||||||
undefined ->
|
fun
|
||||||
{Parents, Candidates};
|
(#{<<"$ref">> := <<"#/components/schemas/", Type/binary>>}, Hier) ->
|
||||||
_ ->
|
%% check: whether type itself exists
|
||||||
{
|
%% TODO: Implement according to OAS3:
|
||||||
Parents#{Name => maps:get(Name, Candidates, [])},
|
%% In scenarios where the value of the discriminator field does not match
|
||||||
maps:without([Name], Candidates)
|
%% the schema name or implicit mapping is not possible, an optional mapping
|
||||||
}
|
%% definition MAY be used.
|
||||||
end.
|
Schema = maps:get(Type, Defs),
|
||||||
|
Discriminator = maps:get(<<"discriminator">>, Schema, undefined),
|
||||||
|
insert_child(Discriminator, Type, Name, Hier);
|
||||||
|
|
||||||
check_backrefs(Name, Schema, Acc) ->
|
(_, Hier) ->
|
||||||
case maps:get(<<"allOf">>, Schema, undefined) of
|
Hier
|
||||||
undefined ->
|
end,
|
||||||
Acc;
|
Acc,
|
||||||
AllOf ->
|
Props
|
||||||
lists:foldl(fun(E, A) -> check_allOf(E, Name, A) end, Acc, AllOf)
|
)
|
||||||
end.
|
end,
|
||||||
|
maps:fold(F, #{}, Defs).
|
||||||
|
|
||||||
check_allOf(#{<<"$ref">> := RefPath}, Child, {Parents, Candidates}) ->
|
insert_parent(Parent, Hier) when not is_map_key(Parent, Hier) ->
|
||||||
Parent = get_parent_from_ref(RefPath),
|
Hier#{Parent => []};
|
||||||
case maps:get(Parent, Parents, undefined) of
|
insert_parent(_, Hier) ->
|
||||||
undefined ->
|
Hier.
|
||||||
{Parents, update_candidates(Parent, Child, Candidates)};
|
|
||||||
Children ->
|
|
||||||
{Parents#{Parent => [Child | Children]}, Candidates}
|
|
||||||
end;
|
|
||||||
check_allOf(_, _, Acc) ->
|
|
||||||
Acc.
|
|
||||||
|
|
||||||
get_parent_from_ref(RefPath) ->
|
insert_child(undefined, _Parent, _Child, Hier) ->
|
||||||
Split = binary:split(RefPath, [<<"/">>], [global]),
|
Hier;
|
||||||
lists:last(Split).
|
insert_child(_Discriminator, Parent, Child, Hier) ->
|
||||||
|
maps:put(Parent, [Child | maps:get(Parent, Hier, [])], Hier).
|
||||||
update_candidates(Parent, Child, Candidates) ->
|
|
||||||
case maps:get(Parent, Candidates, undefined) of
|
|
||||||
undefined ->
|
|
||||||
Candidates#{Parent => [Child]};
|
|
||||||
Children ->
|
|
||||||
Candidates#{Parent => [Child | Children]}
|
|
||||||
end.
|
|
||||||
|
|
||||||
correct_schema(Parent, Children, Schema) ->
|
correct_schema(Parent, Children, Schema) ->
|
||||||
BasePath = [Parent],
|
PropertyName = get_sub_schema([Parent, <<"discriminator">>, <<"propertyName">>], Schema),
|
||||||
Discr = maps:get(<<"discriminator">>, get_sub_schema(BasePath, Schema)),
|
update_schema([Parent, <<"properties">>, PropertyName, <<"enum">>], Children, Schema).
|
||||||
PropertyName = maps:get(<<"propertyName">>, Discr),
|
|
||||||
update_schema(Children, [<<"enum">>, PropertyName, <<"properties">> | BasePath], Schema).
|
|
||||||
|
|
||||||
update_schema(Value, [], _Schema) ->
|
update_schema([Key], Value, Schema) ->
|
||||||
Value;
|
Schema#{Key => Value};
|
||||||
update_schema(Value, [Key | Path], Schema) ->
|
update_schema([Key | Path], Value, Schema) ->
|
||||||
SubSchema0 = get_sub_schema(Path, Schema),
|
maps:put(Key, update_schema(Path, Value, maps:get(Key, Schema)), Schema).
|
||||||
SubSchema1 = update_sub_schema(Key, Value, SubSchema0),
|
|
||||||
update_schema(SubSchema1, Path, Schema).
|
|
||||||
|
|
||||||
get_sub_schema(ReversedPath, Schema) ->
|
get_sub_schema(Path, Schema) ->
|
||||||
lists:foldr(fun(K, S) -> maps:get(K, S) end, Schema, ReversedPath).
|
lists:foldl(fun maps:get/2, Schema, Path).
|
||||||
|
|
||||||
update_sub_schema(Key, Value, Schema) ->
|
|
||||||
Schema#{Key => Value}.
|
|
||||||
|
|
||||||
-spec get_raw() -> map().
|
-spec get_raw() -> map().
|
||||||
get_raw() ->
|
get_raw() ->
|
||||||
@ -215,7 +188,7 @@ get_openapi_path() ->
|
|||||||
}}">>).
|
}}">>).
|
||||||
|
|
||||||
get_enum(Parent, Discr, ComponentType, Schema) ->
|
get_enum(Parent, Discr, ComponentType, Schema) ->
|
||||||
lists:sort(get_sub_schema([<<"enum">>, Discr, <<"properties">>, Parent, ComponentType, ?COMPONENTS], Schema)).
|
lists:sort(get_sub_schema([?COMPONENTS, ComponentType, Parent, <<"properties">>, Discr, <<"enum">>], Schema)).
|
||||||
|
|
||||||
-spec test() -> _.
|
-spec test() -> _.
|
||||||
-spec enumerate_discriminator_children_test() -> _.
|
-spec enumerate_discriminator_children_test() -> _.
|
||||||
@ -223,16 +196,16 @@ enumerate_discriminator_children_test() ->
|
|||||||
Schema = jsx:decode(?SCHEMA, [return_maps]),
|
Schema = jsx:decode(?SCHEMA, [return_maps]),
|
||||||
FixedSchema = enumerate_components(Schema),
|
FixedSchema = enumerate_components(Schema),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
lists:sort([<<"Dog">>, <<"Cat">>, <<"WildMix">>]),
|
[<<"Cat">>, <<"Dog">>, <<"WildMix">>],
|
||||||
get_enum(<<"Pet">>, <<"petType">>, <<"schemas">>, FixedSchema)
|
get_enum(<<"Pet">>, <<"petType">>, <<"schemas">>, FixedSchema)
|
||||||
),
|
),
|
||||||
?assertEqual([<<"WildMix">>], get_enum(<<"Person">>, <<"personType">>, <<"schemas">>, FixedSchema)),
|
?assertEqual([<<"WildMix">>], get_enum(<<"Person">>, <<"personType">>, <<"schemas">>, FixedSchema)),
|
||||||
?assertEqual([], get_enum(<<"Dummy">>, <<"dummyType">>, <<"schemas">>, FixedSchema)).
|
?assertEqual([], get_enum(<<"Dummy">>, <<"dummyType">>, <<"schemas">>, FixedSchema)).
|
||||||
|
|
||||||
-spec get_test() -> _.
|
-spec get_test() -> _.
|
||||||
get_test() ->
|
get_test() ->
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
enumerate_components(maps:with([?COMPONENTS], get_raw())),
|
enumerate_components(get_raw()),
|
||||||
?MODULE:get()
|
?MODULE:get()
|
||||||
).
|
).
|
||||||
-endif.
|
-endif.
|
||||||
|
Loading…
Reference in New Issue
Block a user