Current section

Files

Jump to
oaspec src oaspec@internal@codegen@router_ir.erl
Raw

src/oaspec@internal@codegen@router_ir.erl

-module(oaspec@internal@codegen@router_ir).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/internal/codegen/router_ir.gleam").
-export([imports/2, analyze/1]).
-export_type([router_requirements/0, header_spec/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 router_requirements() :: {router_requirements,
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean(),
boolean()}.
-type header_spec() :: {header_spec, binary(), binary(), binary(), boolean()}.
-file("src/oaspec/internal/codegen/router_ir.gleam", 409).
?DOC(false).
-spec imports(router_requirements(), oaspec@internal@codegen@context:context()) -> list(binary()).
imports(Requirements, Ctx) ->
Std_imports = [<<"gleam/dict.{type Dict}"/utf8>>],
Std_imports@1 = case erlang:element(16, Requirements) of
true ->
lists:append(Std_imports, [<<"gleam/list"/utf8>>]);
false ->
Std_imports
end,
Std_imports@2 = case erlang:element(17, Requirements) of
true ->
lists:append(Std_imports@1, [<<"gleam/uri"/utf8>>]);
false ->
Std_imports@1
end,
Std_imports@3 = case erlang:element(11, Requirements) of
true ->
lists:append(Std_imports@2, [<<"gleam/int"/utf8>>]);
false ->
Std_imports@2
end,
Std_imports@4 = case erlang:element(12, Requirements) of
true ->
lists:append(Std_imports@3, [<<"gleam/float"/utf8>>]);
false ->
Std_imports@3
end,
Std_imports@5 = case erlang:element(13, Requirements) of
true ->
lists:append(Std_imports@4, [<<"gleam/bool"/utf8>>]);
false ->
Std_imports@4
end,
Std_imports@6 = case erlang:element(18, Requirements) of
true ->
lists:append(Std_imports@5, [<<"gleam/option.{None, Some}"/utf8>>]);
false ->
Std_imports@5
end,
Std_imports@7 = case erlang:element(19, Requirements) orelse erlang:element(
20,
Requirements
) of
true ->
lists:append(Std_imports@6, [<<"gleam/json"/utf8>>]);
false ->
Std_imports@6
end,
Std_imports@8 = case erlang:element(14, Requirements) of
true ->
lists:append(Std_imports@7, [<<"gleam/string"/utf8>>]);
false ->
Std_imports@7
end,
Std_imports@9 = case erlang:element(5, Requirements) of
true ->
lists:append(Std_imports@8, [<<"gleam/dynamic"/utf8>>]);
false ->
Std_imports@8
end,
Std_imports@10 = case erlang:element(9, Requirements) of
true ->
lists:append(
Std_imports@9,
[<<"gleam/bit_array"/utf8>>, <<"gleam/result"/utf8>>]
);
false ->
Std_imports@9
end,
Pkg_imports = [<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/handlers"/utf8>>,
<<(oaspec@config:package(oaspec@internal@codegen@context:config(Ctx)))/binary,
"/handlers_generated"/utf8>>],
Pkg_imports@1 = case ((erlang:element(2, Requirements) orelse erlang:element(
6,
Requirements
))
orelse erlang:element(7, Requirements))
orelse erlang:element(27, Requirements) of
true ->
lists:append(
Pkg_imports,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/types"/utf8>>]
);
false ->
Pkg_imports
end,
Pkg_imports@2 = case erlang:element(21, Requirements) of
true ->
lists:append(
Pkg_imports@1,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/decode"/utf8>>]
);
false ->
Pkg_imports@1
end,
Pkg_imports@3 = case erlang:element(22, Requirements) of
true ->
lists:append(
Pkg_imports@2,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/encode"/utf8>>]
);
false ->
Pkg_imports@2
end,
Pkg_imports@4 = case erlang:element(26, Requirements) of
true ->
lists:append(
Pkg_imports@3,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/request_types"/utf8>>,
<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/response_types"/utf8>>]
);
false ->
lists:append(
Pkg_imports@3,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/response_types"/utf8>>]
)
end,
Pkg_imports@5 = case erlang:element(28, Requirements) of
true ->
lists:append(
Pkg_imports@4,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/guards"/utf8>>]
);
false ->
Pkg_imports@4
end,
lists:append(Std_imports@10, Pkg_imports@5).
-file("src/oaspec/internal/codegen/router_ir.gleam", 510).
?DOC(false).
-spec operation_needs_guard_validation(
oaspec@openapi@spec:operation(oaspec@openapi@spec:resolved()),
oaspec@internal@codegen@context:context()
) -> boolean().
operation_needs_guard_validation(Operation, Ctx) ->
Needs_body_guard = case erlang:element(7, Operation) of
{some, {value, Rb}} ->
Content_entries = maps:to_list(erlang:element(3, Rb)),
case Content_entries of
[{_, Mt}] ->
case erlang:element(2, Mt) of
{some, {inline, {object_schema, _, _, _, _, _, _}}} ->
true;
{some, {inline, {all_of_schema, _, _}}} ->
true;
{some, {reference, _, Name}} ->
oaspec@internal@codegen@guards:schema_has_validator(
Name,
Ctx
);
_ ->
false
end;
_ ->
false
end;
_ ->
false
end,
oaspec@config:validate(oaspec@internal@codegen@context:config(Ctx)) andalso Needs_body_guard.
-file("src/oaspec/internal/codegen/router_ir.gleam", 533).
?DOC(false).
-spec operations_have_response_headers(
list({binary(),
oaspec@openapi@spec:operation(oaspec@openapi@spec:resolved()),
binary(),
oaspec@openapi@spec:http_method()})
) -> boolean().
operations_have_response_headers(Operations) ->
gleam@list:any(
Operations,
fun(Op) ->
{_, Operation, _, _} = Op,
gleam@list:any(
maps:to_list(erlang:element(8, Operation)),
fun(Entry) ->
{_, Ref_or} = Entry,
case Ref_or of
{value, Response} ->
not gleam@dict:is_empty(erlang:element(4, Response));
_ ->
false
end
end
)
end
).
-file("src/oaspec/internal/codegen/router_ir.gleam", 613).
?DOC(false).
-spec response_header_field_type(
gleam@option:option(oaspec@openapi@schema:schema_ref())
) -> binary().
response_header_field_type(Schema_opt) ->
case Schema_opt of
{some, {inline, {integer_schema, _, _, _, _, _, _, _}}} ->
<<"Int"/utf8>>;
{some, {inline, {number_schema, _, _, _, _, _, _, _}}} ->
<<"Float"/utf8>>;
{some, {inline, {boolean_schema, _}}} ->
<<"Bool"/utf8>>;
{some, {inline, {string_schema, _, _, _, _, _, _}}} ->
<<"String"/utf8>>;
{some, {reference, _, Name}} ->
<<"types."/utf8,
(oaspec@internal@util@naming:schema_to_type_name(Name))/binary>>;
_ ->
<<"String"/utf8>>
end.
-file("src/oaspec/internal/codegen/router_ir.gleam", 594).
?DOC(false).
-spec sorted_header_specs(
gleam@dict:dict(binary(), oaspec@openapi@spec:header())
) -> list(header_spec()).
sorted_header_specs(Headers) ->
_pipe = Headers,
_pipe@1 = maps:to_list(_pipe),
_pipe@2 = gleam@list:sort(
_pipe@1,
fun(A, B) ->
gleam@string:compare(erlang:element(1, A), erlang:element(1, B))
end
),
gleam@list:map(
_pipe@2,
fun(Entry) ->
{Header_name, Header} = Entry,
Field_name = oaspec@internal@util@naming:to_snake_case(Header_name),
Field_type = response_header_field_type(erlang:element(4, Header)),
{header_spec,
Header_name,
Field_name,
Field_type,
erlang:element(3, Header)}
end
).
-file("src/oaspec/internal/codegen/router_ir.gleam", 548).
?DOC(false).
-spec operations_have_response_header_of_type(
list({binary(),
oaspec@openapi@spec:operation(oaspec@openapi@spec:resolved()),
binary(),
oaspec@openapi@spec:http_method()}),
binary()
) -> boolean().
operations_have_response_header_of_type(Operations, Type_name) ->
gleam@list:any(
Operations,
fun(Op) ->
{_, Operation, _, _} = Op,
gleam@list:any(
maps:to_list(erlang:element(8, Operation)),
fun(Entry) ->
{_, Ref_or} = Entry,
case Ref_or of
{value, Response} ->
gleam@list:any(
sorted_header_specs(erlang:element(4, Response)),
fun(Spec) ->
erlang:element(4, Spec) =:= Type_name
end
);
_ ->
false
end
end
)
end
).
-file("src/oaspec/internal/codegen/router_ir.gleam", 567).
?DOC(false).
-spec operations_have_optional_response_header(
list({binary(),
oaspec@openapi@spec:operation(oaspec@openapi@spec:resolved()),
binary(),
oaspec@openapi@spec:http_method()})
) -> boolean().
operations_have_optional_response_header(Operations) ->
gleam@list:any(
Operations,
fun(Op) ->
{_, Operation, _, _} = Op,
gleam@list:any(
maps:to_list(erlang:element(8, Operation)),
fun(Entry) ->
{_, Ref_or} = Entry,
case Ref_or of
{value, Response} ->
gleam@list:any(
sorted_header_specs(erlang:element(4, Response)),
fun(Spec) -> not erlang:element(5, Spec) end
);
_ ->
false
end
end
)
end
).
-file("src/oaspec/internal/codegen/router_ir.gleam", 49).
?DOC(false).
-spec analyze(oaspec@internal@codegen@context:context()) -> router_requirements().
analyze(Ctx) ->
Operations = oaspec@internal@codegen@context:operations(Ctx),
Has_deep_object = gleam@list:any(
Operations,
fun(Op) ->
{_, Operation, _, _} = Op,
gleam@list:any(
erlang:element(6, Operation),
fun(Ref_p) -> case Ref_p of
{value, P} ->
oaspec@internal@codegen@server_request_decode:is_deep_object_param(
P,
Ctx
);
_ ->
false
end end
)
end
),
Has_deep_object_with_ap = gleam@list:any(
Operations,
fun(Op@1) ->
{_, Operation@1, _, _} = Op@1,
gleam@list:any(
erlang:element(6, Operation@1),
fun(Ref_p@1) -> case Ref_p@1 of
{value, P@1} ->
oaspec@internal@codegen@server_request_decode:is_deep_object_param(
P@1,
Ctx
)
andalso oaspec@internal@codegen@server_request_decode:deep_object_has_additional_properties(
P@1,
Ctx
);
_ ->
false
end end
)
end
),
Needs_deep_object_present = gleam@list:any(
Operations,
fun(Op@2) ->
{_, Operation@2, _, _} = Op@2,
gleam@list:any(
erlang:element(6, Operation@2),
fun(Ref_p@2) -> case Ref_p@2 of
{value, P@2} ->
(oaspec@internal@codegen@server_request_decode:is_deep_object_param(
P@2,
Ctx
)
andalso not erlang:element(5, P@2))
andalso not oaspec@internal@codegen@server_request_decode:deep_object_has_untyped_additional_properties(
P@2,
Ctx
);
_ ->
false
end end
)
end
),
Has_deep_object_untyped_ap = gleam@list:any(
Operations,
fun(Op@3) ->
{_, Operation@3, _, _} = Op@3,
gleam@list:any(
erlang:element(6, Operation@3),
fun(Ref_p@3) -> case Ref_p@3 of
{value, P@3} ->
oaspec@internal@codegen@server_request_decode:is_deep_object_param(
P@3,
Ctx
)
andalso oaspec@internal@codegen@server_request_decode:deep_object_has_untyped_additional_properties(
P@3,
Ctx
);
_ ->
false
end end
)
end
),
Has_form_urlencoded_body = gleam@list:any(
Operations,
fun(Op@4) ->
{_, Operation@4, _, _} = Op@4,
oaspec@internal@codegen@server_request_decode:operation_uses_form_urlencoded_body(
Operation@4
)
end
),
Has_multipart_body = gleam@list:any(
Operations,
fun(Op@5) ->
{_, Operation@5, _, _} = Op@5,
oaspec@internal@codegen@server_request_decode:operation_uses_multipart_body(
Operation@5
)
end
),
Has_binary_request_body = gleam@list:any(
Operations,
fun(Op@6) ->
{_, Operation@6, _, _} = Op@6,
oaspec@internal@codegen@server_request_decode:operation_uses_octet_stream_body(
Operation@6
)
end
),
Needs_bit_array_import = Has_binary_request_body andalso gleam@list:any(
Operations,
fun(Op@7) ->
{_, Operation@7, _, _} = Op@7,
gleam@option:is_some(erlang:element(7, Operation@7)) andalso not oaspec@internal@codegen@server_request_decode:operation_uses_octet_stream_body(
Operation@7
)
end
),
Has_nested_form_urlencoded_body = gleam@list:any(
Operations,
fun(Op@8) ->
{_, Operation@8, _, _} = Op@8,
case erlang:element(7, Operation@8) of
{some, {value, Rb}} ->
oaspec@internal@codegen@server_request_decode:form_urlencoded_body_has_nested_object(
Rb,
Ctx
);
_ ->
false
end
end
),
Needs_int = gleam@list:any(
Operations,
fun(Op@9) ->
{_, Operation@9, _, _} = Op@9,
(gleam@list:any(
erlang:element(6, Operation@9),
fun(Ref_p@4) -> case Ref_p@4 of
{value, P@4} ->
oaspec@internal@codegen@server_request_decode:query_schema_needs_int(
oaspec@openapi@spec:parameter_schema(P@4),
Ctx
)
orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_int(
P@4,
Ctx
);
_ ->
false
end end
)
orelse case erlang:element(7, Operation@9) of
{some, {value, Rb@1}} ->
oaspec@internal@codegen@server_request_decode:form_urlencoded_body_needs_int(
Rb@1,
Ctx
);
_ ->
false
end)
orelse case erlang:element(7, Operation@9) of
{some, {value, Rb@2}} ->
oaspec@internal@codegen@server_request_decode:multipart_body_needs_int(
Rb@2,
Ctx
);
_ ->
false
end
end
)
orelse operations_have_response_header_of_type(Operations, <<"Int"/utf8>>),
Needs_float = gleam@list:any(
Operations,
fun(Op@10) ->
{_, Operation@10, _, _} = Op@10,
(gleam@list:any(
erlang:element(6, Operation@10),
fun(Ref_p@5) -> case Ref_p@5 of
{value, P@5} ->
oaspec@internal@codegen@server_request_decode:query_schema_needs_float(
oaspec@openapi@spec:parameter_schema(P@5),
Ctx
)
orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_float(
P@5,
Ctx
);
_ ->
false
end end
)
orelse case erlang:element(7, Operation@10) of
{some, {value, Rb@3}} ->
oaspec@internal@codegen@server_request_decode:form_urlencoded_body_needs_float(
Rb@3,
Ctx
);
_ ->
false
end)
orelse case erlang:element(7, Operation@10) of
{some, {value, Rb@4}} ->
oaspec@internal@codegen@server_request_decode:multipart_body_needs_float(
Rb@4,
Ctx
);
_ ->
false
end
end
)
orelse operations_have_response_header_of_type(Operations, <<"Float"/utf8>>),
Needs_bool = operations_have_response_header_of_type(
Operations,
<<"Bool"/utf8>>
),
Needs_string = ((Has_form_urlencoded_body orelse Has_multipart_body) orelse Has_deep_object_with_ap)
orelse gleam@list:any(
Operations,
fun(Op@11) ->
{_, Operation@11, _, _} = Op@11,
gleam@list:any(
erlang:element(6, Operation@11),
fun(Ref_p@6) -> case Ref_p@6 of
{value, P@6} ->
case erlang:element(3, P@6) of
in_cookie ->
true;
in_query ->
oaspec@internal@codegen@server_request_decode:query_schema_needs_string(
oaspec@openapi@spec:parameter_schema(
P@6
)
)
orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_string(
P@6,
Ctx
);
in_header ->
oaspec@internal@codegen@server_request_decode:query_schema_needs_string(
oaspec@openapi@spec:parameter_schema(
P@6
)
)
orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_string(
P@6,
Ctx
);
in_path ->
oaspec@internal@codegen@server_request_decode:query_schema_needs_string(
oaspec@openapi@spec:parameter_schema(
P@6
)
)
end;
_ ->
false
end end
)
orelse case erlang:element(7, Operation@11) of
{some, {value, Rb@5}} ->
oaspec@internal@codegen@server_request_decode:form_urlencoded_body_needs_string(
Rb@5,
Ctx
);
_ ->
false
end
end
),
Needs_cookie_lookup = gleam@list:any(
Operations,
fun(Op@12) ->
{_, Operation@12, _, _} = Op@12,
gleam@list:any(
erlang:element(6, Operation@12),
fun(Ref_p@7) -> case Ref_p@7 of
{value, P@7} ->
erlang:element(3, P@7) =:= in_cookie;
_ ->
false
end end
)
end
),
Needs_list_import = ((((Needs_cookie_lookup orelse Has_deep_object) orelse Has_form_urlencoded_body)
orelse Has_multipart_body)
orelse operations_have_response_headers(Operations))
orelse gleam@list:any(
Operations,
fun(Op@13) ->
{_, Operation@13, _, _} = Op@13,
gleam@list:any(
erlang:element(6, Operation@13),
fun(Ref_p@8) -> case Ref_p@8 of
{value, P@8} ->
case {erlang:element(3, P@8),
oaspec@openapi@spec:parameter_schema(P@8)} of
{in_query,
{some,
{inline, {array_schema, _, _, _, _, _}}}} ->
true;
{in_header,
{some,
{inline, {array_schema, _, _, _, _, _}}}} ->
true;
{_, _} ->
false
end;
_ ->
false
end end
)
end
),
Needs_uri_import = Needs_cookie_lookup orelse Has_form_urlencoded_body,
Needs_option = ((oaspec@internal@codegen@import_analysis:operations_have_optional_params(
Operations
)
orelse oaspec@internal@codegen@import_analysis:operations_have_optional_body(
Operations
))
orelse gleam@list:any(
Operations,
fun(Op@14) ->
{_, Operation@14, _, _} = Op@14,
Has_optional_deep_object_fields = gleam@list:any(
erlang:element(6, Operation@14),
fun(Ref_p@9) -> case Ref_p@9 of
{value, P@9} ->
oaspec@internal@codegen@server_request_decode:deep_object_param_has_optional_fields(
P@9,
Ctx
);
_ ->
false
end end
),
Has_optional_form_urlencoded_fields = case erlang:element(
7,
Operation@14
) of
{some, {value, Rb@6}} ->
oaspec@internal@codegen@server_request_decode:form_urlencoded_body_has_optional_fields(
Rb@6,
Ctx
);
_ ->
false
end,
Has_optional_multipart_fields = case erlang:element(7, Operation@14) of
{some, {value, Rb@7}} ->
oaspec@internal@codegen@server_request_decode:multipart_body_has_optional_fields(
Rb@7,
Ctx
);
_ ->
false
end,
(Has_optional_deep_object_fields orelse Has_optional_form_urlencoded_fields)
orelse Has_optional_multipart_fields
end
))
orelse operations_have_optional_response_header(Operations),
Needs_json = gleam@list:any(
Operations,
fun(Op@15) ->
{_, Operation@15, _, _} = Op@15,
gleam@list:any(
maps:to_list(erlang:element(8, Operation@15)),
fun(Entry) ->
{_, Ref_or} = Entry,
case Ref_or of
{value, Response} ->
Content_entries = maps:to_list(
erlang:element(3, Response)
),
case Content_entries of
[{Media_type_name, Media_type}] ->
case oaspec@internal@util@content_type:is_json_compatible(
Media_type_name
) of
true ->
case erlang:element(2, Media_type) of
{some, _} ->
true;
none ->
false
end;
false ->
false
end;
_ ->
false
end;
_ ->
false
end
end
)
end
),
Needs_decode = gleam@list:any(
Operations,
fun(Op@16) ->
{_, Operation@16, _, _} = Op@16,
case erlang:element(7, Operation@16) of
{some, {value, Rb@8}} ->
gleam@list:any(
maps:to_list(erlang:element(3, Rb@8)),
fun(Entry@1) ->
{Content_type_name, _} = Entry@1,
oaspec@internal@util@content_type:is_json_compatible(
Content_type_name
)
end
);
_ ->
false
end
end
),
Uses_query = gleam@list:any(
Operations,
fun(Op@17) ->
{_, Operation@17, _, _} = Op@17,
gleam@list:any(
erlang:element(6, Operation@17),
fun(Ref_p@10) -> case Ref_p@10 of
{value, P@10} ->
erlang:element(3, P@10) =:= in_query;
_ ->
false
end end
)
end
),
Uses_headers = Has_multipart_body orelse gleam@list:any(
Operations,
fun(Op@18) ->
{_, Operation@18, _, _} = Op@18,
gleam@list:any(
erlang:element(6, Operation@18),
fun(Ref_p@11) -> case Ref_p@11 of
{value, P@11} ->
(erlang:element(3, P@11) =:= in_header) orelse (erlang:element(
3,
P@11
)
=:= in_cookie);
_ ->
false
end end
)
end
),
Uses_body = gleam@list:any(
Operations,
fun(Op@19) ->
{_, Operation@19, _, _} = Op@19,
gleam@option:is_some(erlang:element(7, Operation@19))
end
),
Has_params_ops = gleam@list:any(
Operations,
fun(Op@20) ->
{_, Operation@20, _, _} = Op@20,
not gleam@list:is_empty(erlang:element(6, Operation@20)) orelse gleam@option:is_some(
erlang:element(7, Operation@20)
)
end
),
Has_enum_ref_params = oaspec@internal@codegen@server_request_decode:operations_have_enum_ref_params(
Operations,
Ctx
),
Needs_guards = oaspec@config:validate(
oaspec@internal@codegen@context:config(Ctx)
)
andalso gleam@list:any(
Operations,
fun(Op@21) ->
{_, Operation@21, _, _} = Op@21,
operation_needs_guard_validation(Operation@21, Ctx)
end
),
Needs_json_for_guards = Needs_guards,
{router_requirements,
Has_deep_object,
Has_deep_object_with_ap,
Needs_deep_object_present,
Has_deep_object_untyped_ap,
Has_form_urlencoded_body,
Has_multipart_body,
Has_binary_request_body,
Needs_bit_array_import,
Has_nested_form_urlencoded_body,
Needs_int,
Needs_float,
Needs_bool,
Needs_string,
Needs_cookie_lookup,
Needs_list_import,
Needs_uri_import,
Needs_option,
Needs_json,
Needs_json_for_guards,
Needs_decode,
Needs_json,
Uses_query,
Uses_headers,
Uses_body,
Has_params_ops,
Has_enum_ref_params,
Needs_guards}.