-module(oaisp@internal@merge).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaisp/internal/merge.gleam").
-export([to_string/3, unresolved_refs/2, malformed_formats/2, duplicate_routes/1, path_param_mismatches/1]).
-export_type([resolved_component/0, path_param_mismatch/0, oas/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type resolved_component() :: {resolved_component,
binary(),
oaisp@internal@package_interface:resolved_type()}.
-type path_param_mismatch() :: {param_without_placeholder,
binary(),
binary(),
binary()} |
{placeholder_without_param, binary(), binary(), binary()}.
-type oas() :: o_string |
o_integer |
o_number |
o_boolean |
o_null |
{o_array, oas()} |
{o_tuple, list(oas())} |
{o_map, oas()} |
{o_object,
list({binary(), oas()}),
list(binary()),
gleam@option:option(binary())} |
{o_enum, list(binary()), gleam@option:option(binary())} |
{o_ref, binary()} |
{o_nullable, oas()} |
{o_any, gleam@option:option(binary())} |
{o_string_format, binary()}.
-file("src/oaisp/internal/merge.gleam", 334).
?DOC(false).
-spec ref_key(binary(), binary()) -> binary().
ref_key(Module, Name) ->
<<<<Module/binary, "#"/utf8>>/binary, Name/binary>>.
-file("src/oaisp/internal/merge.gleam", 649).
?DOC(false).
-spec ref_or_any(binary(), binary(), gleam@dict:dict(binary(), binary())) -> oas().
ref_or_any(Module, Name, Component_refs) ->
case gleam_stdlib:map_get(Component_refs, ref_key(Module, Name)) of
{ok, Component_name} ->
{o_ref, Component_name};
{error, nil} ->
{o_any, none}
end.
-file("src/oaisp/internal/merge.gleam", 602).
?DOC(false).
-spec field_oas(
oaisp@internal@package_interface:field_type(),
gleam@dict:dict(binary(), binary())
) -> oas().
field_oas(Field_type, Component_refs) ->
case Field_type of
string_type ->
o_string;
int_type ->
o_integer;
float_type ->
o_number;
bool_type ->
o_boolean;
nil_type ->
o_null;
{list_type, Element} ->
{o_array, field_oas(Element, Component_refs)};
{option_type, Inner} ->
{o_nullable, field_oas(Inner, Component_refs)};
{dict_type, Value} ->
{o_map, field_oas(Value, Component_refs)};
{tuple_type, Elements} ->
{o_tuple,
gleam@list:map(
Elements,
fun(_capture) -> field_oas(_capture, Component_refs) end
)};
{formatted_string_type, Format} ->
{o_string_format, Format};
timestamp_type ->
{o_string_format, <<"date-time"/utf8>>};
{ref_type, Module, Name} ->
ref_or_any(Module, Name, Component_refs);
any_type ->
{o_any, none}
end.
-file("src/oaisp/internal/merge.gleam", 577).
?DOC(false).
-spec resolved_oas(
oaisp@internal@package_interface:resolved_type(),
gleam@dict:dict(binary(), binary())
) -> oas().
resolved_oas(Resolved, Component_refs) ->
case Resolved of
{record_type, Fields, Documentation} ->
Properties = gleam@list:map(
Fields,
fun(Field) ->
{erlang:element(2, Field),
field_oas(erlang:element(3, Field), Component_refs)}
end
),
Required = gleam@list:filter_map(
Fields,
fun(Field@1) -> case erlang:element(3, Field@1) of
{option_type, _} ->
{error, nil};
_ ->
{ok, erlang:element(2, Field@1)}
end end
),
{o_object, Properties, Required, Documentation};
{enum_type, Variants, Documentation@1} ->
{o_enum, Variants, Documentation@1};
{unmodelled, Documentation@2} ->
{o_any, Documentation@2}
end.
-file("src/oaisp/internal/merge.gleam", 701).
?DOC(false).
-spec string_format_schema(binary()) -> gleam@json:json().
string_format_schema(Format) ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"string"/utf8>>)},
{<<"format"/utf8>>, gleam@json:string(Format)}]
).
-file("src/oaisp/internal/merge.gleam", 708).
?DOC(false).
-spec typed(binary()) -> gleam@json:json().
typed(Name) ->
gleam@json:object([{<<"type"/utf8>>, gleam@json:string(Name)}]).
-file("src/oaisp/internal/merge.gleam", 778).
?DOC(false).
-spec type_array(list(binary())) -> gleam@json:json().
type_array(Types) ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:array(Types, fun gleam@json:string/1)}]
).
-file("src/oaisp/internal/merge.gleam", 782).
?DOC(false).
-spec optional(binary(), gleam@option:option(binary())) -> list({binary(),
gleam@json:json()}).
optional(Key, Value) ->
case Value of
none ->
[];
{some, Text} ->
[{Key, gleam@json:string(Text)}]
end.
-file("src/oaisp/internal/merge.gleam", 743).
?DOC(false).
-spec enum_to_json(list(binary()), gleam@option:option(binary())) -> gleam@json:json().
enum_to_json(Values, Description) ->
gleam@json:object(
lists:append(
[optional(<<"description"/utf8>>, Description),
[{<<"type"/utf8>>, gleam@json:string(<<"string"/utf8>>)},
{<<"enum"/utf8>>,
gleam@json:array(Values, fun gleam@json:string/1)}]]
)
).
-file("src/oaisp/internal/merge.gleam", 712).
?DOC(false).
-spec number_schema() -> gleam@json:json().
number_schema() ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"number"/utf8>>)},
{<<"format"/utf8>>, gleam@json:string(<<"double"/utf8>>)}]
).
-file("src/oaisp/internal/merge.gleam", 755).
?DOC(false).
-spec nullable_to_json(oas()) -> gleam@json:json().
nullable_to_json(Inner) ->
case Inner of
o_string ->
type_array([<<"string"/utf8>>, <<"null"/utf8>>]);
o_integer ->
type_array([<<"integer"/utf8>>, <<"null"/utf8>>]);
o_number ->
gleam@json:object(
[{<<"type"/utf8>>,
gleam@json:array(
[<<"number"/utf8>>, <<"null"/utf8>>],
fun gleam@json:string/1
)},
{<<"format"/utf8>>, gleam@json:string(<<"double"/utf8>>)}]
);
o_boolean ->
type_array([<<"boolean"/utf8>>, <<"null"/utf8>>]);
o_null ->
typed(<<"null"/utf8>>);
{o_string_format, Format} ->
gleam@json:object(
[{<<"type"/utf8>>,
gleam@json:array(
[<<"string"/utf8>>, <<"null"/utf8>>],
fun gleam@json:string/1
)},
{<<"format"/utf8>>, gleam@json:string(Format)}]
);
Other ->
gleam@json:object(
[{<<"anyOf"/utf8>>,
gleam@json:preprocessed_array(
[oas_to_json(Other), typed(<<"null"/utf8>>)]
)}]
)
end.
-file("src/oaisp/internal/merge.gleam", 719).
?DOC(false).
-spec object_to_json(
list({binary(), oas()}),
list(binary()),
gleam@option:option(binary())
) -> gleam@json:json().
object_to_json(Properties, Required, Description) ->
Required_part = case Required of
[] ->
[];
Names ->
[{<<"required"/utf8>>,
gleam@json:array(Names, fun gleam@json:string/1)}]
end,
gleam@json:object(
lists:append(
[optional(<<"description"/utf8>>, Description),
[{<<"type"/utf8>>, gleam@json:string(<<"object"/utf8>>)},
{<<"properties"/utf8>>,
gleam@json:object(
gleam@list:map(
Properties,
fun(P) ->
{erlang:element(1, P),
oas_to_json(erlang:element(2, P))}
end
)
)}],
Required_part]
)
).
-file("src/oaisp/internal/merge.gleam", 660).
?DOC(false).
-spec oas_to_json(oas()) -> gleam@json:json().
oas_to_json(Oas) ->
case Oas of
o_string ->
typed(<<"string"/utf8>>);
o_integer ->
typed(<<"integer"/utf8>>);
o_number ->
number_schema();
o_boolean ->
typed(<<"boolean"/utf8>>);
o_null ->
typed(<<"null"/utf8>>);
{o_array, Items} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"array"/utf8>>)},
{<<"items"/utf8>>, oas_to_json(Items)}]
);
{o_tuple, Elements} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"array"/utf8>>)},
{<<"prefixItems"/utf8>>,
gleam@json:array(Elements, fun oas_to_json/1)}]
);
{o_map, Value} ->
gleam@json:object(
[{<<"type"/utf8>>, gleam@json:string(<<"object"/utf8>>)},
{<<"additionalProperties"/utf8>>, oas_to_json(Value)}]
);
{o_object, Properties, Required, Description} ->
object_to_json(Properties, Required, Description);
{o_enum, Values, Description@1} ->
enum_to_json(Values, Description@1);
{o_ref, Name} ->
gleam@json:object(
[{<<"$ref"/utf8>>,
gleam@json:string(
<<"#/components/schemas/"/utf8, Name/binary>>
)}]
);
{o_nullable, Inner} ->
nullable_to_json(Inner);
{o_any, Description@2} ->
case Description@2 of
none ->
gleam@json:object([]);
{some, Text} ->
gleam@json:object(
[{<<"description"/utf8>>, gleam@json:string(Text)}]
)
end;
{o_string_format, Format} ->
string_format_schema(Format)
end.
-file("src/oaisp/internal/merge.gleam", 338).
?DOC(false).
-spec components_object(
gleam@dict:dict(binary(), resolved_component()),
gleam@dict:dict(binary(), binary())
) -> gleam@json:json().
components_object(Components, Component_refs) ->
_pipe = Components,
_pipe@1 = maps:to_list(_pipe),
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Entry) ->
Component_name@1 = case gleam_stdlib:map_get(
Component_refs,
erlang:element(1, Entry)
) of
{ok, Component_name} -> Component_name;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"component_refs are derived from the same component map"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"oaisp/internal/merge"/utf8>>,
function => <<"components_object"/utf8>>,
line => 345,
value => _assert_fail,
start => 9708,
'end' => 9773,
pattern_start => 9719,
pattern_end => 9737})
end,
{Component_name@1,
oas_to_json(
resolved_oas(
erlang:element(3, erlang:element(2, Entry)),
Component_refs
)
)}
end
),
_pipe@3 = gleam@list:sort(
_pipe@2,
fun(A, B) ->
gleam@string:compare(erlang:element(1, A), erlang:element(1, B))
end
),
gleam@json:object(_pipe@3).
-file("src/oaisp/internal/merge.gleam", 640).
?DOC(false).
-spec scalar_oas(oaisp@schema:scalar_kind()) -> oas().
scalar_oas(Kind) ->
case Kind of
string_kind ->
o_string;
int_kind ->
o_integer;
bool_kind ->
o_boolean;
float_kind ->
o_number
end.
-file("src/oaisp/internal/merge.gleam", 621).
?DOC(false).
-spec schema_oas(oaisp@schema:schema(), gleam@dict:dict(binary(), binary())) -> oas().
schema_oas(Schema, Component_refs) ->
case Schema of
{type_ref, Module, Name} ->
ref_or_any(Module, Name, Component_refs);
{scalar, Kind, _} ->
scalar_oas(Kind)
end.
-file("src/oaisp/internal/merge.gleam", 282).
?DOC(false).
-spec content(oas()) -> gleam@json:json().
content(Schema) ->
gleam@json:object(
[{<<"application/json"/utf8>>,
gleam@json:object([{<<"schema"/utf8>>, oas_to_json(Schema)}])}]
).
-file("src/oaisp/internal/merge.gleam", 789).
?DOC(false).
-spec status_reason(integer()) -> binary().
status_reason(Status) ->
case Status of
200 ->
<<"OK"/utf8>>;
201 ->
<<"Created"/utf8>>;
202 ->
<<"Accepted"/utf8>>;
204 ->
<<"No Content"/utf8>>;
301 ->
<<"Moved Permanently"/utf8>>;
400 ->
<<"Bad Request"/utf8>>;
401 ->
<<"Unauthorized"/utf8>>;
403 ->
<<"Forbidden"/utf8>>;
404 ->
<<"Not Found"/utf8>>;
409 ->
<<"Conflict"/utf8>>;
422 ->
<<"Unprocessable Entity"/utf8>>;
429 ->
<<"Too Many Requests"/utf8>>;
500 ->
<<"Internal Server Error"/utf8>>;
_ ->
<<"Response"/utf8>>
end.
-file("src/oaisp/internal/merge.gleam", 262).
?DOC(false).
-spec response_object(
oaisp@endpoint:response(),
gleam@dict:dict(binary(), binary())
) -> gleam@json:json().
response_object(Response, Component_refs) ->
Description = gleam@option:unwrap(
erlang:element(4, Response),
status_reason(erlang:element(2, Response))
),
Base = [{<<"description"/utf8>>, gleam@json:string(Description)}],
case erlang:element(3, Response) of
none ->
gleam@json:object(Base);
{some, Schema} ->
gleam@json:object(
lists:append(
Base,
[{<<"content"/utf8>>,
content(schema_oas(Schema, Component_refs))}]
)
)
end.
-file("src/oaisp/internal/merge.gleam", 251).
?DOC(false).
-spec responses_object(
list(oaisp@endpoint:response()),
gleam@dict:dict(binary(), binary())
) -> gleam@json:json().
responses_object(Responses, Component_refs) ->
_pipe = Responses,
_pipe@1 = gleam@list:map(
_pipe,
fun(Response) ->
{erlang:integer_to_binary(erlang:element(2, Response)),
response_object(Response, Component_refs)}
end
),
gleam@json:object(_pipe@1).
-file("src/oaisp/internal/merge.gleam", 244).
?DOC(false).
-spec request_body_object(
oaisp@schema:schema(),
gleam@dict:dict(binary(), binary())
) -> gleam@json:json().
request_body_object(Schema, Component_refs) ->
gleam@json:object(
[{<<"required"/utf8>>, gleam@json:bool(true)},
{<<"content"/utf8>>, content(schema_oas(Schema, Component_refs))}]
).
-file("src/oaisp/internal/merge.gleam", 235).
?DOC(false).
-spec query_parameter_json(binary(), oas(), boolean()) -> gleam@json:json().
query_parameter_json(Name, Oas, Required) ->
gleam@json:object(
[{<<"name"/utf8>>, gleam@json:string(Name)},
{<<"in"/utf8>>, gleam@json:string(<<"query"/utf8>>)},
{<<"required"/utf8>>, gleam@json:bool(Required)},
{<<"schema"/utf8>>, oas_to_json(Oas)}]
).
-file("src/oaisp/internal/merge.gleam", 222).
?DOC(false).
-spec query_scalar_oas(oaisp@internal@package_interface:field_type()) -> {ok,
oas()} |
{error, nil}.
query_scalar_oas(Field_type) ->
case Field_type of
string_type ->
{ok, o_string};
int_type ->
{ok, o_integer};
float_type ->
{ok, o_number};
bool_type ->
{ok, o_boolean};
{list_type, Element} ->
_pipe = query_scalar_oas(Element),
gleam@result:map(_pipe, fun(Field@0) -> {o_array, Field@0} end);
{formatted_string_type, Format} ->
{ok, {o_string_format, Format}};
timestamp_type ->
{ok, {o_string_format, <<"date-time"/utf8>>}};
_ ->
{error, nil}
end.
-file("src/oaisp/internal/merge.gleam", 211).
?DOC(false).
-spec reflected_query_param(oaisp@internal@package_interface:field()) -> {ok,
gleam@json:json()} |
{error, nil}.
reflected_query_param(Field) ->
{Base, Required} = case erlang:element(3, Field) of
{option_type, Inner} ->
{Inner, false};
Other ->
{Other, true}
end,
_pipe = query_scalar_oas(Base),
gleam@result:map(
_pipe,
fun(_capture) ->
query_parameter_json(erlang:element(2, Field), _capture, Required)
end
).
-file("src/oaisp/internal/merge.gleam", 196).
?DOC(false).
-spec reflected_query_params(
gleam@option:option(oaisp@schema:schema()),
gleam@package_interface:package()
) -> list(gleam@json:json()).
reflected_query_params(Query_record, Package) ->
case Query_record of
{some, {type_ref, Module, Name}} ->
case oaisp@internal@package_interface:resolve_type(
Package,
Module,
Name
) of
{ok, {record_type, Fields, _}} ->
gleam@list:filter_map(Fields, fun reflected_query_param/1);
_ ->
[]
end;
_ ->
[]
end.
-file("src/oaisp/internal/merge.gleam", 630).
?DOC(false).
-spec param_schema(oaisp@schema:schema(), gleam@dict:dict(binary(), binary())) -> {oas(),
gleam@option:option(binary())}.
param_schema(Schema, Component_refs) ->
case Schema of
{scalar, Kind, Description} ->
{scalar_oas(Kind), Description};
{type_ref, Module, Name} ->
{ref_or_any(Module, Name, Component_refs), none}
end.
-file("src/oaisp/internal/merge.gleam", 173).
?DOC(false).
-spec parameter(
oaisp@endpoint:param(),
binary(),
gleam@dict:dict(binary(), binary())
) -> gleam@json:json().
parameter(Param, Location, Component_refs) ->
{Schema, Description} = param_schema(
erlang:element(3, Param),
Component_refs
),
gleam@json:object(
lists:append(
[[{<<"name"/utf8>>, gleam@json:string(erlang:element(2, Param))},
{<<"in"/utf8>>, gleam@json:string(Location)}],
optional(<<"description"/utf8>>, Description),
[{<<"required"/utf8>>,
gleam@json:bool(erlang:element(4, Param))},
{<<"schema"/utf8>>, oas_to_json(Schema)}]]
)
).
-file("src/oaisp/internal/merge.gleam", 134).
?DOC(false).
-spec operation(
oaisp@endpoint:endpoint(),
gleam@dict:dict(binary(), binary()),
gleam@package_interface:package()
) -> gleam@json:json().
operation(E, Component_refs, Package) ->
Tags@1 = case oaisp@endpoint:tags(E) of
[] ->
[];
Tags ->
[{<<"tags"/utf8>>, gleam@json:array(Tags, fun gleam@json:string/1)}]
end,
Parameters = lists:append(
[gleam@list:map(
oaisp@endpoint:path_params(E),
fun(_capture) ->
parameter(_capture, <<"path"/utf8>>, Component_refs)
end
),
gleam@list:map(
oaisp@endpoint:query_params(E),
fun(_capture@1) ->
parameter(_capture@1, <<"query"/utf8>>, Component_refs)
end
),
reflected_query_params(oaisp@endpoint:query_record(E), Package)]
),
Parameters_part = case Parameters of
[] ->
[];
Ps ->
[{<<"parameters"/utf8>>, gleam@json:preprocessed_array(Ps)}]
end,
Request_body = case oaisp@endpoint:body(E) of
none ->
[];
{some, Schema} ->
[{<<"requestBody"/utf8>>,
request_body_object(Schema, Component_refs)}]
end,
gleam@json:object(
lists:append(
[Tags@1,
optional(<<"summary"/utf8>>, oaisp@endpoint:summary(E)),
optional(<<"description"/utf8>>, oaisp@endpoint:description(E)),
optional(<<"operationId"/utf8>>, oaisp@endpoint:operation_id(E)),
Parameters_part,
Request_body,
[{<<"responses"/utf8>>,
responses_object(
oaisp@endpoint:responses(E),
Component_refs
)}]]
)
).
-file("src/oaisp/internal/merge.gleam", 119).
?DOC(false).
-spec path_item(
list(oaisp@endpoint:endpoint()),
gleam@dict:dict(binary(), binary()),
gleam@package_interface:package()
) -> gleam@json:json().
path_item(Endpoints, Component_refs, Package) ->
_pipe = Endpoints,
_pipe@1 = gleam@list:map(
_pipe,
fun(E) ->
{oaisp@endpoint:method_to_string(oaisp@endpoint:method(E)),
operation(E, Component_refs, Package)}
end
),
gleam@json:object(_pipe@1).
-file("src/oaisp/internal/merge.gleam", 115).
?DOC(false).
-spec ordered_paths(list(oaisp@endpoint:endpoint())) -> list(binary()).
ordered_paths(Endpoints) ->
_pipe = Endpoints,
_pipe@1 = gleam@list:map(_pipe, fun oaisp@endpoint:path/1),
gleam@list:unique(_pipe@1).
-file("src/oaisp/internal/merge.gleam", 102).
?DOC(false).
-spec paths_object(
list(oaisp@endpoint:endpoint()),
gleam@dict:dict(binary(), binary()),
gleam@package_interface:package()
) -> gleam@json:json().
paths_object(Endpoints, Component_refs, Package) ->
_pipe = ordered_paths(Endpoints),
_pipe@1 = gleam@list:map(
_pipe,
fun(Path) ->
For_path = gleam@list:filter(
Endpoints,
fun(E) -> oaisp@endpoint:path(E) =:= Path end
),
{Path, path_item(For_path, Component_refs, Package)}
end
),
gleam@json:object(_pipe@1).
-file("src/oaisp/internal/merge.gleam", 84).
?DOC(false).
-spec server_object(binary()) -> gleam@json:json().
server_object(Url) ->
gleam@json:object([{<<"url"/utf8>>, gleam@json:string(Url)}]).
-file("src/oaisp/internal/merge.gleam", 88).
?DOC(false).
-spec info_object(oaisp@info:info()) -> gleam@json:json().
info_object(Info) ->
gleam@json:object(
lists:append(
[[{<<"title"/utf8>>, gleam@json:string(erlang:element(2, Info))},
{<<"version"/utf8>>,
gleam@json:string(erlang:element(3, Info))}],
optional(<<"description"/utf8>>, erlang:element(4, Info))]
)
).
-file("src/oaisp/internal/merge.gleam", 324).
?DOC(false).
-spec namespaced_component_name(binary()) -> binary().
namespaced_component_name(Key) ->
case gleam@string:split_once(Key, <<"#"/utf8>>) of
{ok, {Module, Name}} ->
Module_name = begin
_pipe = gleam@string:split(Module, <<"/"/utf8>>),
gleam@string:join(_pipe, <<"."/utf8>>)
end,
<<<<Module_name/binary, "."/utf8>>/binary, Name/binary>>;
{error, nil} ->
Key
end.
-file("src/oaisp/internal/merge.gleam", 312).
?DOC(false).
-spec has_duplicate_type_name(
binary(),
gleam@dict:dict(binary(), resolved_component())
) -> boolean().
has_duplicate_type_name(Type_name, Components) ->
Matches = begin
_pipe = Components,
_pipe@1 = maps:to_list(_pipe),
_pipe@2 = gleam@list:filter(
_pipe@1,
fun(Entry) ->
erlang:element(2, erlang:element(2, Entry)) =:= Type_name
end
),
erlang:length(_pipe@2)
end,
Matches > 1.
-file("src/oaisp/internal/merge.gleam", 301).
?DOC(false).
-spec component_name(
binary(),
resolved_component(),
gleam@dict:dict(binary(), resolved_component())
) -> binary().
component_name(Key, Component, Components) ->
case has_duplicate_type_name(erlang:element(2, Component), Components) of
false ->
erlang:element(2, Component);
true ->
namespaced_component_name(Key)
end.
-file("src/oaisp/internal/merge.gleam", 290).
?DOC(false).
-spec component_index(gleam@dict:dict(binary(), resolved_component())) -> gleam@dict:dict(binary(), binary()).
component_index(Components) ->
_pipe = Components,
_pipe@1 = maps:to_list(_pipe),
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Entry) ->
{erlang:element(1, Entry),
component_name(
erlang:element(1, Entry),
erlang:element(2, Entry),
Components
)}
end
),
maps:from_list(_pipe@2).
-file("src/oaisp/internal/merge.gleam", 421).
?DOC(false).
-spec seed_refs(list(oaisp@endpoint:endpoint())) -> list({binary(), binary()}).
seed_refs(Endpoints) ->
gleam@list:flat_map(Endpoints, fun oaisp@endpoint:type_refs/1).
-file("src/oaisp/internal/merge.gleam", 408).
?DOC(false).
-spec field_type_refs(oaisp@internal@package_interface:field_type()) -> list({binary(),
binary()}).
field_type_refs(Field_type) ->
case Field_type of
{ref_type, Module, Name} ->
[{Module, Name}];
{list_type, Element} ->
field_type_refs(Element);
{option_type, Inner} ->
field_type_refs(Inner);
{dict_type, Value} ->
field_type_refs(Value);
{tuple_type, Elements} ->
gleam@list:flat_map(Elements, fun field_type_refs/1);
_ ->
[]
end.
-file("src/oaisp/internal/merge.gleam", 400).
?DOC(false).
-spec child_refs(oaisp@internal@package_interface:resolved_type()) -> list({binary(),
binary()}).
child_refs(Resolved) ->
case Resolved of
{record_type, Fields, _} ->
gleam@list:flat_map(
Fields,
fun(Field) -> field_type_refs(erlang:element(3, Field)) end
);
_ ->
[]
end.
-file("src/oaisp/internal/merge.gleam", 364).
?DOC(false).
-spec do_closure(
gleam@package_interface:package(),
list({binary(), binary()}),
gleam@set:set(binary()),
gleam@dict:dict(binary(), resolved_component())
) -> gleam@dict:dict(binary(), resolved_component()).
do_closure(Package, Worklist, Visited, Acc) ->
case Worklist of
[] ->
Acc;
[{Module, Name} | Rest] ->
Key = ref_key(Module, Name),
case gleam@set:contains(Visited, Key) of
true ->
do_closure(Package, Rest, Visited, Acc);
false ->
Visited@1 = gleam@set:insert(Visited, Key),
case oaisp@internal@package_interface:resolve_type(
Package,
Module,
Name
) of
{error, _} ->
do_closure(Package, Rest, Visited@1, Acc);
{ok, Resolved} ->
do_closure(
Package,
lists:append(child_refs(Resolved), Rest),
Visited@1,
gleam@dict:insert(
Acc,
Key,
{resolved_component, Name, Resolved}
)
)
end
end
end.
-file("src/oaisp/internal/merge.gleam", 357).
?DOC(false).
-spec resolve_closure(
gleam@package_interface:package(),
list({binary(), binary()})
) -> gleam@dict:dict(binary(), resolved_component()).
resolve_closure(Package, Seeds) ->
do_closure(Package, Seeds, gleam@set:new(), maps:new()).
-file("src/oaisp/internal/merge.gleam", 43).
?DOC(false).
-spec to_openapi(
list(oaisp@endpoint:endpoint()),
oaisp@info:info(),
gleam@package_interface:package()
) -> gleam@json:json().
to_openapi(Endpoints, Info, Package) ->
Components = resolve_closure(Package, seed_refs(Endpoints)),
Component_refs = component_index(Components),
Head = [{<<"openapi"/utf8>>, gleam@json:string(<<"3.1.0"/utf8>>)},
{<<"info"/utf8>>, info_object(Info)}],
Servers = case erlang:element(5, Info) of
[] ->
[];
Urls ->
[{<<"servers"/utf8>>, gleam@json:array(Urls, fun server_object/1)}]
end,
Paths = [{<<"paths"/utf8>>,
paths_object(Endpoints, Component_refs, Package)}],
Components_part = case gleam@dict:is_empty(Components) of
true ->
[];
false ->
[{<<"components"/utf8>>,
gleam@json:object(
[{<<"schemas"/utf8>>,
components_object(Components, Component_refs)}]
)}]
end,
gleam@json:object(lists:append([Head, Servers, Paths, Components_part])).
-file("src/oaisp/internal/merge.gleam", 76).
?DOC(false).
-spec to_string(
list(oaisp@endpoint:endpoint()),
oaisp@info:info(),
gleam@package_interface:package()
) -> binary().
to_string(Endpoints, Info, Package) ->
gleam@json:to_string(to_openapi(Endpoints, Info, Package)).
-file("src/oaisp/internal/merge.gleam", 478).
?DOC(false).
-spec query_record_refs(list(oaisp@endpoint:endpoint())) -> list({binary(),
binary()}).
query_record_refs(Endpoints) ->
_pipe = Endpoints,
_pipe@1 = gleam@list:map(_pipe, fun oaisp@endpoint:query_record/1),
_pipe@2 = gleam@option:values(_pipe@1),
gleam@list:filter_map(_pipe@2, fun oaisp@schema:type_ref_parts/1).
-file("src/oaisp/internal/merge.gleam", 442).
?DOC(false).
-spec refs_to_validate(list(oaisp@endpoint:endpoint())) -> list({binary(),
binary()}).
refs_to_validate(Endpoints) ->
lists:append(seed_refs(Endpoints), query_record_refs(Endpoints)).
-file("src/oaisp/internal/merge.gleam", 429).
?DOC(false).
-spec unresolved_refs(
list(oaisp@endpoint:endpoint()),
gleam@package_interface:package()
) -> list({binary(), binary()}).
unresolved_refs(Endpoints, Package) ->
_pipe = refs_to_validate(Endpoints),
_pipe@1 = gleam@list:unique(_pipe),
gleam@list:filter(
_pipe@1,
fun(Ref) ->
{Module, Name} = Ref,
oaisp@internal@package_interface:knows_module(Package, Module)
andalso gleam@result:is_error(
oaisp@internal@package_interface:resolve_type(
Package,
Module,
Name
)
)
end
).
-file("src/oaisp/internal/merge.gleam", 468).
?DOC(false).
-spec reached_refs(
list(oaisp@endpoint:endpoint()),
gleam@package_interface:package()
) -> list({binary(), binary()}).
reached_refs(Endpoints, Package) ->
_pipe = resolve_closure(Package, seed_refs(Endpoints)),
_pipe@1 = maps:keys(_pipe),
_pipe@2 = gleam@list:filter_map(
_pipe@1,
fun(Key) -> gleam@string:split_once(Key, <<"#"/utf8>>) end
),
lists:append(_pipe@2, query_record_refs(Endpoints)).
-file("src/oaisp/internal/merge.gleam", 453).
?DOC(false).
-spec malformed_formats(
list(oaisp@endpoint:endpoint()),
gleam@package_interface:package()
) -> list({binary(), binary(), binary()}).
malformed_formats(Endpoints, Package) ->
_pipe = reached_refs(Endpoints, Package),
_pipe@1 = gleam@list:unique(_pipe),
gleam@list:flat_map(
_pipe@1,
fun(Ref) ->
{Module, Name} = Ref,
_pipe@2 = oaisp@internal@package_interface:malformed_format_lines(
Package,
Module,
Name
),
gleam@list:map(_pipe@2, fun(Line) -> {Module, Name, Line} end)
end
).
-file("src/oaisp/internal/merge.gleam", 489).
?DOC(false).
-spec duplicate_routes(list(oaisp@endpoint:endpoint())) -> list({binary(),
binary()}).
duplicate_routes(Endpoints) ->
Routes = gleam@list:map(
Endpoints,
fun(E) ->
{oaisp@endpoint:method_to_string(oaisp@endpoint:method(E)),
oaisp@endpoint:path(E)}
end
),
_pipe = Routes,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Route) ->
gleam@list:count(Routes, fun(R) -> R =:= Route end) > 1
end
),
gleam@list:unique(_pipe@1).
-file("src/oaisp/internal/merge.gleam", 541).
?DOC(false).
-spec path_placeholders(binary()) -> list(binary()).
path_placeholders(Path) ->
_pipe = Path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:filter(
_pipe@1,
fun(Segment) -> Segment /= <<""/utf8>> end
),
gleam@list:filter_map(
_pipe@2,
fun(Segment@1) -> _pipe@3 = oaisp@endpoint:placeholder_name(Segment@1),
gleam@option:to_result(_pipe@3, nil) end
).
-file("src/oaisp/internal/merge.gleam", 520).
?DOC(false).
-spec endpoint_path_param_mismatches(oaisp@endpoint:endpoint()) -> list(path_param_mismatch()).
endpoint_path_param_mismatches(E) ->
Method = oaisp@endpoint:method_to_string(oaisp@endpoint:method(E)),
Path = oaisp@endpoint:path(E),
Placeholders = path_placeholders(Path),
Declared = gleam@list:map(
oaisp@endpoint:path_params(E),
fun(Param) -> erlang:element(2, Param) end
),
Params_without_placeholder = begin
_pipe = Declared,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Name) -> not gleam@list:contains(Placeholders, Name) end
),
gleam@list:map(
_pipe@1,
fun(Name@1) -> {param_without_placeholder, Method, Path, Name@1} end
)
end,
Placeholders_without_param = begin
_pipe@2 = Placeholders,
_pipe@3 = gleam@list:filter(
_pipe@2,
fun(Name@2) -> not gleam@list:contains(Declared, Name@2) end
),
gleam@list:map(
_pipe@3,
fun(Name@3) -> {placeholder_without_param, Method, Path, Name@3} end
)
end,
lists:append(Params_without_placeholder, Placeholders_without_param).
-file("src/oaisp/internal/merge.gleam", 514).
?DOC(false).
-spec path_param_mismatches(list(oaisp@endpoint:endpoint())) -> list(path_param_mismatch()).
path_param_mismatches(Endpoints) ->
gleam@list:flat_map(Endpoints, fun endpoint_path_param_mismatches/1).