-module(oaspec@internal@codegen@server). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/internal/codegen/server.gleam"). -export([generate/1]). -export_type([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 header_spec() :: {header_spec, binary(), binary(), binary(), boolean()}. -file("src/oaspec/internal/codegen/server.gleam", 137). ?DOC(false). -spec generate_handler_delegator( gleam@string_tree:string_tree(), binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()) ) -> gleam@string_tree:string_tree(). generate_handler_delegator(Sb, Op_id, Operation) -> Fn_name = oaspec@internal@util@naming:operation_to_function_name(Op_id), Request_type = <<(oaspec@internal@util@naming:schema_to_type_name(Op_id))/binary, "Request"/utf8>>, Response_type = <<(oaspec@internal@util@naming:schema_to_type_name(Op_id))/binary, "Response"/utf8>>, Has_params = not gleam@list:is_empty(erlang:element(6, Operation)) orelse gleam@option:is_some( erlang:element(7, Operation) ), case Has_params of true -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:line( _pipe, <<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(state: handlers.State, req: request_types."/utf8>>/binary, Request_type/binary>>/binary, ") -> response_types."/utf8>>/binary, Response_type/binary>>/binary, " {"/utf8>> ), _pipe@2 = oaspec@internal@util@string_extra:indent( _pipe@1, 1, <<<<"handlers."/utf8, Fn_name/binary>>/binary, "(state, req)"/utf8>> ), _pipe@3 = oaspec@internal@util@string_extra:line( _pipe@2, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@3); false -> _pipe@4 = Sb, _pipe@5 = oaspec@internal@util@string_extra:line( _pipe@4, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(state: handlers.State) -> response_types."/utf8>>/binary, Response_type/binary>>/binary, " {"/utf8>> ), _pipe@6 = oaspec@internal@util@string_extra:indent( _pipe@5, 1, <<<<"handlers."/utf8, Fn_name/binary>>/binary, "(state)"/utf8>> ), _pipe@7 = oaspec@internal@util@string_extra:line( _pipe@6, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@7) end. -file("src/oaspec/internal/codegen/server.gleam", 114). ?DOC(false). -spec generate_handlers_generated( oaspec@internal@codegen@context:context(), list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@openapi@spec:http_method()}) ) -> binary(). generate_handlers_generated(Ctx, Operations) -> Pkg = oaspec@config:package(oaspec@internal@codegen@context:config(Ctx)), Sb = begin _pipe = oaspec@internal@util@string_extra:file_header(<<"0.29.0"/utf8>>), oaspec@internal@util@string_extra:imports( _pipe, [<>, <>, <>] ) end, Sb@2 = gleam@list:fold( Operations, Sb, fun(Sb@1, Op) -> {Op_id, Operation, _, _} = Op, generate_handler_delegator(Sb@1, Op_id, Operation) end ), oaspec@internal@util@string_extra:to_string(Sb@2). -file("src/oaspec/internal/codegen/server.gleam", 181). ?DOC(false). -spec generate_handler( gleam@string_tree:string_tree(), binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_handler(Sb, Op_id, Operation, _) -> Fn_name = oaspec@internal@util@naming:operation_to_function_name(Op_id), Request_type = <<(oaspec@internal@util@naming:schema_to_type_name(Op_id))/binary, "Request"/utf8>>, Response_type = <<(oaspec@internal@util@naming:schema_to_type_name(Op_id))/binary, "Response"/utf8>>, Sb@1 = case erlang:element(3, Operation) of {some, Summary} -> _pipe = Sb, oaspec@internal@util@string_extra:doc_comment(_pipe, Summary); _ -> Sb end, Sb@2 = case erlang:element(4, Operation) of {some, Desc} -> _pipe@1 = Sb@1, oaspec@internal@util@string_extra:doc_comment(_pipe@1, Desc); _ -> Sb@1 end, Has_params = not gleam@list:is_empty(erlang:element(6, Operation)) orelse gleam@option:is_some( erlang:element(7, Operation) ), Sb@3 = case Has_params of true -> _pipe@2 = Sb@2, oaspec@internal@util@string_extra:line( _pipe@2, <<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(state: State, req: request_types."/utf8>>/binary, Request_type/binary>>/binary, ") -> response_types."/utf8>>/binary, Response_type/binary>>/binary, " {"/utf8>> ); false -> _pipe@3 = Sb@2, oaspec@internal@util@string_extra:line( _pipe@3, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(state: State) -> response_types."/utf8>>/binary, Response_type/binary>>/binary, " {"/utf8>> ) end, Sb@4 = begin _pipe@4 = Sb@3, oaspec@internal@util@string_extra:indent( _pipe@4, 1, <<"let _ = state"/utf8>> ) end, Sb@5 = case Has_params of true -> _pipe@5 = Sb@4, oaspec@internal@util@string_extra:indent( _pipe@5, 1, <<"let _ = req"/utf8>> ); false -> Sb@4 end, _pipe@6 = Sb@5, _pipe@7 = oaspec@internal@util@string_extra:indent( _pipe@6, 1, <<<<"panic as \"unimplemented: "/utf8, Fn_name/binary>>/binary, "\""/utf8>> ), _pipe@8 = oaspec@internal@util@string_extra:line(_pipe@7, <<"}"/utf8>>), oaspec@internal@util@string_extra:blank_line(_pipe@8). -file("src/oaspec/internal/codegen/server.gleam", 67). ?DOC(false). -spec generate_handlers( oaspec@internal@codegen@context:context(), list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@openapi@spec:http_method()}) ) -> binary(). generate_handlers(Ctx, Operations) -> Sb = begin _pipe = oaspec@internal@util@string_extra:line( oaspec@internal@util@string_extra:new(), <<"//// Implement these handler functions. This file is emitted once"/utf8>> ), _pipe@1 = oaspec@internal@util@string_extra:line( _pipe, <<"//// by `oaspec generate` and skipped on subsequent runs, so your"/utf8>> ), _pipe@2 = oaspec@internal@util@string_extra:line( _pipe@1, <<"//// edits survive regeneration. Router wiring lives in"/utf8>> ), _pipe@3 = oaspec@internal@util@string_extra:line( _pipe@2, <<"//// `handlers_generated.gleam`, which delegates here."/utf8>> ), _pipe@4 = oaspec@internal@util@string_extra:blank_line(_pipe@3), _pipe@5 = oaspec@internal@util@string_extra:imports( _pipe@4, [<<(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>>] ), _pipe@6 = oaspec@internal@util@string_extra:doc_comment( _pipe@5, <<"Application state passed to every handler."/utf8>> ), _pipe@7 = oaspec@internal@util@string_extra:doc_comment( _pipe@6, <<"Add fields here for DB connections, config, loggers, etc. Construct a value of this type in your `main` and pass it to `router.route` as the first argument."/utf8>> ), _pipe@8 = oaspec@internal@util@string_extra:line( _pipe@7, <<"pub type State {"/utf8>> ), _pipe@9 = oaspec@internal@util@string_extra:indent( _pipe@8, 1, <<"State"/utf8>> ), _pipe@10 = oaspec@internal@util@string_extra:line(_pipe@9, <<"}"/utf8>>), oaspec@internal@util@string_extra:blank_line(_pipe@10) end, Sb@2 = gleam@list:fold( Operations, Sb, fun(Sb@1, Op) -> {Op_id, Operation, _, _} = Op, generate_handler(Sb@1, Op_id, Operation, Ctx) end ), oaspec@internal@util@string_extra:to_string(Sb@2). -file("src/oaspec/internal/codegen/server.gleam", 991). ?DOC(false). -spec route_arg_name(binary(), boolean()) -> binary(). route_arg_name(Name, Used) -> gleam@bool:guard(Used, Name, fun() -> <<"_"/utf8, Name/binary>> end). -file("src/oaspec/internal/codegen/server.gleam", 996). ?DOC(false). -spec generate_cookie_lookup(gleam@string_tree:string_tree()) -> gleam@string_tree:string_tree(). generate_cookie_lookup(Sb) -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:doc_comment( _pipe, <<"Extract a cookie value from the Cookie header."/utf8>> ), _pipe@2 = oaspec@internal@util@string_extra:line( _pipe@1, <<"fn cookie_lookup(headers: Dict(String, String), key: String) -> Result(String, Nil) {"/utf8>> ), _pipe@3 = oaspec@internal@util@string_extra:indent( _pipe@2, 1, <<"case dict.get(headers, \"cookie\") {"/utf8>> ), _pipe@4 = oaspec@internal@util@string_extra:indent( _pipe@3, 2, <<"Ok(raw) ->"/utf8>> ), _pipe@5 = oaspec@internal@util@string_extra:indent( _pipe@4, 3, <<"list.find_map(string.split(raw, \";\"), fn(part) {"/utf8>> ), _pipe@6 = oaspec@internal@util@string_extra:indent( _pipe@5, 4, <<"let trimmed = string.trim(part)"/utf8>> ), _pipe@7 = oaspec@internal@util@string_extra:indent( _pipe@6, 4, <<"case string.split_once(trimmed, on: \"=\") {"/utf8>> ), _pipe@8 = oaspec@internal@util@string_extra:indent( _pipe@7, 5, <<"Ok(#(cookie_key, cookie_value)) ->"/utf8>> ), _pipe@9 = oaspec@internal@util@string_extra:indent( _pipe@8, 6, <<"case string.trim(cookie_key) == key {"/utf8>> ), _pipe@10 = oaspec@internal@util@string_extra:indent( _pipe@9, 7, <<"True -> uri.percent_decode(string.trim(cookie_value))"/utf8>> ), _pipe@11 = oaspec@internal@util@string_extra:indent( _pipe@10, 7, <<"False -> Error(Nil)"/utf8>> ), _pipe@12 = oaspec@internal@util@string_extra:indent( _pipe@11, 6, <<"}"/utf8>> ), _pipe@13 = oaspec@internal@util@string_extra:indent( _pipe@12, 5, <<"Error(_) -> Error(Nil)"/utf8>> ), _pipe@14 = oaspec@internal@util@string_extra:indent( _pipe@13, 4, <<"}"/utf8>> ), _pipe@15 = oaspec@internal@util@string_extra:indent( _pipe@14, 3, <<"})"/utf8>> ), _pipe@16 = oaspec@internal@util@string_extra:indent( _pipe@15, 2, <<"Error(_) -> Error(Nil)"/utf8>> ), _pipe@17 = oaspec@internal@util@string_extra:indent( _pipe@16, 1, <<"}"/utf8>> ), _pipe@18 = oaspec@internal@util@string_extra:line(_pipe@17, <<"}"/utf8>>), oaspec@internal@util@string_extra:blank_line(_pipe@18). -file("src/oaspec/internal/codegen/server.gleam", 1414). ?DOC(false). -spec query_param_explode_array( oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()) ) -> boolean(). query_param_explode_array(P) -> case oaspec@internal@openapi@spec:parameter_schema(P) of {some, {inline, {array_schema, _, _, _, _, _}}} -> case erlang:element(8, P) of {some, false} -> false; _ -> true end; _ -> false end. -file("src/oaspec/internal/codegen/server.gleam", 1494). ?DOC(false). -spec array_int_parse_expr( binary(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()), binary() ) -> binary(). array_int_parse_expr(Raw_var, P, Delim) -> case erlang:element(8, P) of {some, false} -> <<<<<<<<"list.try_map(list.map(string.split("/utf8, Raw_var/binary>>/binary, ", \""/utf8>>/binary, Delim/binary>>/binary, "\"), string.trim), int.parse)"/utf8>>; _ -> <<<<"list.try_map(list.map("/utf8, Raw_var/binary>>/binary, ", string.trim), int.parse)"/utf8>> end. -file("src/oaspec/internal/codegen/server.gleam", 1510). ?DOC(false). -spec array_float_parse_expr( binary(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()), binary() ) -> binary(). array_float_parse_expr(Raw_var, P, Delim) -> case erlang:element(8, P) of {some, false} -> <<<<<<<<"list.try_map(list.map(string.split("/utf8, Raw_var/binary>>/binary, ", \""/utf8>>/binary, Delim/binary>>/binary, "\"), string.trim), float.parse)"/utf8>>; _ -> <<<<"list.try_map(list.map("/utf8, Raw_var/binary>>/binary, ", string.trim), float.parse)"/utf8>> end. -file("src/oaspec/internal/codegen/server.gleam", 1431). ?DOC(false). -spec query_required_open_parse_case( gleam@string_tree:string_tree(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). query_required_open_parse_case(Sb, P, Ctx) -> Raw_var = <<(oaspec@internal@util@naming:to_snake_case(erlang:element(2, P)))/binary, "_raw"/utf8>>, Delim = case erlang:element(7, P) of {some, pipe_delimited_style} -> <<"|"/utf8>>; {some, space_delimited_style} -> <<" "/utf8>>; _ -> <<","/utf8>> end, case oaspec@internal@openapi@spec:parameter_schema(P) of {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 3, <<<<"case int.parse("/utf8, Raw_var/binary>>/binary, ") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed) -> {"/utf8>> ); {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> _pipe@2 = Sb, _pipe@3 = oaspec@internal@util@string_extra:indent( _pipe@2, 3, <<<<"case float.parse("/utf8, Raw_var/binary>>/binary, ") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@3, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed) -> {"/utf8>> ); {some, {inline, {array_schema, _, {inline, {integer_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Parse_expr = array_int_parse_expr(Raw_var, P, Delim), _pipe@4 = Sb, _pipe@5 = oaspec@internal@util@string_extra:indent( _pipe@4, 3, <<<<"case "/utf8, Parse_expr/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@5, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed_list) -> {"/utf8>> ); {some, {inline, {array_schema, _, {inline, {number_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Parse_expr@1 = array_float_parse_expr(Raw_var, P, Delim), _pipe@6 = Sb, _pipe@7 = oaspec@internal@util@string_extra:indent( _pipe@6, 3, <<<<"case "/utf8, Parse_expr@1/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@7, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed_list) -> {"/utf8>> ); {some, Ref} -> case oaspec@internal@codegen@server_request_decode:schema_ref_string_enum( Ref, Ctx ) of {some, {Type_name, Values}} -> _pipe@8 = Sb, _pipe@9 = oaspec@internal@util@string_extra:indent( _pipe@8, 3, <<<<"case "/utf8, (oaspec@internal@codegen@server_request_decode:enum_match_result_expr( Raw_var, Type_name, Values ))/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@9, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed) -> {"/utf8>> ); none -> Sb end; _ -> Sb end. -file("src/oaspec/internal/codegen/server.gleam", 1568). ?DOC(false). -spec single_value_required_open_parse_case( gleam@string_tree:string_tree(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()) ) -> gleam@string_tree:string_tree(). single_value_required_open_parse_case(Sb, P) -> Raw_var = <<(oaspec@internal@util@naming:to_snake_case(erlang:element(2, P)))/binary, "_raw"/utf8>>, case oaspec@internal@openapi@spec:parameter_schema(P) of {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 3, <<<<"case int.parse("/utf8, Raw_var/binary>>/binary, ") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed) -> {"/utf8>> ); {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> _pipe@2 = Sb, _pipe@3 = oaspec@internal@util@string_extra:indent( _pipe@2, 3, <<<<"case float.parse("/utf8, Raw_var/binary>>/binary, ") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@3, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed) -> {"/utf8>> ); {some, {inline, {array_schema, _, {inline, {integer_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> _pipe@4 = Sb, _pipe@5 = oaspec@internal@util@string_extra:indent( _pipe@4, 3, <<<<"case list.try_map(list.map(string.split("/utf8, Raw_var/binary>>/binary, ", \",\"), string.trim), int.parse) {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@5, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed_list) -> {"/utf8>> ); {some, {inline, {array_schema, _, {inline, {number_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> _pipe@6 = Sb, _pipe@7 = oaspec@internal@util@string_extra:indent( _pipe@6, 3, <<<<"case list.try_map(list.map(string.split("/utf8, Raw_var/binary>>/binary, ", \",\"), string.trim), float.parse) {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@7, 4, <<<<"Ok("/utf8, Raw_var/binary>>/binary, "_parsed_list) -> {"/utf8>> ); _ -> Sb end. -file("src/oaspec/internal/codegen/server.gleam", 1659). ?DOC(false). -spec problem_response_expr(integer(), binary()) -> binary(). problem_response_expr(Status, Detail) -> Body = <<<<"\"{\\\"type\\\":\\\"about:blank\\\",\\\"title\\\":\\\""/utf8, Detail/binary>>/binary, "\\\"}\""/utf8>>, <<<<<<<<"ServerResponse(status: "/utf8, (erlang:integer_to_binary(Status))/binary>>/binary, ", body: TextBody("/utf8>>/binary, Body/binary>>/binary, "), headers: [#(\"content-type\", \"application/problem+json\")])"/utf8>>. -file("src/oaspec/internal/codegen/server.gleam", 1527). ?DOC(false). -spec close_query_required_parse_case( gleam@string_tree:string_tree(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). close_query_required_parse_case(Sb, P, Ctx) -> Close = fun(Sb@1) -> _pipe = Sb@1, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 4, <<"}"/utf8>> ), _pipe@2 = oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<"_ -> "/utf8, (problem_response_expr(400, <<"invalid query parameter"/utf8>>))/binary>> ), oaspec@internal@util@string_extra:indent(_pipe@2, 3, <<"}"/utf8>>) end, case oaspec@internal@openapi@spec:parameter_schema(P) of {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> Close(Sb); {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> Close(Sb); {some, {inline, {array_schema, _, {inline, {integer_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Close(Sb); {some, {inline, {array_schema, _, {inline, {number_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Close(Sb); {some, Ref} -> case oaspec@internal@codegen@server_request_decode:schema_ref_string_enum( Ref, Ctx ) of {some, _} -> Close(Sb); none -> Sb end; _ -> Sb end. -file("src/oaspec/internal/codegen/server.gleam", 1610). ?DOC(false). -spec close_single_value_required_parse_case( gleam@string_tree:string_tree(), oaspec@internal@openapi@spec:parameter(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). close_single_value_required_parse_case(Sb, P, Ctx) -> Close = fun(Sb@1) -> _pipe = Sb@1, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 4, <<"}"/utf8>> ), _pipe@2 = oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<"_ -> "/utf8, (problem_response_expr(400, <<"invalid header or cookie"/utf8>>))/binary>> ), oaspec@internal@util@string_extra:indent(_pipe@2, 3, <<"}"/utf8>>) end, case oaspec@internal@openapi@spec:parameter_schema(P) of {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> Close(Sb); {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> Close(Sb); {some, {inline, {array_schema, _, {inline, {integer_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Close(Sb); {some, {inline, {array_schema, _, {inline, {number_schema, _, _, _, _, _, _, _}}, _, _, _}}} -> Close(Sb); {some, Ref} -> case oaspec@internal@codegen@server_request_decode:schema_ref_string_enum( Ref, Ctx ) of {some, _} -> Close(Sb); none -> Sb end; _ -> Sb end. -file("src/oaspec/internal/codegen/server.gleam", 1674). ?DOC(false). -spec close_lookup_case(gleam@string_tree:string_tree()) -> gleam@string_tree:string_tree(). close_lookup_case(Sb) -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:indent(_pipe, 4, <<"}"/utf8>>), _pipe@2 = oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<"_ -> "/utf8, (problem_response_expr(400, <<"missing or invalid parameter"/utf8>>))/binary>> ), oaspec@internal@util@string_extra:indent(_pipe@2, 3, <<"}"/utf8>>). -file("src/oaspec/internal/codegen/server.gleam", 1692). ?DOC(false). -spec operation_needs_guard_validation( oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> boolean(). operation_needs_guard_validation(Operation, Ctx) -> case erlang:element(7, Operation) of {some, {value, Rb}} -> erlang:element(4, Rb) andalso begin Content_entries = maps:to_list(erlang:element(3, Rb)), gleam@list:any( Content_entries, fun(Entry) -> oaspec@internal@util@content_type:is_json_compatible( erlang:element(1, Entry) ) end ) andalso case Content_entries of [{_, Mt}] -> case erlang:element(2, Mt) of {some, {reference, _, Name}} -> oaspec@internal@codegen@guards:schema_has_validator( Name, Ctx ); _ -> false end; _ -> false end end; _ -> false end. -file("src/oaspec/internal/codegen/server.gleam", 1909). ?DOC(false). -spec operations_have_response_headers( list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@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/server.gleam", 2003). ?DOC(false). -spec response_header_field_type( gleam@option:option(oaspec@internal@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/server.gleam", 1981). ?DOC(false). -spec sorted_header_specs( gleam@dict:dict(binary(), oaspec@internal@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/server.gleam", 1927). ?DOC(false). -spec operations_have_response_header_of_type( list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@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/server.gleam", 1948). ?DOC(false). -spec operations_have_optional_response_header( list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@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/server.gleam", 2087). ?DOC(false). -spec append_chunks(binary(), list(binary())) -> binary(). append_chunks(Prefix, Header_chunks) -> case Header_chunks of [] -> Prefix; _ -> case Prefix of <<""/utf8>> -> gleam@string:join(Header_chunks, <<", "/utf8>>); _ -> <<<>/binary, (gleam@string:join(Header_chunks, <<", "/utf8>>))/binary>> end end. -file("src/oaspec/internal/codegen/server.gleam", 2130). ?DOC(false). -spec stringify_header_value(binary(), binary()) -> binary(). stringify_header_value(Field_type, Value_expr) -> case Field_type of <<"Int"/utf8>> -> <<<<"int.to_string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>; <<"Float"/utf8>> -> <<<<"float.to_string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>; <<"Bool"/utf8>> -> <<<<"bool.to_string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>; _ -> Value_expr end. -file("src/oaspec/internal/codegen/server.gleam", 2106). ?DOC(false). -spec header_chunk_expr(header_spec()) -> binary(). header_chunk_expr(Spec) -> Render_value = fun(Value_expr) -> <<<<<<<<"[#(\""/utf8, (erlang:element(2, Spec))/binary>>/binary, "\", "/utf8>>/binary, (stringify_header_value(erlang:element(4, Spec), Value_expr))/binary>>/binary, ")]"/utf8>> end, case erlang:element(5, Spec) of true -> Render_value(<<"hdrs."/utf8, (erlang:element(3, Spec))/binary>>); false -> <<<<<<<<"case hdrs."/utf8, (erlang:element(3, Spec))/binary>>/binary, " { Some(v) -> "/utf8>>/binary, (Render_value(<<"v"/utf8>>))/binary>>/binary, " None -> [] }"/utf8>> end. -file("src/oaspec/internal/codegen/server.gleam", 2064). ?DOC(false). -spec headers_slot_expr(gleam@option:option(binary()), list(header_spec())) -> binary(). headers_slot_expr(Content_type_header, Header_specs) -> Content_type_chunk = case Content_type_header of {some, Media_type_name} -> [<<<<"[#(\"content-type\", \""/utf8, Media_type_name/binary>>/binary, "\")]"/utf8>>]; none -> [] end, Header_chunks = gleam@list:map( Header_specs, fun(Spec) -> header_chunk_expr(Spec) end ), case {Content_type_chunk, Header_chunks} of {[], []} -> <<"[]"/utf8>>; {[Single_chunk], []} -> Single_chunk; {_, _} -> <<<<"list.flatten(["/utf8, (begin _pipe = gleam@string:join( Content_type_chunk, <<", "/utf8>> ), append_chunks(_pipe, Header_chunks) end)/binary>>/binary, "])"/utf8>> end. -file("src/oaspec/internal/codegen/server.gleam", 2022). ?DOC(false). -spec emit_response_arm( gleam@string_tree:string_tree(), binary(), binary(), boolean(), boolean(), binary(), gleam@option:option(binary()), list(header_spec()) ) -> gleam@string_tree:string_tree(). emit_response_arm( Sb, Variant_name, Status_int, Has_data, Has_headers, Body_expr, Content_type_header, Header_specs ) -> Pattern_args = case {Has_data, Has_headers} of {true, true} -> <<"(data, hdrs)"/utf8>>; {true, false} -> <<"(data)"/utf8>>; {false, true} -> <<"(hdrs)"/utf8>>; {false, false} -> <<""/utf8>> end, Headers_expr = headers_slot_expr(Content_type_header, Header_specs), _pipe = Sb, oaspec@internal@util@string_extra:indent( _pipe, 4, <<<<<<<<<<<<<<<<<<"response_types."/utf8, Variant_name/binary>>/binary, Pattern_args/binary>>/binary, " -> ServerResponse(status: "/utf8>>/binary, Status_int/binary>>/binary, ", body: "/utf8>>/binary, Body_expr/binary>>/binary, ", headers: "/utf8>>/binary, Headers_expr/binary>>/binary, ")"/utf8>> ). -file("src/oaspec/internal/codegen/server.gleam", 2140). ?DOC(false). -spec get_encode_function( gleam@option:option(oaspec@internal@openapi@schema:schema_ref()), oaspec@internal@codegen@context:context() ) -> binary(). get_encode_function(Schema_ref, _) -> case Schema_ref of {some, {reference, _, Name}} -> <<<<"encode.encode_"/utf8, (oaspec@internal@util@naming:to_snake_case(Name))/binary>>/binary, "_json"/utf8>>; {some, {inline, {array_schema, _, Items, _, _, _}}} -> case Items of {reference, _, Name@1} -> <<<<"fn(items) { json.array(items, encode.encode_"/utf8, (oaspec@internal@util@naming:to_snake_case(Name@1))/binary>>/binary, "_json) }"/utf8>>; {inline, {string_schema, _, _, _, _, _, _}} -> <<"fn(items) { json.array(items, json.string) }"/utf8>>; {inline, {integer_schema, _, _, _, _, _, _, _}} -> <<"fn(items) { json.array(items, json.int) }"/utf8>>; {inline, {number_schema, _, _, _, _, _, _, _}} -> <<"fn(items) { json.array(items, json.float) }"/utf8>>; {inline, {boolean_schema, _}} -> <<"fn(items) { json.array(items, json.bool) }"/utf8>>; _ -> <<"fn(items) { json.array(items, json.string) }"/utf8>> end; {some, {inline, {string_schema, _, _, _, _, _, _}}} -> <<"json.string"/utf8>>; {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> <<"json.int"/utf8>>; {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> <<"json.float"/utf8>>; {some, {inline, {boolean_schema, _}}} -> <<"json.bool"/utf8>>; _ -> <<"json.string"/utf8>> end. -file("src/oaspec/internal/codegen/server.gleam", 1722). ?DOC(false). -spec generate_response_conversion( gleam@string_tree:string_tree(), binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_response_conversion(Sb, Response_type_name, Operation, Ctx) -> Responses = oaspec@internal@util@http:sort_response_entries( maps:to_list(erlang:element(8, Operation)) ), case gleam@list:is_empty(Responses) of true -> _pipe = Sb, oaspec@internal@util@string_extra:indent( _pipe, 3, <<"ServerResponse(status: 200, body: EmptyBody, headers: [])"/utf8>> ); false -> Sb@1 = begin _pipe@1 = Sb, oaspec@internal@util@string_extra:indent( _pipe@1, 3, <<"case response {"/utf8>> ) end, Sb@3 = gleam@list:fold( Responses, Sb@1, fun(Sb@2, Entry) -> {Status_code, Ref_or} = Entry, case Ref_or of {value, Response} -> Variant_name = <>, Status_int = oaspec@internal@util@http:status_code_to_int( Status_code ), Content_entries = maps:to_list( erlang:element(3, Response) ), Header_specs = sorted_header_specs( erlang:element(4, Response) ), Has_headers = not gleam@list:is_empty(Header_specs), case Content_entries of [] -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ); [{Media_type_name, Media_type}] -> case oaspec@internal@util@content_type:from_string( Media_type_name ) of application_json -> case erlang:element(2, Media_type) of {some, _} -> Encode_fn = get_encode_function( erlang:element( 2, Media_type ), Ctx ), emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<<<"TextBody(json.to_string("/utf8, Encode_fn/binary>>/binary, "(data)))"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end; text_plain -> case erlang:element(2, Media_type) of {some, _} -> emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<"TextBody(data)"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end; application_xml -> case erlang:element(2, Media_type) of {some, _} -> emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<"TextBody(data)"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end; text_xml -> case erlang:element(2, Media_type) of {some, _} -> emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<"TextBody(data)"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end; application_octet_stream -> case erlang:element(2, Media_type) of {some, _} -> emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<"BytesBody(data)"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end; _ -> case erlang:element(2, Media_type) of {some, _} -> Encode_fn@1 = get_encode_function( erlang:element( 2, Media_type ), Ctx ), emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<<<"TextBody(json.to_string("/utf8, Encode_fn@1/binary>>/binary, "(data)))"/utf8>>, {some, Media_type_name}, Header_specs ); none -> emit_response_arm( Sb@2, Variant_name, Status_int, false, Has_headers, <<"EmptyBody"/utf8>>, none, Header_specs ) end end; [{First_media_type, _}, _ | _] -> emit_response_arm( Sb@2, Variant_name, Status_int, true, Has_headers, <<"TextBody(data)"/utf8>>, {some, First_media_type}, Header_specs ) end; _ -> Sb@2 end end ), _pipe@2 = Sb@3, oaspec@internal@util@string_extra:indent(_pipe@2, 3, <<"}"/utf8>>) end. -file("src/oaspec/internal/codegen/server.gleam", 1065). ?DOC(false). -spec generate_safe_request_and_dispatch( gleam@string_tree:string_tree(), binary(), binary(), binary(), binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_safe_request_and_dispatch( Sb, Request_type_name, Response_type_name, Op_id, Fn_name, Operation, _, Ctx ) -> Params = gleam@list:filter_map( erlang:element(6, Operation), fun(R) -> case R of {value, P} -> {ok, P}; _ -> {error, nil} end end ), Deduped_field_names = oaspec@internal@openapi@dedup:dedup_param_field_names( Params ), Params_with_field_names = gleam@list:zip(Params, Deduped_field_names), Path_params_needing_parse = gleam@list:filter( Params, fun(P@1) -> (erlang:element(3, P@1) =:= in_path) andalso oaspec@internal@codegen@server_request_decode:param_needs_result_unwrap( P@1 ) end ), Required_query_params = gleam@list:filter( Params, fun(P@2) -> ((erlang:element(3, P@2) =:= in_query) andalso erlang:element( 5, P@2 )) andalso not oaspec@internal@codegen@server_request_decode:is_deep_object_param( P@2, Ctx ) end ), Required_header_params = gleam@list:filter( Params, fun(P@3) -> (erlang:element(3, P@3) =:= in_header) andalso erlang:element( 5, P@3 ) end ), Required_cookie_params = gleam@list:filter( Params, fun(P@4) -> (erlang:element(3, P@4) =:= in_cookie) andalso erlang:element( 5, P@4 ) end ), Needs_body_guard = case erlang:element(7, Operation) of {some, {value, Rb}} -> erlang:element(4, Rb) andalso gleam@list:any( maps:to_list(erlang:element(3, Rb)), fun(Entry) -> oaspec@internal@util@content_type:is_json_compatible( erlang:element(1, Entry) ) end ); _ -> false end, Sb@2 = gleam@list:fold( Path_params_needing_parse, Sb, fun(Sb@1, P@5) -> Var_name = oaspec@internal@util@naming:to_snake_case( erlang:element(2, P@5) ), Parse_expr = oaspec@internal@codegen@server_request_decode:param_parse_expr( Var_name, P@5 ), _pipe = Sb@1, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 3, <<<<"case "/utf8, Parse_expr/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@1, 4, <<<<"Ok("/utf8, Var_name/binary>>/binary, "_parsed) -> {"/utf8>> ) end ), Sb@4 = gleam@list:fold( Required_query_params, Sb@2, fun(Sb@3, P@6) -> Raw_var = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, P@6) ))/binary, "_raw"/utf8>>, Pattern = case query_param_explode_array(P@6) of true -> <<<<"Ok([_, ..] as "/utf8, Raw_var/binary>>/binary, ")"/utf8>>; false -> <<<<"Ok(["/utf8, Raw_var/binary>>/binary, ", ..])"/utf8>> end, _pipe@2 = Sb@3, _pipe@3 = oaspec@internal@util@string_extra:indent( _pipe@2, 3, <<<<"case dict.get(query, \""/utf8, (erlang:element(2, P@6))/binary>>/binary, "\") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@3, 4, < {"/utf8>> ) end ), Sb@6 = gleam@list:fold( Required_query_params, Sb@4, fun(Sb@5, P@7) -> query_required_open_parse_case(Sb@5, P@7, Ctx) end ), Sb@8 = gleam@list:fold( Required_header_params, Sb@6, fun(Sb@7, P@8) -> Raw_var@1 = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, P@8) ))/binary, "_raw"/utf8>>, Key = string:lowercase(erlang:element(2, P@8)), _pipe@4 = Sb@7, _pipe@5 = oaspec@internal@util@string_extra:indent( _pipe@4, 3, <<<<"case dict.get(headers, \""/utf8, Key/binary>>/binary, "\") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@5, 4, <<<<"Ok("/utf8, Raw_var@1/binary>>/binary, ") -> {"/utf8>> ) end ), Sb@10 = gleam@list:fold( Required_header_params, Sb@8, fun(Sb@9, P@9) -> single_value_required_open_parse_case(Sb@9, P@9) end ), Sb@12 = gleam@list:fold( Required_cookie_params, Sb@10, fun(Sb@11, P@10) -> Raw_var@2 = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, P@10) ))/binary, "_raw"/utf8>>, _pipe@6 = Sb@11, _pipe@7 = oaspec@internal@util@string_extra:indent( _pipe@6, 3, <<<<"case cookie_lookup(headers, \""/utf8, (erlang:element(2, P@10))/binary>>/binary, "\") {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@7, 4, <<<<"Ok("/utf8, Raw_var@2/binary>>/binary, ") -> {"/utf8>> ) end ), Sb@14 = gleam@list:fold( Required_cookie_params, Sb@12, fun(Sb@13, P@11) -> single_value_required_open_parse_case(Sb@13, P@11) end ), Body_schema_ref_name = case erlang:element(7, Operation) of {some, {value, Rb@1}} -> Content_entries = maps:to_list(erlang:element(3, Rb@1)), case Content_entries of [{_, Media_type}] -> case erlang:element(2, Media_type) of {some, {reference, _, Name}} -> {some, Name}; _ -> none end; _ -> none end; _ -> none end, Needs_guard_validation = (oaspec@config:validate( oaspec@internal@codegen@context:config(Ctx) ) andalso Needs_body_guard) andalso (case Body_schema_ref_name of {some, Name@1} -> oaspec@internal@codegen@guards:schema_has_validator(Name@1, Ctx); none -> false end), Sb@15 = case {Needs_body_guard, erlang:element(7, Operation)} of {true, {some, {value, Rb@2}}} -> Content_entries@1 = maps:to_list(erlang:element(3, Rb@2)), case Content_entries@1 of [{_, Media_type@1}] -> case erlang:element(2, Media_type@1) of {some, {reference, _, Name@2}} -> Decode_fn = <<<<"decode.decode_"/utf8, (oaspec@internal@util@naming:to_snake_case( Name@2 ))/binary>>/binary, "(body)"/utf8>>, _pipe@8 = Sb@14, _pipe@9 = oaspec@internal@util@string_extra:indent( _pipe@8, 3, <<<<"case "/utf8, Decode_fn/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@9, 4, <<"Ok(decoded_body) -> {"/utf8>> ); _ -> Decode_fn@1 = <<<<"decode.decode_"/utf8, (oaspec@internal@util@naming:to_snake_case( Op_id ))/binary>>/binary, "_request_body(body)"/utf8>>, _pipe@10 = Sb@14, _pipe@11 = oaspec@internal@util@string_extra:indent( _pipe@10, 3, <<<<"case "/utf8, Decode_fn@1/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@11, 4, <<"Ok(decoded_body) -> {"/utf8>> ) end; _ -> Sb@14 end; {_, _} -> Sb@14 end, Sb@16 = case {Needs_guard_validation, Body_schema_ref_name} of {true, {some, Name@3}} -> Validate_fn = <<<<"guards.validate_"/utf8, (oaspec@internal@util@naming:to_snake_case(Name@3))/binary>>/binary, "(decoded_body)"/utf8>>, _pipe@12 = Sb@15, _pipe@13 = oaspec@internal@util@string_extra:indent( _pipe@12, 3, <<<<"case "/utf8, Validate_fn/binary>>/binary, " {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@13, 4, <<"Ok(decoded_body) -> {"/utf8>> ); {_, _} -> Sb@15 end, Sb@17 = case erlang:element(7, Operation) of {some, {value, Rb@3}} -> case oaspec@internal@codegen@server_request_decode:request_body_uses_form_urlencoded( Rb@3 ) of true -> _pipe@14 = Sb@16, oaspec@internal@util@string_extra:indent( _pipe@14, 3, <<"let form_body = parse_form_body(body)"/utf8>> ); false -> case oaspec@internal@codegen@server_request_decode:request_body_uses_multipart( Rb@3 ) of true -> _pipe@15 = Sb@16, oaspec@internal@util@string_extra:indent( _pipe@15, 3, <<"let multipart_body = parse_multipart_body(body, headers)"/utf8>> ); false -> Sb@16 end end; _ -> Sb@16 end, Sb@18 = begin _pipe@16 = Sb@17, oaspec@internal@util@string_extra:indent( _pipe@16, 3, <<<<"let request = request_types."/utf8, Request_type_name/binary>>/binary, "("/utf8>> ) end, Sb@20 = gleam@list:fold( Params_with_field_names, Sb@18, fun(Sb@19, Entry@1) -> {Param, Field_name} = Entry@1, Trailing = <<","/utf8>>, Value_expr = case erlang:element(3, Param) of in_path -> case oaspec@internal@codegen@server_request_decode:param_needs_result_unwrap( Param ) of true -> <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, Param) ))/binary, "_parsed"/utf8>>; false -> Var_name@1 = oaspec@internal@util@naming:to_snake_case( erlang:element(2, Param) ), oaspec@internal@codegen@server_request_decode:param_parse_expr( Var_name@1, Param ) end; in_query -> Key@1 = erlang:element(2, Param), Raw_var@3 = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, Param) ))/binary, "_raw"/utf8>>, case {oaspec@internal@codegen@server_request_decode:is_deep_object_param( Param, Ctx ), erlang:element(5, Param)} of {true, true} -> oaspec@internal@codegen@server_request_decode:deep_object_required_expr( Key@1, Param, Op_id, Ctx ); {true, false} -> oaspec@internal@codegen@server_request_decode:deep_object_optional_expr( Key@1, Param, Op_id, Ctx ); {false, true} -> oaspec@internal@codegen@server_request_decode:query_required_expr( Raw_var@3, Param, Ctx ); {false, false} -> oaspec@internal@codegen@server_request_decode:query_optional_expr( Key@1, Param, Ctx ) end; in_header -> Key@2 = string:lowercase(erlang:element(2, Param)), Raw_var@4 = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, Param) ))/binary, "_raw"/utf8>>, case erlang:element(5, Param) of true -> oaspec@internal@codegen@server_request_decode:header_required_expr( Raw_var@4, Param ); false -> oaspec@internal@codegen@server_request_decode:header_optional_expr( Key@2, Param ) end; in_cookie -> Key@3 = erlang:element(2, Param), Raw_var@5 = <<(oaspec@internal@util@naming:to_snake_case( erlang:element(2, Param) ))/binary, "_raw"/utf8>>, case erlang:element(5, Param) of true -> oaspec@internal@codegen@server_request_decode:cookie_required_expr( Raw_var@5, Param ); false -> oaspec@internal@codegen@server_request_decode:cookie_optional_expr( Key@3, Param ) end end, _pipe@17 = Sb@19, oaspec@internal@util@string_extra:indent( _pipe@17, 4, <<<<<>/binary, Value_expr/binary>>/binary, Trailing/binary>> ) end ), Sb@21 = case Needs_body_guard of true -> _pipe@18 = Sb@20, oaspec@internal@util@string_extra:indent( _pipe@18, 4, <<"body: decoded_body,"/utf8>> ); false -> case erlang:element(7, Operation) of {some, {value, Rb@4}} -> Body_expr = oaspec@internal@codegen@server_request_decode:generate_body_decode_expr( Rb@4, Op_id, Ctx ), _pipe@19 = Sb@20, oaspec@internal@util@string_extra:indent( _pipe@19, 4, <<<<"body: "/utf8, Body_expr/binary>>/binary, ","/utf8>> ); _ -> Sb@20 end end, Sb@22 = begin _pipe@20 = Sb@21, oaspec@internal@util@string_extra:indent(_pipe@20, 3, <<")"/utf8>>) end, Sb@23 = begin _pipe@21 = Sb@22, _pipe@22 = oaspec@internal@util@string_extra:indent( _pipe@21, 3, <<<<"let response = handlers_generated."/utf8, Fn_name/binary>>/binary, "(app_state, request)"/utf8>> ), generate_response_conversion( _pipe@22, Response_type_name, Operation, Ctx ) end, Sb@24 = case Needs_guard_validation of true -> _pipe@23 = Sb@23, _pipe@24 = oaspec@internal@util@string_extra:indent( _pipe@23, 4, <<"}"/utf8>> ), _pipe@25 = oaspec@internal@util@string_extra:indent( _pipe@24, 4, <<"Error(errors) -> ServerResponse(status: 422, body: TextBody(json.to_string(json.array(errors, guards.validation_failure_to_json))), headers: [#(\"content-type\", \"application/json\")])"/utf8>> ), oaspec@internal@util@string_extra:indent(_pipe@25, 3, <<"}"/utf8>>); false -> Sb@23 end, Sb@25 = case Needs_body_guard of true -> _pipe@26 = Sb@24, _pipe@27 = oaspec@internal@util@string_extra:indent( _pipe@26, 4, <<"}"/utf8>> ), _pipe@28 = oaspec@internal@util@string_extra:indent( _pipe@27, 4, <<"Error(_) -> "/utf8, (problem_response_expr(400, <<"invalid request body"/utf8>>))/binary>> ), oaspec@internal@util@string_extra:indent(_pipe@28, 3, <<"}"/utf8>>); false -> Sb@24 end, Sb@27 = gleam@list:fold( Required_cookie_params, Sb@25, fun(Sb@26, P@12) -> close_single_value_required_parse_case(Sb@26, P@12, Ctx) end ), Sb@29 = gleam@list:fold( Required_cookie_params, Sb@27, fun(Sb@28, _) -> close_lookup_case(Sb@28) end ), Sb@31 = gleam@list:fold( Required_header_params, Sb@29, fun(Sb@30, P@13) -> close_single_value_required_parse_case(Sb@30, P@13, Ctx) end ), Sb@33 = gleam@list:fold( Required_header_params, Sb@31, fun(Sb@32, _) -> close_lookup_case(Sb@32) end ), Sb@35 = gleam@list:fold( Required_query_params, Sb@33, fun(Sb@34, P@14) -> close_query_required_parse_case(Sb@34, P@14, Ctx) end ), Sb@37 = gleam@list:fold( Required_query_params, Sb@35, fun(Sb@36, _) -> close_lookup_case(Sb@36) end ), gleam@list:fold( Path_params_needing_parse, Sb@37, fun(Sb@38, _) -> _pipe@29 = Sb@38, _pipe@30 = oaspec@internal@util@string_extra:indent( _pipe@29, 4, <<"}"/utf8>> ), _pipe@31 = oaspec@internal@util@string_extra:indent( _pipe@30, 4, <<"Error(_) -> "/utf8, (problem_response_expr( 400, <<"invalid path parameter"/utf8>> ))/binary>> ), oaspec@internal@util@string_extra:indent(_pipe@31, 3, <<"}"/utf8>>) end ). -file("src/oaspec/internal/codegen/server.gleam", 1022). ?DOC(false). -spec generate_route_body( gleam@string_tree:string_tree(), binary(), binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), boolean(), oaspec@internal@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_route_body(Sb, Op_id, Fn_name, Operation, Path, Has_params, Ctx) -> Type_name = oaspec@internal@util@naming:schema_to_type_name(Op_id), Response_type_name = <>, case Has_params of false -> _pipe = Sb, _pipe@1 = oaspec@internal@util@string_extra:indent( _pipe, 3, <<<<"let response = handlers_generated."/utf8, Fn_name/binary>>/binary, "(app_state)"/utf8>> ), generate_response_conversion( _pipe@1, Response_type_name, Operation, Ctx ); true -> Request_type_name = <>, generate_safe_request_and_dispatch( Sb, Request_type_name, Response_type_name, Op_id, Fn_name, Operation, Path, Ctx ) end. -file("src/oaspec/internal/codegen/server.gleam", 2202). ?DOC(false). -spec is_path_param(binary()) -> boolean(). is_path_param(Segment) -> case Segment of <<"{"/utf8, _/binary>> -> true; _ -> false end. -file("src/oaspec/internal/codegen/server.gleam", 2210). ?DOC(false). -spec extract_param_name(binary()) -> binary(). extract_param_name(Segment) -> _pipe = Segment, _pipe@1 = gleam@string:replace(_pipe, <<"{"/utf8>>, <<""/utf8>>), gleam@string:replace(_pipe@1, <<"}"/utf8>>, <<""/utf8>>). -file("src/oaspec/internal/codegen/server.gleam", 2181). ?DOC(false). -spec path_to_pattern(binary()) -> binary(). path_to_pattern(Path) -> Segments = begin _pipe = Path, _pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>), gleam@list:filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end) end, Patterns = gleam@list:map(Segments, fun(Seg) -> case is_path_param(Seg) of true -> Param_name = extract_param_name(Seg), oaspec@internal@util@naming:to_snake_case(Param_name); false -> <<<<"\""/utf8, Seg/binary>>/binary, "\""/utf8>> end end), <<<<"["/utf8, (oaspec@internal@util@string_extra:join_with( Patterns, <<", "/utf8>> ))/binary>>/binary, "]"/utf8>>. -file("src/oaspec/internal/codegen/server.gleam", 240). ?DOC(false). -spec generate_router( oaspec@internal@codegen@context:context(), list({binary(), oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()), binary(), oaspec@internal@openapi@spec:http_method()}) ) -> binary(). generate_router(Ctx, Operations) -> 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_nested_form_urlencoded_body = gleam@list:any( Operations, fun(Op@6) -> {_, Operation@6, _, _} = Op@6, case erlang:element(7, Operation@6) 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@7) -> {_, Operation@7, _, _} = Op@7, (gleam@list:any( erlang:element(6, Operation@7), fun(Ref_p@4) -> case Ref_p@4 of {value, P@4} -> oaspec@internal@codegen@server_request_decode:query_schema_needs_int( oaspec@internal@openapi@spec:parameter_schema( P@4 ) ) orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_int( P@4, Ctx ); _ -> false end end ) orelse case erlang:element(7, Operation@7) 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@7) 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@8) -> {_, Operation@8, _, _} = Op@8, (gleam@list:any( erlang:element(6, Operation@8), fun(Ref_p@5) -> case Ref_p@5 of {value, P@5} -> oaspec@internal@codegen@server_request_decode:query_schema_needs_float( oaspec@internal@openapi@spec:parameter_schema( P@5 ) ) orelse oaspec@internal@codegen@server_request_decode:deep_object_param_needs_float( P@5, Ctx ); _ -> false end end ) orelse case erlang:element(7, Operation@8) 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@8) 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@9) -> {_, Operation@9, _, _} = Op@9, gleam@list:any( erlang:element(6, Operation@9), 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@internal@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@internal@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@internal@openapi@spec:parameter_schema( P@6 ) ) end; _ -> false end end ) orelse case erlang:element(7, Operation@9) 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@10) -> {_, Operation@10, _, _} = Op@10, gleam@list:any( erlang:element(6, Operation@10), 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@11) -> {_, Operation@11, _, _} = Op@11, gleam@list:any( erlang:element(6, Operation@11), fun(Ref_p@8) -> case Ref_p@8 of {value, P@8} -> case {erlang:element(3, P@8), oaspec@internal@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@12) -> {_, Operation@12, _, _} = Op@12, Has_optional_deep_object_fields = gleam@list:any( erlang:element(6, Operation@12), 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@12 ) 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@12) 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@13) -> {_, Operation@13, _, _} = Op@13, Responses = maps:to_list(erlang:element(8, Operation@13)), gleam@list:any( Responses, 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@14) -> {_, Operation@14, _, _} = Op@14, case erlang:element(7, Operation@14) of {some, {value, Rb@8}} -> gleam@list:any( maps:to_list(erlang:element(3, Rb@8)), fun(Entry@1) -> {Content_type, _} = Entry@1, oaspec@internal@util@content_type:is_json_compatible( Content_type ) end ); _ -> false end end ), Needs_encode = Needs_json, Uses_query = gleam@list:any( Operations, fun(Op@15) -> {_, Operation@15, _, _} = Op@15, gleam@list:any( erlang:element(6, Operation@15), 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@16) -> {_, Operation@16, _, _} = Op@16, gleam@list:any( erlang:element(6, Operation@16), 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@17) -> {_, Operation@17, _, _} = Op@17, gleam@option:is_some(erlang:element(7, Operation@17)) end ), Has_params_ops = gleam@list:any( Operations, fun(Op@18) -> {_, Operation@18, _, _} = Op@18, not gleam@list:is_empty(erlang:element(6, Operation@18)) orelse gleam@option:is_some( erlang:element(7, Operation@18) ) end ), Std_imports = [<<"gleam/dict.{type Dict}"/utf8>>], Std_imports@1 = case Needs_list_import of true -> lists:append(Std_imports, [<<"gleam/list"/utf8>>]); false -> Std_imports end, Std_imports@2 = case Needs_uri_import of true -> lists:append(Std_imports@1, [<<"gleam/uri"/utf8>>]); false -> Std_imports@1 end, Std_imports@3 = case Needs_int of true -> lists:append(Std_imports@2, [<<"gleam/int"/utf8>>]); false -> Std_imports@2 end, Std_imports@4 = case Needs_float of true -> lists:append(Std_imports@3, [<<"gleam/float"/utf8>>]); false -> Std_imports@3 end, Std_imports@5 = case Needs_bool of true -> lists:append(Std_imports@4, [<<"gleam/bool"/utf8>>]); false -> Std_imports@4 end, Std_imports@6 = case Needs_option of true -> lists:append(Std_imports@5, [<<"gleam/option.{None, Some}"/utf8>>]); false -> Std_imports@5 end, Needs_json_for_guards = oaspec@config:validate( oaspec@internal@codegen@context:config(Ctx) ) andalso gleam@list:any( Operations, fun(Op@19) -> {_, Operation@19, _, _} = Op@19, operation_needs_guard_validation(Operation@19, Ctx) end ), Std_imports@7 = case Needs_json orelse Needs_json_for_guards of true -> lists:append(Std_imports@6, [<<"gleam/json"/utf8>>]); false -> Std_imports@6 end, Std_imports@8 = case Needs_string of true -> lists:append(Std_imports@7, [<<"gleam/string"/utf8>>]); false -> Std_imports@7 end, Std_imports@9 = case Has_deep_object_untyped_ap of true -> lists:append(Std_imports@8, [<<"gleam/dynamic"/utf8>>]); false -> Std_imports@8 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>>], Has_enum_ref_params = oaspec@internal@codegen@server_request_decode:operations_have_enum_ref_params( Operations, Ctx ), Pkg_imports@1 = case ((Has_deep_object orelse Has_form_urlencoded_body) orelse Has_multipart_body) orelse Has_enum_ref_params 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 Needs_decode 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 Needs_encode 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 Has_params_ops 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, Needs_guards = oaspec@config:validate( oaspec@internal@codegen@context:config(Ctx) ) andalso gleam@list:any( Operations, fun(Op@20) -> {_, Operation@20, _, _} = Op@20, operation_needs_guard_validation(Operation@20, Ctx) end ), Pkg_imports@5 = case Needs_guards of true -> lists:append( Pkg_imports@4, [<<(oaspec@config:package( oaspec@internal@codegen@context:config(Ctx) ))/binary, "/guards"/utf8>>] ); false -> Pkg_imports@4 end, All_imports = lists:append(Std_imports@9, Pkg_imports@5), Sb = begin _pipe = oaspec@internal@util@string_extra:file_header(<<"0.29.0"/utf8>>), oaspec@internal@util@string_extra:imports(_pipe, All_imports) end, Sb@1 = begin _pipe@1 = Sb, _pipe@2 = oaspec@internal@util@string_extra:doc_comment( _pipe@1, <<"Response body payload — text, raw bytes, or no body. The router emits `BytesBody` for `application/octet-stream` (and other binary content types) so adapters never have to round-trip bytes through a String."/utf8>> ), _pipe@3 = oaspec@internal@util@string_extra:line( _pipe@2, <<"pub type ResponseBody {"/utf8>> ), _pipe@4 = oaspec@internal@util@string_extra:indent( _pipe@3, 1, <<"TextBody(String)"/utf8>> ), _pipe@5 = oaspec@internal@util@string_extra:indent( _pipe@4, 1, <<"BytesBody(BitArray)"/utf8>> ), _pipe@6 = oaspec@internal@util@string_extra:indent( _pipe@5, 1, <<"EmptyBody"/utf8>> ), _pipe@7 = oaspec@internal@util@string_extra:line(_pipe@6, <<"}"/utf8>>), _pipe@8 = oaspec@internal@util@string_extra:blank_line(_pipe@7), _pipe@9 = oaspec@internal@util@string_extra:doc_comment( _pipe@8, <<"A server response with status code, body, and headers."/utf8>> ), _pipe@10 = oaspec@internal@util@string_extra:line( _pipe@9, <<"pub type ServerResponse {"/utf8>> ), _pipe@11 = oaspec@internal@util@string_extra:indent( _pipe@10, 1, <<"ServerResponse(status: Int, body: ResponseBody, headers: List(#(String, String)))"/utf8>> ), _pipe@12 = oaspec@internal@util@string_extra:line( _pipe@11, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@12) end, Sb@2 = case Needs_deep_object_present of true -> _pipe@13 = Sb@1, _pipe@14 = oaspec@internal@util@string_extra:line( _pipe@13, <<"fn deep_object_present(query: Dict(String, List(String)), prefix: String, props: List(String)) -> Bool {"/utf8>> ), _pipe@15 = oaspec@internal@util@string_extra:indent( _pipe@14, 1, <<"list.any(props, fn(prop) { dict.has_key(query, prefix <> \"[\" <> prop <> \"]\") })"/utf8>> ), _pipe@16 = oaspec@internal@util@string_extra:line( _pipe@15, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@16); false -> Sb@1 end, Sb@3 = case Has_deep_object_with_ap of true -> _pipe@17 = Sb@2, _pipe@18 = oaspec@internal@util@string_extra:line( _pipe@17, <<"fn deep_object_present_any(query: Dict(String, List(String)), prefix: String) -> Bool {"/utf8>> ), _pipe@19 = oaspec@internal@util@string_extra:indent( _pipe@18, 1, <<"let prefix_bracket = prefix <> \"[\""/utf8>> ), _pipe@20 = oaspec@internal@util@string_extra:indent( _pipe@19, 1, <<"dict.fold(query, False, fn(found, k, _v) { found || string.starts_with(k, prefix_bracket) })"/utf8>> ), _pipe@21 = oaspec@internal@util@string_extra:line( _pipe@20, <<"}"/utf8>> ), _pipe@22 = oaspec@internal@util@string_extra:blank_line(_pipe@21), _pipe@23 = oaspec@internal@util@string_extra:line( _pipe@22, <<"fn deep_object_additional_properties(query: Dict(String, List(String)), prefix: String, known_props: List(String)) -> Dict(String, List(String)) {"/utf8>> ), _pipe@24 = oaspec@internal@util@string_extra:indent( _pipe@23, 1, <<"let prefix_bracket = prefix <> \"[\""/utf8>> ), _pipe@25 = oaspec@internal@util@string_extra:indent( _pipe@24, 1, <<"let prefix_len = string.length(prefix_bracket)"/utf8>> ), _pipe@26 = oaspec@internal@util@string_extra:indent( _pipe@25, 1, <<"dict.fold(query, dict.new(), fn(acc, k, v) {"/utf8>> ), _pipe@27 = oaspec@internal@util@string_extra:indent( _pipe@26, 2, <<"case string.starts_with(k, prefix_bracket) && string.ends_with(k, \"]\") {"/utf8>> ), _pipe@28 = oaspec@internal@util@string_extra:indent( _pipe@27, 3, <<"True -> {"/utf8>> ), _pipe@29 = oaspec@internal@util@string_extra:indent( _pipe@28, 4, <<"let prop = string.slice(k, prefix_len, string.length(k) - prefix_len - 1)"/utf8>> ), _pipe@30 = oaspec@internal@util@string_extra:indent( _pipe@29, 4, <<"case list.contains(known_props, prop) { True -> acc False -> dict.insert(acc, prop, v) }"/utf8>> ), _pipe@31 = oaspec@internal@util@string_extra:indent( _pipe@30, 3, <<"}"/utf8>> ), _pipe@32 = oaspec@internal@util@string_extra:indent( _pipe@31, 3, <<"False -> acc"/utf8>> ), _pipe@33 = oaspec@internal@util@string_extra:indent( _pipe@32, 2, <<"}"/utf8>> ), _pipe@34 = oaspec@internal@util@string_extra:indent( _pipe@33, 1, <<"})"/utf8>> ), _pipe@35 = oaspec@internal@util@string_extra:line( _pipe@34, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@35); false -> Sb@2 end, Sb@4 = case Has_deep_object_untyped_ap of true -> _pipe@36 = Sb@3, _pipe@37 = oaspec@internal@util@string_extra:line( _pipe@36, <<"@external(erlang, \"gleam_stdlib\", \"identity\")"/utf8>> ), _pipe@38 = oaspec@internal@util@string_extra:line( _pipe@37, <<"fn coerce_dict(value: Dict(String, List(String))) -> Dict(String, dynamic.Dynamic)"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@38); false -> Sb@3 end, Sb@5 = case Has_form_urlencoded_body of true -> _pipe@39 = Sb@4, _pipe@40 = oaspec@internal@util@string_extra:line( _pipe@39, <<"fn form_url_decode(value: String) -> String {"/utf8>> ), _pipe@41 = oaspec@internal@util@string_extra:indent( _pipe@40, 1, <<"let value = string.replace(value, \"+\", \" \")"/utf8>> ), _pipe@42 = oaspec@internal@util@string_extra:indent( _pipe@41, 1, <<"case uri.percent_decode(value) { Ok(decoded) -> decoded Error(_) -> value }"/utf8>> ), _pipe@43 = oaspec@internal@util@string_extra:line( _pipe@42, <<"}"/utf8>> ), _pipe@44 = oaspec@internal@util@string_extra:blank_line(_pipe@43), _pipe@45 = oaspec@internal@util@string_extra:line( _pipe@44, <<"fn parse_form_body(body: String) -> Dict(String, List(String)) {"/utf8>> ), _pipe@46 = oaspec@internal@util@string_extra:indent( _pipe@45, 1, <<"let parts = case body { \"\" -> [] _ -> string.split(body, \"&\") }"/utf8>> ), _pipe@47 = oaspec@internal@util@string_extra:indent( _pipe@46, 1, <<"list.fold(parts, dict.new(), fn(acc, part) {"/utf8>> ), _pipe@48 = oaspec@internal@util@string_extra:indent( _pipe@47, 2, <<"case part {"/utf8>> ), _pipe@49 = oaspec@internal@util@string_extra:indent( _pipe@48, 3, <<"\"\" -> acc"/utf8>> ), _pipe@50 = oaspec@internal@util@string_extra:indent( _pipe@49, 3, <<"_ ->"/utf8>> ), _pipe@51 = oaspec@internal@util@string_extra:indent( _pipe@50, 4, <<"case string.split_once(part, on: \"=\") {"/utf8>> ), _pipe@52 = oaspec@internal@util@string_extra:indent( _pipe@51, 5, <<"Ok(#(raw_key, raw_value)) -> {"/utf8>> ), _pipe@53 = oaspec@internal@util@string_extra:indent( _pipe@52, 6, <<"let key = form_url_decode(raw_key)"/utf8>> ), _pipe@54 = oaspec@internal@util@string_extra:indent( _pipe@53, 6, <<"let value = form_url_decode(raw_value)"/utf8>> ), _pipe@55 = oaspec@internal@util@string_extra:indent( _pipe@54, 6, <<"case dict.get(acc, key) {"/utf8>> ), _pipe@56 = oaspec@internal@util@string_extra:indent( _pipe@55, 7, <<"Ok(existing) -> dict.insert(acc, key, list.append(existing, [value]))"/utf8>> ), _pipe@57 = oaspec@internal@util@string_extra:indent( _pipe@56, 7, <<"Error(_) -> dict.insert(acc, key, [value])"/utf8>> ), _pipe@58 = oaspec@internal@util@string_extra:indent( _pipe@57, 6, <<"}"/utf8>> ), _pipe@59 = oaspec@internal@util@string_extra:indent( _pipe@58, 5, <<"}"/utf8>> ), _pipe@60 = oaspec@internal@util@string_extra:indent( _pipe@59, 5, <<"Error(_) -> {"/utf8>> ), _pipe@61 = oaspec@internal@util@string_extra:indent( _pipe@60, 6, <<"let key = form_url_decode(part)"/utf8>> ), _pipe@62 = oaspec@internal@util@string_extra:indent( _pipe@61, 6, <<"case dict.get(acc, key) {"/utf8>> ), _pipe@63 = oaspec@internal@util@string_extra:indent( _pipe@62, 7, <<"Ok(existing) -> dict.insert(acc, key, list.append(existing, [\"\"]))"/utf8>> ), _pipe@64 = oaspec@internal@util@string_extra:indent( _pipe@63, 7, <<"Error(_) -> dict.insert(acc, key, [\"\"])"/utf8>> ), _pipe@65 = oaspec@internal@util@string_extra:indent( _pipe@64, 6, <<"}"/utf8>> ), _pipe@66 = oaspec@internal@util@string_extra:indent( _pipe@65, 5, <<"}"/utf8>> ), _pipe@67 = oaspec@internal@util@string_extra:indent( _pipe@66, 4, <<"}"/utf8>> ), _pipe@68 = oaspec@internal@util@string_extra:indent( _pipe@67, 2, <<"}"/utf8>> ), _pipe@69 = oaspec@internal@util@string_extra:indent( _pipe@68, 1, <<"})"/utf8>> ), _pipe@70 = oaspec@internal@util@string_extra:line( _pipe@69, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@70); false -> Sb@4 end, Sb@6 = case Has_multipart_body of true -> _pipe@71 = Sb@5, _pipe@72 = oaspec@internal@util@string_extra:line( _pipe@71, <<"fn multipart_boundary(headers: Dict(String, String)) -> Result(String, Nil) {"/utf8>> ), _pipe@73 = oaspec@internal@util@string_extra:indent( _pipe@72, 1, <<"case dict.get(headers, \"content-type\") {"/utf8>> ), _pipe@74 = oaspec@internal@util@string_extra:indent( _pipe@73, 2, <<"Ok(content_type) ->"/utf8>> ), _pipe@75 = oaspec@internal@util@string_extra:indent( _pipe@74, 3, <<"list.find_map(string.split(content_type, \";\"), fn(part) {"/utf8>> ), _pipe@76 = oaspec@internal@util@string_extra:indent( _pipe@75, 4, <<"let trimmed = string.trim(part)"/utf8>> ), _pipe@77 = oaspec@internal@util@string_extra:indent( _pipe@76, 4, <<"case string.starts_with(trimmed, \"boundary=\") {"/utf8>> ), _pipe@78 = oaspec@internal@util@string_extra:indent( _pipe@77, 5, <<"True -> Ok(string.replace(trimmed, \"boundary=\", \"\"))"/utf8>> ), _pipe@79 = oaspec@internal@util@string_extra:indent( _pipe@78, 5, <<"False -> Error(Nil)"/utf8>> ), _pipe@80 = oaspec@internal@util@string_extra:indent( _pipe@79, 4, <<"}"/utf8>> ), _pipe@81 = oaspec@internal@util@string_extra:indent( _pipe@80, 3, <<"})"/utf8>> ), _pipe@82 = oaspec@internal@util@string_extra:indent( _pipe@81, 2, <<"Error(_) -> Error(Nil)"/utf8>> ), _pipe@83 = oaspec@internal@util@string_extra:indent( _pipe@82, 1, <<"}"/utf8>> ), _pipe@84 = oaspec@internal@util@string_extra:line( _pipe@83, <<"}"/utf8>> ), _pipe@85 = oaspec@internal@util@string_extra:blank_line(_pipe@84), _pipe@86 = oaspec@internal@util@string_extra:line( _pipe@85, <<"fn multipart_name(raw_headers: String) -> Result(String, Nil) {"/utf8>> ), _pipe@87 = oaspec@internal@util@string_extra:indent( _pipe@86, 1, <<"list.find_map(string.split(raw_headers, \"\\r\\n\"), fn(line) {"/utf8>> ), _pipe@88 = oaspec@internal@util@string_extra:indent( _pipe@87, 2, <<"case string.contains(line, \"name=\") {"/utf8>> ), _pipe@89 = oaspec@internal@util@string_extra:indent( _pipe@88, 3, <<"True ->"/utf8>> ), _pipe@90 = oaspec@internal@util@string_extra:indent( _pipe@89, 4, <<"list.find_map(string.split(line, \";\"), fn(part) {"/utf8>> ), _pipe@91 = oaspec@internal@util@string_extra:indent( _pipe@90, 5, <<"let trimmed = string.trim(part)"/utf8>> ), _pipe@92 = oaspec@internal@util@string_extra:indent( _pipe@91, 5, <<"case string.starts_with(trimmed, \"name=\") {"/utf8>> ), _pipe@93 = oaspec@internal@util@string_extra:indent( _pipe@92, 6, <<"True -> Ok(string.replace(string.replace(trimmed, \"name=\", \"\"), \"\\\"\", \"\"))"/utf8>> ), _pipe@94 = oaspec@internal@util@string_extra:indent( _pipe@93, 6, <<"False -> Error(Nil)"/utf8>> ), _pipe@95 = oaspec@internal@util@string_extra:indent( _pipe@94, 5, <<"}"/utf8>> ), _pipe@96 = oaspec@internal@util@string_extra:indent( _pipe@95, 4, <<"})"/utf8>> ), _pipe@97 = oaspec@internal@util@string_extra:indent( _pipe@96, 3, <<"False -> Error(Nil)"/utf8>> ), _pipe@98 = oaspec@internal@util@string_extra:indent( _pipe@97, 2, <<"}"/utf8>> ), _pipe@99 = oaspec@internal@util@string_extra:indent( _pipe@98, 1, <<"})"/utf8>> ), _pipe@100 = oaspec@internal@util@string_extra:line( _pipe@99, <<"}"/utf8>> ), _pipe@101 = oaspec@internal@util@string_extra:blank_line(_pipe@100), _pipe@102 = oaspec@internal@util@string_extra:line( _pipe@101, <<"fn parse_multipart_body(body: String, headers: Dict(String, String)) -> Dict(String, List(String)) {"/utf8>> ), _pipe@103 = oaspec@internal@util@string_extra:indent( _pipe@102, 1, <<"case multipart_boundary(headers) {"/utf8>> ), _pipe@104 = oaspec@internal@util@string_extra:indent( _pipe@103, 2, <<"Ok(boundary) -> {"/utf8>> ), _pipe@105 = oaspec@internal@util@string_extra:indent( _pipe@104, 3, <<"let delimiter = \"--\" <> boundary"/utf8>> ), _pipe@106 = oaspec@internal@util@string_extra:indent( _pipe@105, 3, <<"let parts = string.split(body, delimiter)"/utf8>> ), _pipe@107 = oaspec@internal@util@string_extra:indent( _pipe@106, 3, <<"list.fold(parts, dict.new(), fn(acc, part) {"/utf8>> ), _pipe@108 = oaspec@internal@util@string_extra:indent( _pipe@107, 4, <<"let normalized_part = part |> string.remove_prefix(\"\\r\\n\") |> string.remove_suffix(\"\\r\\n\")"/utf8>> ), _pipe@109 = oaspec@internal@util@string_extra:indent( _pipe@108, 4, <<"case normalized_part == \"\" || normalized_part == \"--\" {"/utf8>> ), _pipe@110 = oaspec@internal@util@string_extra:indent( _pipe@109, 5, <<"True -> acc"/utf8>> ), _pipe@111 = oaspec@internal@util@string_extra:indent( _pipe@110, 5, <<"False ->"/utf8>> ), _pipe@112 = oaspec@internal@util@string_extra:indent( _pipe@111, 6, <<"case string.split_once(normalized_part, on: \"\\r\\n\\r\\n\") {"/utf8>> ), _pipe@113 = oaspec@internal@util@string_extra:indent( _pipe@112, 7, <<"Ok(#(raw_part_headers, raw_value)) ->"/utf8>> ), _pipe@114 = oaspec@internal@util@string_extra:indent( _pipe@113, 8, <<"case multipart_name(raw_part_headers) {"/utf8>> ), _pipe@115 = oaspec@internal@util@string_extra:indent( _pipe@114, 9, <<"Ok(name) -> {"/utf8>> ), _pipe@116 = oaspec@internal@util@string_extra:indent( _pipe@115, 10, <<"let value = raw_value"/utf8>> ), _pipe@117 = oaspec@internal@util@string_extra:indent( _pipe@116, 10, <<"case dict.get(acc, name) {"/utf8>> ), _pipe@118 = oaspec@internal@util@string_extra:indent( _pipe@117, 11, <<"Ok(existing) -> dict.insert(acc, name, list.append(existing, [value]))"/utf8>> ), _pipe@119 = oaspec@internal@util@string_extra:indent( _pipe@118, 11, <<"Error(_) -> dict.insert(acc, name, [value])"/utf8>> ), _pipe@120 = oaspec@internal@util@string_extra:indent( _pipe@119, 10, <<"}"/utf8>> ), _pipe@121 = oaspec@internal@util@string_extra:indent( _pipe@120, 9, <<"}"/utf8>> ), _pipe@122 = oaspec@internal@util@string_extra:indent( _pipe@121, 9, <<"Error(_) -> acc"/utf8>> ), _pipe@123 = oaspec@internal@util@string_extra:indent( _pipe@122, 8, <<"}"/utf8>> ), _pipe@124 = oaspec@internal@util@string_extra:indent( _pipe@123, 7, <<"Error(_) -> acc"/utf8>> ), _pipe@125 = oaspec@internal@util@string_extra:indent( _pipe@124, 6, <<"}"/utf8>> ), _pipe@126 = oaspec@internal@util@string_extra:indent( _pipe@125, 4, <<"}"/utf8>> ), _pipe@127 = oaspec@internal@util@string_extra:indent( _pipe@126, 3, <<"})"/utf8>> ), _pipe@128 = oaspec@internal@util@string_extra:indent( _pipe@127, 2, <<"}"/utf8>> ), _pipe@129 = oaspec@internal@util@string_extra:indent( _pipe@128, 2, <<"Error(_) -> dict.new()"/utf8>> ), _pipe@130 = oaspec@internal@util@string_extra:indent( _pipe@129, 1, <<"}"/utf8>> ), _pipe@131 = oaspec@internal@util@string_extra:line( _pipe@130, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@131); false -> Sb@5 end, Sb@7 = case Has_nested_form_urlencoded_body of true -> _pipe@132 = Sb@6, _pipe@133 = oaspec@internal@util@string_extra:line( _pipe@132, <<"fn form_object_present(form_body: Dict(String, List(String)), prefix: String, props: List(String)) -> Bool {"/utf8>> ), _pipe@134 = oaspec@internal@util@string_extra:indent( _pipe@133, 1, <<"list.any(props, fn(prop) { dict.has_key(form_body, prefix <> \"[\" <> prop <> \"]\") })"/utf8>> ), _pipe@135 = oaspec@internal@util@string_extra:line( _pipe@134, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@135); false -> Sb@6 end, Sb@8 = begin _pipe@136 = Sb@7, _pipe@137 = oaspec@internal@util@string_extra:doc_comment( _pipe@136, <<"Route an incoming request to the appropriate handler."/utf8>> ), _pipe@138 = oaspec@internal@util@string_extra:line( _pipe@137, <<<<<<<<<<<<"pub fn route(app_state: handlers.State, method: String, path: List(String), "/utf8, (route_arg_name( <<"query"/utf8>>, Uses_query ))/binary>>/binary, ": Dict(String, List(String)), "/utf8>>/binary, (route_arg_name(<<"headers"/utf8>>, Uses_headers))/binary>>/binary, ": Dict(String, String), "/utf8>>/binary, (route_arg_name(<<"body"/utf8>>, Uses_body))/binary>>/binary, ": String) -> ServerResponse {"/utf8>> ), oaspec@internal@util@string_extra:indent( _pipe@138, 1, <<"case method, path {"/utf8>> ) end, Sb@10 = gleam@list:fold( Operations, Sb@8, fun(Sb@9, Op@21) -> {Op_id, Operation@21, Path, Method} = Op@21, Fn_name = oaspec@internal@util@naming:operation_to_function_name( Op_id ), Method_str = oaspec@internal@openapi@spec:method_to_string(Method), Path_pattern = path_to_pattern(Path), Has_params = not gleam@list:is_empty( erlang:element(6, Operation@21) ) orelse gleam@option:is_some(erlang:element(7, Operation@21)), _pipe@139 = Sb@9, _pipe@140 = oaspec@internal@util@string_extra:indent( _pipe@139, 2, <<<<<<<<"\""/utf8, Method_str/binary>>/binary, "\", "/utf8>>/binary, Path_pattern/binary>>/binary, " -> {"/utf8>> ), _pipe@141 = generate_route_body( _pipe@140, Op_id, Fn_name, Operation@21, Path, Has_params, Ctx ), oaspec@internal@util@string_extra:indent(_pipe@141, 2, <<"}"/utf8>>) end ), Sb@11 = begin _pipe@142 = Sb@10, _pipe@143 = oaspec@internal@util@string_extra:indent( _pipe@142, 2, <<"_, _ -> "/utf8, (problem_response_expr(404, <<"not found"/utf8>>))/binary>> ), _pipe@144 = oaspec@internal@util@string_extra:indent( _pipe@143, 1, <<"}"/utf8>> ), _pipe@145 = oaspec@internal@util@string_extra:line( _pipe@144, <<"}"/utf8>> ), oaspec@internal@util@string_extra:blank_line(_pipe@145) end, Sb@12 = case Needs_cookie_lookup of true -> generate_cookie_lookup(Sb@11); false -> Sb@11 end, oaspec@internal@util@string_extra:to_string(Sb@12). -file("src/oaspec/internal/codegen/server.gleam", 35). ?DOC(false). -spec generate(oaspec@internal@codegen@context:context()) -> list(oaspec@internal@codegen@context:generated_file()). generate(Ctx) -> Operations = oaspec@internal@openapi@operations:collect_operations(Ctx), Handlers_content = generate_handlers(Ctx, Operations), Handlers_generated_content = generate_handlers_generated(Ctx, Operations), Router_content = generate_router(Ctx, Operations), [{generated_file, <<"handlers.gleam"/utf8>>, Handlers_content, server_target, skip_if_exists}, {generated_file, <<"handlers_generated.gleam"/utf8>>, Handlers_generated_content, server_target, overwrite}, {generated_file, <<"router.gleam"/utf8>>, Router_content, server_target, overwrite}].