-module(oaspec@codegen@client). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/codegen/client.gleam"). -export([generate/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/oaspec/codegen/client.gleam", 417). ?DOC(" Substitute server variable placeholders in a URL template with their default values.\n"). -spec substitute_server_variables( binary(), list({binary(), oaspec@openapi@spec:server_variable()}) ) -> binary(). substitute_server_variables(Url, Variables) -> gleam@list:fold( Variables, Url, fun(Acc, Entry) -> {Name, Variable} = Entry, gleam@string:replace( Acc, <<<<"{"/utf8, Name/binary>>/binary, "}"/utf8>>, erlang:element(2, Variable) ) end ). -file("src/oaspec/codegen/client.gleam", 428). ?DOC(" Generate the default_base_url function from the first server's template and variables.\n"). -spec generate_default_base_url( gleam@string_tree:string_tree(), oaspec@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_default_base_url(Sb, Ctx) -> case erlang:element(6, erlang:element(2, Ctx)) of [First_server | _] -> Variables = oaspec@codegen@ir_build:sorted_entries( erlang:element(4, First_server) ), Resolved_url = substitute_server_variables( erlang:element(2, First_server), Variables ), Defaults_doc = case Variables of [] -> <<""/utf8>>; _ -> <<"Defaults: "/utf8, (gleam@string:join( gleam@list:map( Variables, fun(Entry) -> {Name, Variable} = Entry, <<<<<>/binary, (erlang:element(2, Variable))/binary>>/binary, "\""/utf8>> end ), <<", "/utf8>> ))/binary>> end, Sb@1 = case Defaults_doc of <<""/utf8>> -> _pipe = Sb, oaspec@util@string_extra:doc_comment( _pipe, <<"Build the base URL from server template variables."/utf8>> ); Doc -> _pipe@1 = Sb, _pipe@2 = oaspec@util@string_extra:doc_comment( _pipe@1, <<"Build the base URL from server template variables."/utf8>> ), oaspec@util@string_extra:doc_comment(_pipe@2, Doc) end, _pipe@3 = Sb@1, _pipe@4 = oaspec@util@string_extra:line( _pipe@3, <<"pub fn default_base_url() -> String {"/utf8>> ), _pipe@5 = oaspec@util@string_extra:indent( _pipe@4, 1, <<<<"\""/utf8, Resolved_url/binary>>/binary, "\""/utf8>> ), _pipe@6 = oaspec@util@string_extra:line(_pipe@5, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@6); [] -> Sb end. -file("src/oaspec/codegen/client.gleam", 473). ?DOC(" Generate a client function for a single operation.\n"). -spec generate_client_function( gleam@string_tree:string_tree(), binary(), oaspec@openapi@spec:operation(oaspec@openapi@spec:resolved()), binary(), oaspec@openapi@spec:http_method(), oaspec@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_client_function(Sb, Op_id, Operation, Path, Method, Ctx) -> Fn_name = oaspec@util@naming:operation_to_function_name(Op_id), Sb@1 = case erlang:element(3, Operation) of {some, Summary} -> _pipe = Sb, oaspec@util@string_extra:doc_comment(_pipe, Summary); _ -> Sb end, Sb@2 = case erlang:element(4, Operation) of {some, Desc} -> _pipe@1 = Sb@1, oaspec@util@string_extra:doc_comment(_pipe@1, Desc); _ -> Sb@1 end, Sb@3 = case erlang:element(7, Operation) of {some, {value, Rb}} -> Content_entries = oaspec@codegen@ir_build:sorted_entries( erlang:element(3, Rb) ), case Content_entries of [_, _ | _] -> Ct_names = begin _pipe@2 = gleam@list:map( Content_entries, fun(E) -> erlang:element(1, E) end ), gleam@string:join(_pipe@2, <<", "/utf8>>) end, _pipe@3 = Sb@2, oaspec@util@string_extra:doc_comment( _pipe@3, <<"Supported content types: "/utf8, Ct_names/binary>> ); _ -> Sb@2 end; _ -> Sb@2 end, Unwrapped_params = gleam@list:filter_map( erlang:element(6, Operation), fun(Ref_p) -> case Ref_p of {value, P} -> {ok, P}; _ -> {error, nil} end end ), Path_params = gleam@list:filter( Unwrapped_params, fun(P@1) -> case erlang:element(3, P@1) of in_path -> true; _ -> false end end ), Query_params = gleam@list:filter( Unwrapped_params, fun(P@2) -> case erlang:element(3, P@2) of in_query -> true; _ -> false end end ), Header_params = gleam@list:filter( Unwrapped_params, fun(P@3) -> case erlang:element(3, P@3) of in_header -> true; _ -> false end end ), Cookie_params = gleam@list:filter( Unwrapped_params, fun(P@4) -> case erlang:element(3, P@4) of in_cookie -> true; _ -> false end end ), Response_type = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, "Response"/utf8>>, Params = oaspec@codegen@client_request:build_param_list( Path_params, Query_params, Header_params, Cookie_params, Operation, Op_id, Ctx ), Sb@4 = begin _pipe@4 = Sb@3, oaspec@util@string_extra:line( _pipe@4, <<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(config: ClientConfig"/utf8>>/binary, Params/binary>>/binary, ") -> Result(response_types."/utf8>>/binary, Response_type/binary>>/binary, ", ClientError) {"/utf8>> ) end, Client_guard_schema_name = case {erlang:element(7, erlang:element(3, Ctx)), erlang:element(7, Operation)} of {true, {some, {value, Rb@1}}} -> Content_entries@1 = maps:to_list(erlang:element(3, Rb@1)), case Content_entries@1 of [{_, Mt}] -> case erlang:element(2, Mt) of {some, {reference, _, Name}} -> case oaspec@codegen@guards:schema_has_validator( Name, Ctx ) of true -> {some, {Name, erlang:element(4, Rb@1)}}; false -> none end; _ -> none end; _ -> none end; {_, _} -> none end, Sb@5 = case Client_guard_schema_name of {some, {Name@1, true}} -> Validate_fn = <<<<"guards.validate_"/utf8, (oaspec@util@naming:to_snake_case(Name@1))/binary>>/binary, "(body)"/utf8>>, _pipe@5 = Sb@4, _pipe@6 = oaspec@util@string_extra:indent( _pipe@5, 1, <<<<"case "/utf8, Validate_fn/binary>>/binary, " {"/utf8>> ), _pipe@7 = oaspec@util@string_extra:indent( _pipe@6, 2, <<"Error(errors) -> Error(ValidationError(errors:))"/utf8>> ), oaspec@util@string_extra:indent(_pipe@7, 2, <<"Ok(_) -> {"/utf8>>); {some, {Name@2, false}} -> Validate_fn@1 = <<"guards.validate_"/utf8, (oaspec@util@naming:to_snake_case(Name@2))/binary>>, _pipe@8 = Sb@4, _pipe@9 = oaspec@util@string_extra:indent( _pipe@8, 1, <<"let validation_errors = case body {"/utf8>> ), _pipe@10 = oaspec@util@string_extra:indent( _pipe@9, 2, <<<<"Some(b) -> case "/utf8, Validate_fn@1/binary>>/binary, "(b) {"/utf8>> ), _pipe@11 = oaspec@util@string_extra:indent( _pipe@10, 3, <<"Error(errors) -> errors"/utf8>> ), _pipe@12 = oaspec@util@string_extra:indent( _pipe@11, 3, <<"Ok(_) -> []"/utf8>> ), _pipe@13 = oaspec@util@string_extra:indent( _pipe@12, 2, <<"}"/utf8>> ), _pipe@14 = oaspec@util@string_extra:indent( _pipe@13, 2, <<"None -> []"/utf8>> ), _pipe@15 = oaspec@util@string_extra:indent( _pipe@14, 1, <<"}"/utf8>> ), _pipe@16 = oaspec@util@string_extra:indent( _pipe@15, 1, <<"case validation_errors {"/utf8>> ), _pipe@17 = oaspec@util@string_extra:indent( _pipe@16, 2, <<"[_, ..] -> Error(ValidationError(errors: validation_errors))"/utf8>> ), oaspec@util@string_extra:indent(_pipe@17, 2, <<"[] -> {"/utf8>>); none -> Sb@4 end, Effective_server_url = case erlang:element(12, Operation) of [First_server | _] -> Variables = oaspec@codegen@ir_build:sorted_entries( erlang:element(4, First_server) ), Resolved = substitute_server_variables( erlang:element(2, First_server), Variables ), {some, Resolved}; [] -> none end, Sb@6 = case Effective_server_url of {some, Url} -> _pipe@18 = Sb@5, oaspec@util@string_extra:indent( _pipe@18, 1, <<"// Server override: "/utf8, Url/binary>> ); none -> Sb@5 end, Sb@7 = begin _pipe@19 = Sb@6, oaspec@util@string_extra:indent( _pipe@19, 1, <<<<"let path = \""/utf8, Path/binary>>/binary, "\""/utf8>> ) end, Sb@9 = gleam@list:fold( Path_params, Sb@7, fun(Sb@8, P@5) -> Param_name = oaspec@util@naming:to_snake_case( erlang:element(2, P@5) ), To_string_expr = oaspec@codegen@client_request:param_to_string_expr( P@5, Param_name, Ctx ), _pipe@20 = Sb@8, oaspec@util@string_extra:indent( _pipe@20, 1, <<<<<<<<"let path = string.replace(path, \"{"/utf8, (erlang:element(2, P@5))/binary>>/binary, "}\", uri.percent_encode("/utf8>>/binary, To_string_expr/binary>>/binary, "))"/utf8>> ) end ), Sb@14 = case gleam@list:is_empty(Query_params) of true -> Sb@9; false -> Sb@10 = begin _pipe@21 = Sb@9, oaspec@util@string_extra:indent( _pipe@21, 1, <<"let query_parts = []"/utf8>> ) end, Sb@12 = gleam@list:fold( Query_params, Sb@10, fun(Sb@11, P@6) -> Param_name@1 = oaspec@util@naming:to_snake_case( erlang:element(2, P@6) ), case {erlang:element(7, P@6), oaspec@codegen@client_request:is_deep_object_param( P@6, Ctx )} of {{some, deep_object_style}, true} -> oaspec@codegen@client_request:generate_deep_object_query_param( Sb@11, P@6, Param_name@1, Ctx ); {_, _} -> case oaspec@codegen@client_request:is_exploded_array_param( P@6, Ctx ) of true -> oaspec@codegen@client_request:generate_exploded_array_query_param( Sb@11, P@6, Param_name@1, Ctx ); false -> case erlang:element(5, P@6) of true -> To_str = oaspec@codegen@client_request:to_str_for_required( P@6, Param_name@1, Ctx ), Encoded = oaspec@codegen@client_security:maybe_percent_encode( To_str, P@6 ), _pipe@22 = Sb@11, oaspec@util@string_extra:indent( _pipe@22, 1, <<<<<<<<"let query_parts = [\""/utf8, (erlang:element( 2, P@6 ))/binary>>/binary, "=\" <> "/utf8>>/binary, Encoded/binary>>/binary, ", ..query_parts]"/utf8>> ); false -> To_str@1 = oaspec@codegen@client_request:to_str_for_optional_value( P@6, Ctx ), Encoded@1 = oaspec@codegen@client_security:maybe_percent_encode( To_str@1, P@6 ), _pipe@23 = Sb@11, _pipe@24 = oaspec@util@string_extra:indent( _pipe@23, 1, <<<<"let query_parts = case "/utf8, Param_name@1/binary>>/binary, " {"/utf8>> ), _pipe@25 = oaspec@util@string_extra:indent( _pipe@24, 2, <<<<<<<<"Some(v) -> [\""/utf8, (erlang:element( 2, P@6 ))/binary>>/binary, "=\" <> "/utf8>>/binary, Encoded@1/binary>>/binary, ", ..query_parts]"/utf8>> ), _pipe@26 = oaspec@util@string_extra:indent( _pipe@25, 2, <<"None -> query_parts"/utf8>> ), oaspec@util@string_extra:indent( _pipe@26, 1, <<"}"/utf8>> ) end end end end ), Sb@13 = begin _pipe@27 = Sb@12, _pipe@28 = oaspec@util@string_extra:indent( _pipe@27, 1, <<"let query_string = string.join(query_parts, \"&\")"/utf8>> ), _pipe@29 = oaspec@util@string_extra:indent( _pipe@28, 1, <<"let path = case query_string {"/utf8>> ), _pipe@30 = oaspec@util@string_extra:indent( _pipe@29, 2, <<"\"\" -> path"/utf8>> ), _pipe@31 = oaspec@util@string_extra:indent( _pipe@30, 2, <<"_ -> path <> \"?\" <> query_string"/utf8>> ), oaspec@util@string_extra:indent(_pipe@31, 1, <<"}"/utf8>>) end, Sb@13 end, Http_method = case Method of get -> <<"http.Get"/utf8>>; post -> <<"http.Post"/utf8>>; put -> <<"http.Put"/utf8>>; delete -> <<"http.Delete"/utf8>>; patch -> <<"http.Patch"/utf8>>; head -> <<"http.Head"/utf8>>; options -> <<"http.Options"/utf8>>; trace -> <<"http.Trace"/utf8>> end, Base_url_expr = case Effective_server_url of {some, Url@1} -> <<<<"\""/utf8, Url@1/binary>>/binary, "\""/utf8>>; none -> <<"config.base_url"/utf8>> end, Sb@15 = begin _pipe@32 = Sb@14, _pipe@33 = oaspec@util@string_extra:indent( _pipe@32, 1, <<<<"let assert Ok(req) = request.to("/utf8, Base_url_expr/binary>>/binary, " <> path)"/utf8>> ), oaspec@util@string_extra:indent( _pipe@33, 1, <<<<"let req = request.set_method(req, "/utf8, Http_method/binary>>/binary, ")"/utf8>> ) end, Sb@18 = case erlang:element(7, Operation) of {some, {value, Rb@2}} -> Sb@16 = case erlang:element(4, Rb@2) of true -> Sb@15; false -> _pipe@34 = Sb@15, _pipe@35 = oaspec@util@string_extra:indent( _pipe@34, 1, <<"let req = case body {"/utf8>> ), oaspec@util@string_extra:indent( _pipe@35, 2, <<"Some(body) -> {"/utf8>> ) end, Content_entries@2 = oaspec@codegen@ir_build:sorted_entries( erlang:element(3, Rb@2) ), Sb@17 = case Content_entries@2 of [_, _ | _] -> _pipe@36 = Sb@16, _pipe@37 = oaspec@util@string_extra:indent( _pipe@36, 1, <<"let req = request.set_header(req, \"content-type\", content_type)"/utf8>> ), oaspec@util@string_extra:indent( _pipe@37, 1, <<"let req = request.set_body(req, body)"/utf8>> ); [{Content_type_key, _}] -> case Content_type_key of <<"multipart/form-data"/utf8>> -> oaspec@codegen@client_request:generate_multipart_body( Sb@16, Rb@2, Op_id, Ctx ); <<"application/x-www-form-urlencoded"/utf8>> -> oaspec@codegen@client_request:generate_form_urlencoded_body( Sb@16, Rb@2, Op_id, Ctx ); _ -> Body_encode_expr = oaspec@codegen@client_request:get_body_encode_expr( Rb@2, Op_id, Ctx ), _pipe@38 = Sb@16, _pipe@39 = oaspec@util@string_extra:indent( _pipe@38, 1, <<<<"let req = request.set_header(req, \"content-type\", \""/utf8, Content_type_key/binary>>/binary, "\")"/utf8>> ), oaspec@util@string_extra:indent( _pipe@39, 1, <<<<"let req = request.set_body(req, "/utf8, Body_encode_expr/binary>>/binary, ")"/utf8>> ) end; [] -> Sb@16 end, case erlang:element(4, Rb@2) of true -> Sb@17; false -> _pipe@40 = Sb@17, _pipe@41 = oaspec@util@string_extra:indent( _pipe@40, 2, <<"req"/utf8>> ), _pipe@42 = oaspec@util@string_extra:indent( _pipe@41, 1, <<"}"/utf8>> ), _pipe@43 = oaspec@util@string_extra:indent( _pipe@42, 2, <<"None -> req"/utf8>> ), oaspec@util@string_extra:indent(_pipe@43, 1, <<"}"/utf8>>) end; _ -> Sb@15 end, Sb@20 = gleam@list:fold( Header_params, Sb@18, fun(Sb@19, P@7) -> Param_name@2 = oaspec@util@naming:to_snake_case( erlang:element(2, P@7) ), Header_name = string:lowercase(erlang:element(2, P@7)), case erlang:element(5, P@7) of true -> To_str@2 = oaspec@codegen@client_request:param_to_string_expr( P@7, Param_name@2, Ctx ), _pipe@44 = Sb@19, oaspec@util@string_extra:indent( _pipe@44, 1, <<<<<<<<"let req = request.set_header(req, \""/utf8, Header_name/binary>>/binary, "\", "/utf8>>/binary, To_str@2/binary>>/binary, ")"/utf8>> ); false -> To_str@3 = oaspec@codegen@client_request:to_str_for_optional_value( P@7, Ctx ), _pipe@45 = Sb@19, _pipe@46 = oaspec@util@string_extra:indent( _pipe@45, 1, <<<<"let req = case "/utf8, Param_name@2/binary>>/binary, " {"/utf8>> ), _pipe@47 = oaspec@util@string_extra:indent( _pipe@46, 2, <<<<<<<<"Some(v) -> request.set_header(req, \""/utf8, Header_name/binary>>/binary, "\", "/utf8>>/binary, To_str@3/binary>>/binary, ")"/utf8>> ), _pipe@48 = oaspec@util@string_extra:indent( _pipe@47, 2, <<"None -> req"/utf8>> ), oaspec@util@string_extra:indent(_pipe@48, 1, <<"}"/utf8>>) end end ), Sb@24 = case gleam@list:is_empty(Cookie_params) of true -> Sb@20; false -> Sb@21 = begin _pipe@49 = Sb@20, oaspec@util@string_extra:indent( _pipe@49, 1, <<"let cookie_parts = []"/utf8>> ) end, Sb@23 = gleam@list:fold( Cookie_params, Sb@21, fun(Sb@22, P@8) -> Param_name@3 = oaspec@util@naming:to_snake_case( erlang:element(2, P@8) ), case erlang:element(5, P@8) of true -> To_str@4 = oaspec@codegen@client_request:param_to_string_expr( P@8, Param_name@3, Ctx ), _pipe@50 = Sb@22, oaspec@util@string_extra:indent( _pipe@50, 1, <<<<<<<<"let cookie_parts = [\""/utf8, (erlang:element(2, P@8))/binary>>/binary, "=\" <> uri.percent_encode("/utf8>>/binary, To_str@4/binary>>/binary, "), ..cookie_parts]"/utf8>> ); false -> To_str@5 = oaspec@codegen@client_request:to_str_for_optional_value( P@8, Ctx ), _pipe@51 = Sb@22, _pipe@52 = oaspec@util@string_extra:indent( _pipe@51, 1, <<<<"let cookie_parts = case "/utf8, Param_name@3/binary>>/binary, " {"/utf8>> ), _pipe@53 = oaspec@util@string_extra:indent( _pipe@52, 2, <<<<<<<<"Some(v) -> [\""/utf8, (erlang:element(2, P@8))/binary>>/binary, "=\" <> uri.percent_encode("/utf8>>/binary, To_str@5/binary>>/binary, "), ..cookie_parts]"/utf8>> ), _pipe@54 = oaspec@util@string_extra:indent( _pipe@53, 2, <<"None -> cookie_parts"/utf8>> ), oaspec@util@string_extra:indent( _pipe@54, 1, <<"}"/utf8>> ) end end ), _pipe@55 = Sb@23, _pipe@56 = oaspec@util@string_extra:indent( _pipe@55, 1, <<"let req = case cookie_parts {"/utf8>> ), _pipe@57 = oaspec@util@string_extra:indent( _pipe@56, 2, <<"[] -> req"/utf8>> ), _pipe@58 = oaspec@util@string_extra:indent( _pipe@57, 2, <<"_ -> request.set_header(req, \"cookie\", string.join(cookie_parts, \"; \"))"/utf8>> ), oaspec@util@string_extra:indent(_pipe@58, 1, <<"}"/utf8>>) end, Effective_security = case erlang:element(10, Operation) of {some, Sec} -> Sec; none -> erlang:element(7, erlang:element(2, Ctx)) end, Sb@27 = case Effective_security of [] -> Sb@24; Alternatives -> Sb@26 = gleam@list:fold( Alternatives, Sb@24, fun(Sb@25, Alt) -> All_scopes = gleam@list:flat_map( erlang:element(2, Alt), fun(S) -> erlang:element(3, S) end ), case All_scopes of [] -> Sb@25; Scopes -> _pipe@59 = Sb@25, oaspec@util@string_extra:indent( _pipe@59, 1, <<"// Required scopes: "/utf8, (gleam@string:join(Scopes, <<", "/utf8>>))/binary>> ) end end ), oaspec@codegen@client_security:generate_security_or_chain( Sb@26, Ctx, Alternatives, 1 ) end, Sb@28 = begin _pipe@60 = Sb@27, _pipe@61 = oaspec@util@string_extra:indent( _pipe@60, 1, <<"case config.send(req) {"/utf8>> ), _pipe@62 = oaspec@util@string_extra:indent( _pipe@61, 2, <<"Error(e) -> Error(e)"/utf8>> ), oaspec@util@string_extra:indent(_pipe@62, 2, <<"Ok(resp) -> {"/utf8>>) end, Responses = oaspec@util@http:sort_response_entries( maps:to_list(erlang:element(8, Operation)) ), Sb@29 = begin _pipe@63 = Sb@28, oaspec@util@string_extra:indent( _pipe@63, 3, <<"case resp.status {"/utf8>> ) end, Sb@31 = gleam@list:fold( Responses, Sb@29, fun(Sb@30, Entry) -> {Status_code, Ref_or} = Entry, case Ref_or of {value, Response} -> Variant_name = <<<<<<"response_types."/utf8, (oaspec@util@naming:schema_to_type_name(Op_id))/binary>>/binary, "Response"/utf8>>/binary, (oaspec@util@http:status_code_suffix(Status_code))/binary>>, Content_entries@3 = oaspec@codegen@ir_build:sorted_entries( erlang:element(3, Response) ), case Content_entries@3 of [] -> _pipe@64 = Sb@30, oaspec@util@string_extra:indent( _pipe@64, 4, <<<<<<(oaspec@util@http:status_code_to_int_pattern( Status_code ))/binary, " -> Ok("/utf8>>/binary, Variant_name/binary>>/binary, ")"/utf8>> ); [{Single_ct, Single_mt}] -> oaspec@codegen@client_response:generate_single_content_response( Sb@30, Status_code, Variant_name, Single_ct, Single_mt, Op_id, Ctx ); Multiple -> oaspec@codegen@client_response:generate_multi_content_response( Sb@30, Status_code, Variant_name, Multiple, Op_id, Ctx ) end; _ -> Sb@30 end end ), Has_default = gleam@list:any( Responses, fun(Entry@1) -> {Code, _} = Entry@1, Code =:= default_status end ), Sb@32 = case Has_default of true -> Sb@31; false -> _pipe@65 = Sb@31, oaspec@util@string_extra:indent( _pipe@65, 4, <<"_ -> Error(DecodeError(detail: \"Unexpected status: \" <> int.to_string(resp.status)))"/utf8>> ) end, Sb@33 = begin _pipe@66 = Sb@32, _pipe@67 = oaspec@util@string_extra:indent(_pipe@66, 3, <<"}"/utf8>>), _pipe@68 = oaspec@util@string_extra:indent(_pipe@67, 2, <<"}"/utf8>>), oaspec@util@string_extra:indent(_pipe@68, 1, <<"}"/utf8>>) end, Sb@34 = case Client_guard_schema_name of {some, _} -> _pipe@69 = Sb@33, _pipe@70 = oaspec@util@string_extra:indent( _pipe@69, 1, <<"}"/utf8>> ), oaspec@util@string_extra:indent(_pipe@70, 1, <<"}"/utf8>>); none -> Sb@33 end, _pipe@71 = Sb@34, _pipe@72 = oaspec@util@string_extra:line(_pipe@71, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@72). -file("src/oaspec/codegen/client.gleam", 1057). ?DOC(" Build a doc comment describing a security scheme helper.\n"). -spec scheme_doc_comment( binary(), oaspec@openapi@spec:ref_or(oaspec@openapi@spec:security_scheme()) ) -> binary(). scheme_doc_comment(Scheme_name, Scheme_ref) -> case Scheme_ref of {value, {api_key_scheme, Key_name, scheme_in_header}} -> <<<<<<<<"Set the API key for the "/utf8, Scheme_name/binary>>/binary, " security scheme (header: "/utf8>>/binary, Key_name/binary>>/binary, ")."/utf8>>; {value, {api_key_scheme, Key_name@1, scheme_in_query}} -> <<<<<<<<"Set the API key for the "/utf8, Scheme_name/binary>>/binary, " security scheme (query: "/utf8>>/binary, Key_name@1/binary>>/binary, ")."/utf8>>; {value, {api_key_scheme, Key_name@2, scheme_in_cookie}} -> <<<<<<<<"Set the API key for the "/utf8, Scheme_name/binary>>/binary, " security scheme (cookie: "/utf8>>/binary, Key_name@2/binary>>/binary, ")."/utf8>>; {value, {http_scheme, <<"bearer"/utf8>>, _}} -> <<<<"Set the bearer token for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>>; {value, {http_scheme, <<"basic"/utf8>>, _}} -> <<<<"Set the basic auth credentials for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>>; {value, {http_scheme, <<"digest"/utf8>>, _}} -> <<<<"Set the digest auth credentials for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>>; {value, {http_scheme, Http_scheme, _}} -> <<<<<<<<"Set the token for the "/utf8, Scheme_name/binary>>/binary, " security scheme ("/utf8>>/binary, Http_scheme/binary>>/binary, " auth)."/utf8>>; {value, {o_auth2_scheme, _, _}} -> <<<<"Set the OAuth2 token for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>>; {value, {open_id_connect_scheme, _, _}} -> <<<<"Set the OpenID Connect token for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>>; _ -> <<<<"Set the credential for the "/utf8, Scheme_name/binary>>/binary, " security scheme."/utf8>> end. -file("src/oaspec/codegen/client.gleam", 1035). ?DOC(" Generate with_* helper functions for security scheme configuration.\n"). -spec generate_with_helpers( gleam@string_tree:string_tree(), list({binary(), oaspec@openapi@spec:ref_or(oaspec@openapi@spec:security_scheme())}) ) -> gleam@string_tree:string_tree(). generate_with_helpers(Sb, Security_schemes) -> gleam@list:fold( Security_schemes, Sb, fun(Sb@1, Entry) -> {Scheme_name, Scheme_ref} = Entry, Field_name = oaspec@util@naming:to_snake_case(Scheme_name), Doc = scheme_doc_comment(Scheme_name, Scheme_ref), _pipe = Sb@1, _pipe@1 = oaspec@util@string_extra:doc_comment(_pipe, Doc), _pipe@2 = oaspec@util@string_extra:line( _pipe@1, <<<<"pub fn with_"/utf8, Field_name/binary>>/binary, "(config: ClientConfig, token: String) -> ClientConfig {"/utf8>> ), _pipe@3 = oaspec@util@string_extra:indent( _pipe@2, 1, <<<<"ClientConfig(..config, "/utf8, Field_name/binary>>/binary, ": Some(token))"/utf8>> ), _pipe@4 = oaspec@util@string_extra:line(_pipe@3, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@4) end ). -file("src/oaspec/codegen/client.gleam", 34). ?DOC(" Generate the client module with functions for each operation.\n"). -spec generate_client(oaspec@codegen@context:context()) -> binary(). generate_client(Ctx) -> Operations = oaspec@openapi@operations:collect_operations(Ctx), All_params = gleam@list:flat_map( Operations, fun(Op) -> {_, Operation, _, _} = Op, gleam@list:filter_map( erlang:element(6, Operation), fun(Ref_p) -> case Ref_p of {value, P} -> {ok, P}; _ -> {error, nil} end end ) end ), Needs_bool = gleam@list:any( All_params, fun(P@1) -> case erlang:element(6, P@1) of {parameter_schema, {inline, {boolean_schema, _}}} -> true; _ -> false end end ), Needs_float = gleam@list:any( All_params, fun(P@2) -> case erlang:element(6, P@2) of {parameter_schema, {inline, {number_schema, _, _, _, _, _, _, _}}} -> true; _ -> false end end ), Has_multi_content_response = gleam@list:any( Operations, fun(Op@1) -> {_, Operation@1, _, _} = Op@1, gleam@list:any( maps:to_list(erlang:element(8, Operation@1)), fun(Entry) -> {_, Ref_or} = Entry, case Ref_or of {value, Response} -> erlang:length( maps:to_list(erlang:element(3, Response)) ) > 1; _ -> false end end ) end ), Has_form_urlencoded = gleam@list:any( Operations, fun(Op@2) -> {_, Operation@2, _, _} = Op@2, case erlang:element(7, Operation@2) of {some, {value, Rb}} -> gleam@list:any( maps:to_list(erlang:element(3, Rb)), fun(Ce) -> {Key, _} = Ce, Key =:= <<"application/x-www-form-urlencoded"/utf8>> end ); _ -> false end end ), Needs_list = (Has_form_urlencoded orelse Has_multi_content_response) orelse gleam@list:any( All_params, fun(P@3) -> case erlang:element(6, P@3) of {parameter_schema, {inline, {array_schema, _, _, _, _, _}}} -> true; {parameter_schema, {reference, _, _} = Sr} -> case oaspec@openapi@resolver:resolve_schema_ref( Sr, erlang:element(2, Ctx) ) of {ok, {array_schema, _, _, _, _, _}} -> true; _ -> false end; _ -> false end end ), Needs_dyn_decode = gleam@list:any( Operations, fun(Op@3) -> {_, Operation@3, _, _} = Op@3, gleam@list:any( maps:to_list(erlang:element(8, Operation@3)), fun(Entry@1) -> {_, Ref_or@1} = Entry@1, case Ref_or@1 of {value, Response@1} -> gleam@list:any( maps:to_list(erlang:element(3, Response@1)), fun(Ce@1) -> {Media_type_name, Mt} = Ce@1, case Media_type_name of <<"text/plain"/utf8>> -> false; _ -> case erlang:element(2, Mt) of {some, {inline, {array_schema, _, {inline, _}, _, _, _}}} -> true; {some, {inline, {string_schema, _, _, _, _, _, _}}} -> true; {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> true; {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> true; {some, {inline, {boolean_schema, _}}} -> true; _ -> false end end end ); _ -> false end end ) end ), Needs_json = Needs_dyn_decode orelse gleam@list:any( Operations, fun(Op@4) -> {_, Operation@4, _, _} = Op@4, case erlang:element(7, Operation@4) of {some, {value, Rb@1}} -> gleam@list:any( maps:to_list(erlang:element(3, Rb@1)), fun(Ce@2) -> {_, Mt@1} = Ce@2, case erlang:element(2, Mt@1) of {some, {inline, {string_schema, _, _, _, _, _, _}}} -> true; {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> true; {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> true; {some, {inline, {boolean_schema, _}}} -> true; _ -> false end end ); _ -> false end end ), Needs_string = (((Has_multi_content_response orelse Has_form_urlencoded) orelse gleam@list:any( Operations, fun(Op@5) -> {_, Operation@5, _, _} = Op@5, not gleam@list:is_empty(erlang:element(6, Operation@5)) end )) orelse gleam@list:any( Operations, fun(Op@6) -> {_, Operation@6, _, _} = Op@6, case erlang:element(7, Operation@6) of {some, {value, Rb@2}} -> gleam@list:any( maps:to_list(erlang:element(3, Rb@2)), fun(Ce@3) -> {Key@1, _} = Ce@3, Key@1 =:= <<"multipart/form-data"/utf8>> end ); _ -> false end end )) orelse begin Security_schemes = case erlang:element(5, erlang:element(2, Ctx)) of {some, C} -> maps:to_list(erlang:element(6, C)); _ -> [] end, gleam@list:any(Security_schemes, fun(Entry@2) -> case Entry@2 of {_, {value, {api_key_scheme, _, scheme_in_query}}} -> true; _ -> false end end) end, Needs_typed_schemas = oaspec@codegen@import_analysis:operations_need_typed_schemas( Operations ), Needs_option = oaspec@codegen@import_analysis:operations_have_optional_params( Operations ) orelse begin Security_schemes@1 = case erlang:element(5, erlang:element(2, Ctx)) of {some, C@1} -> maps:to_list(erlang:element(6, C@1)); _ -> [] end, not gleam@list:is_empty(Security_schemes@1) end, Base_imports = [<<"gleam/http/request"/utf8>>, <<"gleam/http"/utf8>>, <<"gleam/int"/utf8>>, <<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/decode"/utf8>>, <<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/response_types"/utf8>>], Base_imports@1 = case Needs_option of true -> [<<"gleam/option.{type Option, None, Some}"/utf8>> | Base_imports]; false -> Base_imports end, Base_imports@2 = case Needs_typed_schemas of true -> lists:append( [<<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/types"/utf8>>, <<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/encode"/utf8>>], Base_imports@1 ); false -> Base_imports@1 end, Base_imports@3 = case Needs_string of true -> [<<"gleam/string"/utf8>> | Base_imports@2]; false -> Base_imports@2 end, Imports = case Needs_dyn_decode of true -> [<<"gleam/dynamic/decode as dyn_decode"/utf8>> | Base_imports@3]; false -> Base_imports@3 end, Imports@1 = case Needs_json of true -> [<<"gleam/json"/utf8>> | Imports]; false -> Imports end, Imports@2 = case Needs_bool of true -> [<<"gleam/bool"/utf8>> | Imports@1]; false -> Imports@1 end, Imports@3 = case Needs_float of true -> [<<"gleam/float"/utf8>> | Imports@2]; false -> Imports@2 end, Imports@4 = case Needs_list of true -> [<<"gleam/list"/utf8>> | Imports@3]; false -> Imports@3 end, Needs_uri = Has_form_urlencoded orelse gleam@list:any( Operations, fun(Op@7) -> {_, Operation@7, _, _} = Op@7, not gleam@list:is_empty(erlang:element(6, Operation@7)) end ), Imports@5 = case Needs_uri of true -> [<<"gleam/uri"/utf8>> | Imports@4]; false -> Imports@4 end, Has_cookie_api_key = case erlang:element(5, erlang:element(2, Ctx)) of {some, C@2} -> gleam@list:any( maps:to_list(erlang:element(6, C@2)), fun(Entry@3) -> case Entry@3 of {_, {value, {api_key_scheme, _, scheme_in_cookie}}} -> true; _ -> false end end ); _ -> false end, Imports@7 = case Has_cookie_api_key of true -> Imports@6 = case Needs_list of true -> Imports@5; false -> [<<"gleam/list"/utf8>> | Imports@5] end, [<<"gleam/result"/utf8>> | Imports@6]; false -> Imports@5 end, Needs_guards = erlang:element(7, erlang:element(3, Ctx)) andalso gleam@list:any( Operations, fun(Op@8) -> {_, Operation@8, _, _} = Op@8, case erlang:element(7, Operation@8) of {some, {value, Rb@3}} -> Content_entries = maps:to_list(erlang:element(3, Rb@3)), case Content_entries of [{_, Mt@2}] -> case erlang:element(2, Mt@2) of {some, {reference, _, Name}} -> oaspec@codegen@guards:schema_has_validator( Name, Ctx ); _ -> false end; _ -> false end; _ -> false end end ), Imports@8 = case Needs_guards of true -> [<<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/guards"/utf8>> | Imports@7]; false -> Imports@7 end, Sb = begin _pipe = oaspec@util@string_extra:file_header(<<"0.12.0"/utf8>>), oaspec@util@string_extra:imports(_pipe, Imports@8) end, Security_schemes@2 = case erlang:element(5, erlang:element(2, Ctx)) of {some, Components} -> oaspec@codegen@ir_build:sorted_entries( erlang:element(6, Components) ); _ -> [] end, Sb@1 = begin _pipe@1 = Sb, _pipe@2 = oaspec@util@string_extra:doc_comment( _pipe@1, <<"HTTP client configuration."/utf8>> ), _pipe@3 = oaspec@util@string_extra:line( _pipe@2, <<"pub type ClientConfig {"/utf8>> ), _pipe@4 = oaspec@util@string_extra:indent( _pipe@3, 1, <<"ClientConfig("/utf8>> ), _pipe@5 = oaspec@util@string_extra:indent( _pipe@4, 2, <<"base_url: String,"/utf8>> ), oaspec@util@string_extra:indent( _pipe@5, 2, <<"send: fn(request.Request(String)) -> Result(ClientResponse, ClientError),"/utf8>> ) end, Sb@3 = gleam@list:fold( Security_schemes@2, Sb@1, fun(Sb@2, Entry@4) -> {Scheme_name, _} = Entry@4, Field_name = oaspec@util@naming:to_snake_case(Scheme_name), _pipe@6 = Sb@2, oaspec@util@string_extra:indent( _pipe@6, 2, <> ) end ), Sb@4 = begin _pipe@7 = Sb@3, _pipe@8 = oaspec@util@string_extra:indent(_pipe@7, 1, <<")"/utf8>>), _pipe@9 = oaspec@util@string_extra:line(_pipe@8, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@9) end, Sb@5 = begin _pipe@10 = Sb@4, _pipe@11 = oaspec@util@string_extra:doc_comment( _pipe@10, <<"Raw HTTP response from the server."/utf8>> ), _pipe@12 = oaspec@util@string_extra:line( _pipe@11, <<"pub type ClientResponse {"/utf8>> ), _pipe@13 = oaspec@util@string_extra:indent( _pipe@12, 1, <<"ClientResponse("/utf8>> ), _pipe@14 = oaspec@util@string_extra:indent( _pipe@13, 2, <<"status: Int,"/utf8>> ), _pipe@15 = oaspec@util@string_extra:indent( _pipe@14, 2, <<"body: String,"/utf8>> ), _pipe@16 = oaspec@util@string_extra:indent(_pipe@15, 1, <<")"/utf8>>), _pipe@17 = oaspec@util@string_extra:line(_pipe@16, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@17) end, Sb@6 = begin _pipe@18 = Sb@5, _pipe@19 = oaspec@util@string_extra:doc_comment( _pipe@18, <<"HTTP client errors."/utf8>> ), _pipe@20 = oaspec@util@string_extra:line( _pipe@19, <<"pub type ClientError {"/utf8>> ), _pipe@21 = oaspec@util@string_extra:indent( _pipe@20, 1, <<"ConnectionError(detail: String)"/utf8>> ), _pipe@22 = oaspec@util@string_extra:indent( _pipe@21, 1, <<"TimeoutError"/utf8>> ), oaspec@util@string_extra:indent( _pipe@22, 1, <<"DecodeError(detail: String)"/utf8>> ) end, Sb@7 = case erlang:element(7, erlang:element(3, Ctx)) of true -> _pipe@23 = Sb@6, oaspec@util@string_extra:indent( _pipe@23, 1, <<"ValidationError(errors: List(String))"/utf8>> ); false -> Sb@6 end, Sb@8 = begin _pipe@24 = Sb@7, _pipe@25 = oaspec@util@string_extra:line(_pipe@24, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@25) end, Sb@9 = begin _pipe@26 = Sb@8, _pipe@27 = oaspec@util@string_extra:doc_comment( _pipe@26, <<"Create a new client configuration."/utf8>> ), _pipe@28 = oaspec@util@string_extra:line( _pipe@27, <<"pub fn new("/utf8>> ), _pipe@29 = oaspec@util@string_extra:indent( _pipe@28, 1, <<"base_url: String,"/utf8>> ), _pipe@30 = oaspec@util@string_extra:indent( _pipe@29, 1, <<"send: fn(request.Request(String)) -> Result(ClientResponse, ClientError),"/utf8>> ), _pipe@31 = oaspec@util@string_extra:line( _pipe@30, <<") -> ClientConfig {"/utf8>> ), oaspec@util@string_extra:indent( _pipe@31, 1, <<"ClientConfig(base_url:, send:,"/utf8>> ) end, Sb@11 = gleam@list:fold( Security_schemes@2, Sb@9, fun(Sb@10, Entry@5) -> {Scheme_name@1, _} = Entry@5, Field_name@1 = oaspec@util@naming:to_snake_case(Scheme_name@1), _pipe@32 = Sb@10, oaspec@util@string_extra:indent( _pipe@32, 2, <> ) end ), Sb@12 = begin _pipe@33 = Sb@11, _pipe@34 = oaspec@util@string_extra:indent(_pipe@33, 1, <<")"/utf8>>), _pipe@35 = oaspec@util@string_extra:line(_pipe@34, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@35) end, Sb@13 = generate_with_helpers(Sb@12, Security_schemes@2), Sb@14 = generate_default_base_url(Sb@13, Ctx), Sb@16 = gleam@list:fold( Operations, Sb@14, fun(Sb@15, Op@9) -> {Op_id, Operation@9, Path, Method} = Op@9, generate_client_function( Sb@15, Op_id, Operation@9, Path, Method, Ctx ) end ), oaspec@util@string_extra:to_string(Sb@16). -file("src/oaspec/codegen/client.gleam", 21). ?DOC(" Generate client SDK files.\n"). -spec generate(oaspec@codegen@context:context()) -> list(oaspec@codegen@context:generated_file()). generate(Ctx) -> Client_content = generate_client(Ctx), [{generated_file, <<"client.gleam"/utf8>>, Client_content, client_target}].