-module(oaspec@codegen@types). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/codegen/types.gleam"). -export([schema_ref_to_type/2, schema_to_gleam_type/2, merge_allof_schemas/2, collect_operations/1, schema_has_additional_properties/2, schema_has_untyped_additional_properties/2, schema_has_optional_fields/2, schema_ref_is_read_only/2, schema_ref_is_write_only/2, filter_read_only_properties/2, filter_write_only_properties/2, generate/1]). -export_type([merged_all_of/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. -type merged_all_of() :: {merged_all_of, gleam@dict:dict(binary(), oaspec@openapi@schema:schema_ref()), list(binary()), gleam@option:option(oaspec@openapi@schema:schema_ref()), boolean()}. -file("src/oaspec/codegen/types.gleam", 48). ?DOC( " Generate types from component schemas and anonymous types from operations.\n" " Delegates to the IR pipeline: build IR declarations, then render to source.\n" ). -spec generate_types(oaspec@codegen@context:context()) -> binary(). generate_types(Ctx) -> _pipe = oaspec@codegen@ir_build:build_types_module(Ctx), oaspec@codegen@ir_render:render(_pipe). -file("src/oaspec/codegen/types.gleam", 131). ?DOC(" Convert a SchemaRef to a Gleam type string.\n"). -spec schema_ref_to_type( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> binary(). schema_ref_to_type(Ref, _) -> case Ref of {inline, Schema} -> oaspec@codegen@schema_dispatch:schema_type(Schema); {reference, _, Name} -> oaspec@util@naming:schema_to_type_name(Name) end. -file("src/oaspec/codegen/types.gleam", 140). ?DOC( " Convert a schema object to a Gleam type string.\n" " Delegates to schema_dispatch for the centralized type mapping.\n" ). -spec schema_to_gleam_type( oaspec@openapi@schema:schema_object(), oaspec@codegen@context:context() ) -> binary(). schema_to_gleam_type(Schema, _) -> oaspec@codegen@schema_dispatch:schema_type(Schema). -file("src/oaspec/codegen/types.gleam", 71). ?DOC(" Convert a schema to a qualified Gleam type with types. prefix for compound types.\n"). -spec schema_to_gleam_type_qualified( oaspec@openapi@schema:schema_object(), binary(), binary(), oaspec@codegen@context:context() ) -> binary(). schema_to_gleam_type_qualified(Schema_obj, Op_id, Suffix, Ctx) -> case Schema_obj of {array_schema, _, Items, _, _, _} -> case Items of {reference, _, Name} -> <<<<"List(types."/utf8, (oaspec@util@naming:schema_to_type_name(Name))/binary>>/binary, ")"/utf8>>; _ -> schema_to_gleam_type(Schema_obj, Ctx) end; {object_schema, _, _, _, _, _, _, _} -> Type_name = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, Suffix/binary>>, <<"types."/utf8, Type_name/binary>>; {one_of_schema, _, Schemas, _} -> All_refs = gleam@list:all(Schemas, fun(S) -> case S of {reference, _, _} -> true; _ -> false end end), case All_refs of true -> Type_name@1 = <<(oaspec@util@naming:schema_to_type_name( Op_id ))/binary, Suffix/binary>>, <<"types."/utf8, Type_name@1/binary>>; false -> schema_to_gleam_type(Schema_obj, Ctx) end; {any_of_schema, _, Schemas@1, _} -> All_refs@1 = gleam@list:all(Schemas@1, fun(S@1) -> case S@1 of {reference, _, _} -> true; _ -> false end end), case All_refs@1 of true -> Type_name@2 = <<(oaspec@util@naming:schema_to_type_name( Op_id ))/binary, Suffix/binary>>, <<"types."/utf8, Type_name@2/binary>>; false -> schema_to_gleam_type(Schema_obj, Ctx) end; {all_of_schema, _, _} -> Type_name@3 = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, Suffix/binary>>, <<"types."/utf8, Type_name@3/binary>>; _ -> schema_to_gleam_type(Schema_obj, Ctx) end. -file("src/oaspec/codegen/types.gleam", 55). ?DOC( " Convert a SchemaRef to a qualified Gleam type string (with types. prefix).\n" " Used in response_types and request_types where types are in a separate module.\n" ). -spec schema_ref_to_type_qualified( oaspec@openapi@schema:schema_ref(), binary(), binary(), oaspec@codegen@context:context() ) -> binary(). schema_ref_to_type_qualified(Ref, Op_id, Suffix, Ctx) -> case Ref of {inline, Schema_obj} -> schema_to_gleam_type_qualified(Schema_obj, Op_id, Suffix, Ctx); {reference, _, Name} -> <<"types."/utf8, (oaspec@util@naming:schema_to_type_name(Name))/binary>> end. -file("src/oaspec/codegen/types.gleam", 368). ?DOC( " Convert an HTTP status code to a Gleam variant name.\n" " Prefixed with the type name to avoid duplicate constructors across types.\n" ). -spec status_code_to_variant(binary(), binary()) -> binary(). status_code_to_variant(Code, Type_name) -> <>. -file("src/oaspec/codegen/types.gleam", 304). ?DOC(" Generate a response type for an operation.\n"). -spec generate_response_type( gleam@string_tree:string_tree(), binary(), oaspec@openapi@spec:operation(), oaspec@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_response_type(Sb, Op_id, Operation, Ctx) -> Type_name = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, "Response"/utf8>>, Responses = maps:to_list(erlang:element(8, Operation)), case gleam@list:is_empty(Responses) of true -> Sb; false -> Sb@1 = begin _pipe = Sb, oaspec@util@string_extra:line( _pipe, <<<<"pub type "/utf8, Type_name/binary>>/binary, " {"/utf8>> ) end, Sb@3 = gleam@list:fold( Responses, Sb@1, fun(Sb@2, Entry) -> {Status_code, Response} = Entry, Variant_name = status_code_to_variant( Status_code, Type_name ), Content_entries = maps:to_list(erlang:element(3, Response)), case Content_entries of [] -> _pipe@1 = Sb@2, oaspec@util@string_extra:indent( _pipe@1, 1, Variant_name ); [_, _ | _] -> _pipe@2 = Sb@2, oaspec@util@string_extra:indent( _pipe@2, 1, <> ); [{Media_type_name, Media_type}] -> case Media_type_name of <<"text/plain"/utf8>> -> case erlang:element(2, Media_type) of {some, _} -> _pipe@3 = Sb@2, oaspec@util@string_extra:indent( _pipe@3, 1, <> ); none -> _pipe@4 = Sb@2, oaspec@util@string_extra:indent( _pipe@4, 1, Variant_name ) end; <<"application/xml"/utf8>> -> case erlang:element(2, Media_type) of {some, _} -> _pipe@3 = Sb@2, oaspec@util@string_extra:indent( _pipe@3, 1, <> ); none -> _pipe@4 = Sb@2, oaspec@util@string_extra:indent( _pipe@4, 1, Variant_name ) end; <<"text/xml"/utf8>> -> case erlang:element(2, Media_type) of {some, _} -> _pipe@3 = Sb@2, oaspec@util@string_extra:indent( _pipe@3, 1, <> ); none -> _pipe@4 = Sb@2, oaspec@util@string_extra:indent( _pipe@4, 1, Variant_name ) end; <<"application/octet-stream"/utf8>> -> case erlang:element(2, Media_type) of {some, _} -> _pipe@3 = Sb@2, oaspec@util@string_extra:indent( _pipe@3, 1, <> ); none -> _pipe@4 = Sb@2, oaspec@util@string_extra:indent( _pipe@4, 1, Variant_name ) end; _ -> case erlang:element(2, Media_type) of {some, Ref} -> Suffix = <<"Response"/utf8, (oaspec@util@http:status_code_suffix( Status_code ))/binary>>, Inner_type = schema_ref_to_type_qualified( Ref, Op_id, Suffix, Ctx ), _pipe@5 = Sb@2, oaspec@util@string_extra:indent( _pipe@5, 1, <<<<<>/binary, Inner_type/binary>>/binary, ")"/utf8>> ); none -> _pipe@6 = Sb@2, oaspec@util@string_extra:indent( _pipe@6, 1, Variant_name ) end end end end ), _pipe@7 = Sb@3, _pipe@8 = oaspec@util@string_extra:line(_pipe@7, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@8) end. -file("src/oaspec/codegen/types.gleam", 385). ?DOC( " Merge allOf sub-schemas: properties, required, and additionalProperties.\n" " Non-object sub-schemas (primitives, arrays) are included as a synthetic\n" " \"value\" property to preserve their constraints.\n" ). -spec merge_allof_schemas( list(oaspec@openapi@schema:schema_ref()), oaspec@codegen@context:context() ) -> merged_all_of(). merge_allof_schemas(Schemas, Ctx) -> gleam@list:index_fold( Schemas, {merged_all_of, maps:new(), [], none, false}, fun(Acc, S_ref, Idx) -> Resolved = case S_ref of {inline, Obj} -> {ok, Obj}; {reference, _, _} -> oaspec@openapi@resolver:resolve_schema_ref( S_ref, erlang:element(2, Ctx) ) end, case Resolved of {ok, {object_schema, _, Properties, Required, Additional_properties, Additional_properties_untyped, _, _}} -> Merged_ap = case {erlang:element(4, Acc), Additional_properties} of {none, Ap} -> Ap; {Existing, _} -> Existing end, Merged_ap_untyped = erlang:element(5, Acc) orelse Additional_properties_untyped, {merged_all_of, maps:merge(erlang:element(2, Acc), Properties), lists:append(erlang:element(3, Acc), Required), Merged_ap, Merged_ap_untyped}; {ok, Schema_obj} -> Field_name = case Idx of 0 -> <<"value"/utf8>>; N -> <<"value_"/utf8, (erlang:integer_to_binary(N))/binary>> end, {merged_all_of, gleam@dict:insert( erlang:element(2, Acc), Field_name, {inline, Schema_obj} ), [Field_name | erlang:element(3, Acc)], erlang:element(4, Acc), erlang:element(5, Acc)}; _ -> Acc end end ). -file("src/oaspec/codegen/types.gleam", 449). ?DOC(" Collect all operations from the spec with their IDs, paths, and methods.\n"). -spec collect_operations(oaspec@codegen@context:context()) -> list({binary(), oaspec@openapi@spec:operation(), binary(), oaspec@openapi@spec:http_method()}). collect_operations(Ctx) -> Paths = gleam@list:sort( maps:to_list(erlang:element(4, erlang:element(2, Ctx))), fun(A, B) -> gleam@string:compare(erlang:element(1, A), erlang:element(1, B)) end ), gleam@list:flat_map( Paths, fun(Entry) -> {Path, Path_item} = Entry, Ops = [{erlang:element(4, Path_item), get}, {erlang:element(5, Path_item), post}, {erlang:element(6, Path_item), put}, {erlang:element(7, Path_item), delete}, {erlang:element(8, Path_item), patch}, {erlang:element(9, Path_item), head}, {erlang:element(10, Path_item), options}, {erlang:element(11, Path_item), trace}], gleam@list:filter_map( Ops, fun(Op_entry) -> {Maybe_op, Method} = Op_entry, case Maybe_op of {some, Operation} -> Op_param_keys = gleam@list:map( erlang:element(6, Operation), fun(P) -> {erlang:element(2, P), erlang:element(3, P)} end ), Inherited_params = gleam@list:filter( erlang:element(12, Path_item), fun(P@1) -> not gleam@list:contains( Op_param_keys, {erlang:element(2, P@1), erlang:element(3, P@1)} ) end ), Merged_params = lists:append( Inherited_params, erlang:element(6, Operation) ), Effective_security = case erlang:element( 10, Operation ) of {some, Sec} -> Sec; none -> erlang:element(7, erlang:element(2, Ctx)) end, Operation@1 = {operation, erlang:element(2, Operation), erlang:element(3, Operation), erlang:element(4, Operation), erlang:element(5, Operation), Merged_params, erlang:element(7, Operation), erlang:element(8, Operation), erlang:element(9, Operation), {some, Effective_security}, erlang:element(11, Operation), erlang:element(12, Operation), erlang:element(13, Operation)}, Op_id = case erlang:element(2, Operation@1) of {some, Id} -> Id; none -> <<<<(oaspec@openapi@spec:method_to_lower( Method ))/binary, "_"/utf8>>/binary, (begin _pipe = gleam@string:replace( Path, <<"/"/utf8>>, <<"_"/utf8>> ), _pipe@1 = gleam@string:replace( _pipe, <<"{"/utf8>>, <<""/utf8>> ), gleam@string:replace( _pipe@1, <<"}"/utf8>>, <<""/utf8>> ) end)/binary>> end, {ok, {Op_id, Operation@1, Path, Method}}; none -> {error, nil} end end ) end ). -file("src/oaspec/codegen/types.gleam", 287). ?DOC(" Generate response types for all operations.\n"). -spec generate_response_types(oaspec@codegen@context:context()) -> binary(). generate_response_types(Ctx) -> Sb = begin _pipe = oaspec@util@string_extra:file_header(<<"0.5.0"/utf8>>), oaspec@util@string_extra:imports( _pipe, [<<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/types"/utf8>>] ) end, Operations = collect_operations(Ctx), Sb@2 = gleam@list:fold( Operations, Sb, fun(Sb@1, Op) -> {Op_id, Operation, _, _} = Op, generate_response_type(Sb@1, Op_id, Operation, Ctx) end ), oaspec@util@string_extra:to_string(Sb@2). -file("src/oaspec/codegen/types.gleam", 514). ?DOC(" Check if a schema has typed or untyped additionalProperties that would need Dict.\n"). -spec schema_has_additional_properties( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_has_additional_properties(Schema_ref, Ctx) -> case Schema_ref of {inline, {object_schema, _, _, _, {some, _}, _, _, _}} -> true; {inline, {object_schema, _, _, _, _, true, _, _}} -> true; {inline, {all_of_schema, _, Schemas}} -> gleam@list:any( Schemas, fun(S) -> schema_has_additional_properties(S, Ctx) end ); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Schema_ref, erlang:element(2, Ctx) ) of {ok, Schema_obj} -> schema_has_additional_properties({inline, Schema_obj}, Ctx); {error, _} -> false end; _ -> false end. -file("src/oaspec/codegen/types.gleam", 534). ?DOC(" Check if a schema has untyped additionalProperties (needs Dynamic import).\n"). -spec schema_has_untyped_additional_properties( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_has_untyped_additional_properties(Schema_ref, Ctx) -> case Schema_ref of {inline, {object_schema, _, _, _, _, true, _, _}} -> true; {inline, {all_of_schema, _, Schemas}} -> gleam@list:any( Schemas, fun(S) -> schema_has_untyped_additional_properties(S, Ctx) end ); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Schema_ref, erlang:element(2, Ctx) ) of {ok, Schema_obj} -> schema_has_untyped_additional_properties( {inline, Schema_obj}, Ctx ); {error, _} -> false end; _ -> false end. -file("src/oaspec/codegen/types.gleam", 579). ?DOC(" Check if a SchemaRef is nullable, resolving $ref if needed.\n"). -spec schema_ref_is_nullable( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_ref_is_nullable(Ref, Ctx) -> case Ref of {inline, S} -> oaspec@openapi@schema:is_nullable(S); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Ref, erlang:element(2, Ctx) ) of {ok, S@1} -> oaspec@openapi@schema:is_nullable(S@1); {error, _} -> false end end. -file("src/oaspec/codegen/types.gleam", 555). ?DOC(" Check if a schema has any optional or nullable fields that would need Option.\n"). -spec schema_has_optional_fields( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_has_optional_fields(Schema_ref, Ctx) -> case Schema_ref of {inline, {object_schema, _, Properties, Required, _, _, _, _}} -> Has_optional = begin _pipe = maps:to_list(Properties), gleam@list:any( _pipe, fun(Entry) -> {Prop_name, Prop_ref} = Entry, not gleam@list:contains(Required, Prop_name) orelse schema_ref_is_nullable( Prop_ref, Ctx ) end ) end, Has_optional; {inline, {all_of_schema, _, Schemas}} -> gleam@list:any( Schemas, fun(S) -> schema_has_optional_fields(S, Ctx) end ); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Schema_ref, erlang:element(2, Ctx) ) of {ok, Schema_obj} -> schema_has_optional_fields({inline, Schema_obj}, Ctx); {error, _} -> false end; _ -> false end. -file("src/oaspec/codegen/types.gleam", 591). ?DOC(" Check if a SchemaRef has readOnly metadata, resolving $ref if needed.\n"). -spec schema_ref_is_read_only( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_ref_is_read_only(Ref, Ctx) -> case Ref of {inline, S} -> erlang:element(6, oaspec@openapi@schema:get_metadata(S)); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Ref, erlang:element(2, Ctx) ) of {ok, S@1} -> erlang:element(6, oaspec@openapi@schema:get_metadata(S@1)); {error, _} -> false end end. -file("src/oaspec/codegen/types.gleam", 603). ?DOC(" Check if a SchemaRef has writeOnly metadata, resolving $ref if needed.\n"). -spec schema_ref_is_write_only( oaspec@openapi@schema:schema_ref(), oaspec@codegen@context:context() ) -> boolean(). schema_ref_is_write_only(Ref, Ctx) -> case Ref of {inline, S} -> erlang:element(7, oaspec@openapi@schema:get_metadata(S)); {reference, _, _} -> case oaspec@openapi@resolver:resolve_schema_ref( Ref, erlang:element(2, Ctx) ) of {ok, S@1} -> erlang:element(7, oaspec@openapi@schema:get_metadata(S@1)); {error, _} -> false end end. -file("src/oaspec/codegen/types.gleam", 616). ?DOC( " Filter readOnly properties from an ObjectSchema for request body context.\n" " Returns a new schema with readOnly properties removed.\n" ). -spec filter_read_only_properties( oaspec@openapi@schema:schema_object(), oaspec@codegen@context:context() ) -> oaspec@openapi@schema:schema_object(). filter_read_only_properties(Schema_obj, Ctx) -> case Schema_obj of {object_schema, Metadata, Properties, Required, Additional_properties, Additional_properties_untyped, Min_properties, Max_properties} -> Filtered_props = gleam@dict:filter( Properties, fun(_, Prop_ref) -> not schema_ref_is_read_only(Prop_ref, Ctx) end ), Filtered_required = gleam@list:filter( Required, fun(Name) -> case gleam_stdlib:map_get(Filtered_props, Name) of {ok, _} -> true; {error, _} -> false end end ), {object_schema, Metadata, Filtered_props, Filtered_required, Additional_properties, Additional_properties_untyped, Min_properties, Max_properties}; _ -> Schema_obj end. -file("src/oaspec/codegen/types.gleam", 657). ?DOC( " Filter writeOnly properties from an ObjectSchema for response body context.\n" " Returns a new schema with writeOnly properties removed.\n" ). -spec filter_write_only_properties( oaspec@openapi@schema:schema_object(), oaspec@codegen@context:context() ) -> oaspec@openapi@schema:schema_object(). filter_write_only_properties(Schema_obj, Ctx) -> case Schema_obj of {object_schema, Metadata, Properties, Required, Additional_properties, Additional_properties_untyped, Min_properties, Max_properties} -> Filtered_props = gleam@dict:filter( Properties, fun(_, Prop_ref) -> not schema_ref_is_write_only(Prop_ref, Ctx) end ), Filtered_required = gleam@list:filter( Required, fun(Name) -> case gleam_stdlib:map_get(Filtered_props, Name) of {ok, _} -> true; {error, _} -> false end end ), {object_schema, Metadata, Filtered_props, Filtered_required, Additional_properties, Additional_properties_untyped, Min_properties, Max_properties}; _ -> Schema_obj end. -file("src/oaspec/codegen/types.gleam", 718). ?DOC(" Extract the type for an inline request body schema.\n"). -spec extract_inline_request_body_type( oaspec@openapi@schema:schema_object(), binary(), oaspec@codegen@context:context() ) -> binary(). extract_inline_request_body_type(Schema_obj, Op_id, Ctx) -> case Schema_obj of {object_schema, _, _, _, _, _, _, _} -> Type_name = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, "RequestBody"/utf8>>, <<"types."/utf8, Type_name/binary>>; {all_of_schema, _, _} -> Type_name@1 = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, "RequestBody"/utf8>>, <<"types."/utf8, Type_name@1/binary>>; {string_schema, _, _, _, _, _, _} -> <<"String"/utf8>>; {integer_schema, _, _, _, _, _, _, _} -> <<"Int"/utf8>>; {number_schema, _, _, _, _, _, _, _} -> <<"Float"/utf8>>; {boolean_schema, _} -> <<"Bool"/utf8>>; _ -> schema_to_gleam_type(Schema_obj, Ctx) end. -file("src/oaspec/codegen/types.gleam", 698). ?DOC( " Extract the Gleam type for a request body from its content media types.\n" " Uses types. prefix since request body schemas live in the types module.\n" ). -spec extract_request_body_type( oaspec@openapi@spec:request_body(), binary(), oaspec@codegen@context:context() ) -> binary(). extract_request_body_type(Rb, Op_id, Ctx) -> Content_entries = maps:to_list(erlang:element(3, Rb)), case Content_entries of [{_, Media_type} | _] -> case erlang:element(2, Media_type) of {some, {reference, _, Name}} -> <<"types."/utf8, (oaspec@util@naming:schema_to_type_name(Name))/binary>>; {some, {inline, Schema_obj}} -> extract_inline_request_body_type(Schema_obj, Op_id, Ctx); _ -> <<"String"/utf8>> end; [] -> <<"String"/utf8>> end. -file("src/oaspec/codegen/types.gleam", 211). ?DOC(" Generate a single request type for an operation.\n"). -spec generate_request_type( gleam@string_tree:string_tree(), binary(), oaspec@openapi@spec:operation(), oaspec@codegen@context:context() ) -> gleam@string_tree:string_tree(). generate_request_type(Sb, Op_id, Operation, Ctx) -> Type_name = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary, "Request"/utf8>>, Params = erlang:element(6, Operation), case gleam@list:is_empty(Params) andalso gleam@option:is_none( erlang:element(7, Operation) ) of true -> Sb; false -> Sb@1 = case erlang:element(4, Operation) of {some, Desc} -> _pipe = Sb, oaspec@util@string_extra:doc_comment(_pipe, Desc); none -> Sb end, Sb@2 = begin _pipe@1 = Sb@1, oaspec@util@string_extra:line( _pipe@1, <<<<"pub type "/utf8, Type_name/binary>>/binary, " {"/utf8>> ) end, Sb@3 = begin _pipe@2 = Sb@2, oaspec@util@string_extra:indent( _pipe@2, 1, <> ) end, Sb@5 = gleam@list:index_fold( Params, Sb@3, fun(Sb@4, Param, Idx) -> Field_name = oaspec@util@naming:to_snake_case( erlang:element(2, Param) ), Field_type = case erlang:element(6, Param) of {some, {inline, {string_schema, _, _, _, _, _, _}}} -> <<"String"/utf8>>; {some, {inline, {integer_schema, _, _, _, _, _, _, _}}} -> <<"Int"/utf8>>; {some, {inline, {number_schema, _, _, _, _, _, _, _}}} -> <<"Float"/utf8>>; {some, {inline, {boolean_schema, _}}} -> <<"Bool"/utf8>>; {some, {inline, {array_schema, _, Items, _, _, _}}} -> Item_type = case Items of {inline, {string_schema, _, _, _, _, _, _}} -> <<"String"/utf8>>; {inline, {integer_schema, _, _, _, _, _, _, _}} -> <<"Int"/utf8>>; {inline, {number_schema, _, _, _, _, _, _, _}} -> <<"Float"/utf8>>; {inline, {boolean_schema, _}} -> <<"Bool"/utf8>>; {reference, _, Name} -> oaspec@util@naming:schema_to_type_name(Name); _ -> <<"String"/utf8>> end, <<<<"List("/utf8, Item_type/binary>>/binary, ")"/utf8>>; {some, {reference, _, Name@1}} -> <<"types."/utf8, (oaspec@util@naming:schema_to_type_name(Name@1))/binary>>; _ -> <<"String"/utf8>> end, Final_type = case erlang:element(5, Param) of true -> Field_type; false -> <<<<"Option("/utf8, Field_type/binary>>/binary, ")"/utf8>> end, Has_more = Idx < (erlang:length(Params) - 1), Has_body = gleam@option:is_some( erlang:element(7, Operation) ), Trailing = case Has_more orelse Has_body of true -> <<","/utf8>>; false -> <<""/utf8>> end, _pipe@3 = Sb@4, oaspec@util@string_extra:indent( _pipe@3, 2, <<<<<>/binary, Final_type/binary>>/binary, Trailing/binary>> ) end ), Sb@6 = case erlang:element(7, Operation) of {some, Rb} -> Body_type = extract_request_body_type(Rb, Op_id, Ctx), Wrapped = case erlang:element(4, Rb) of true -> Body_type; false -> <<<<"Option("/utf8, Body_type/binary>>/binary, ")"/utf8>> end, _pipe@4 = Sb@5, oaspec@util@string_extra:indent( _pipe@4, 2, <<"body: "/utf8, Wrapped/binary>> ); none -> Sb@5 end, _pipe@5 = Sb@6, _pipe@6 = oaspec@util@string_extra:indent(_pipe@5, 1, <<")"/utf8>>), _pipe@7 = oaspec@util@string_extra:line(_pipe@6, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@7) end. -file("src/oaspec/codegen/types.gleam", 145). ?DOC(" Generate request types for all operations.\n"). -spec generate_request_types(oaspec@codegen@context:context()) -> binary(). generate_request_types(Ctx) -> Operations = collect_operations(Ctx), Needs_option = gleam@list:any( Operations, fun(Op) -> {_, Operation, _, _} = Op, Has_optional_params = gleam@list:any( erlang:element(6, Operation), fun(P) -> not erlang:element(5, P) end ), Has_optional_body = case erlang:element(7, Operation) of {some, Rb} -> not erlang:element(4, Rb); _ -> false end, Has_optional_params orelse Has_optional_body end ), Needs_types = gleam@list:any( Operations, fun(Op@1) -> {_, Operation@1, _, _} = Op@1, Has_ref_params = gleam@list:any( erlang:element(6, Operation@1), fun(P@1) -> case erlang:element(6, P@1) of {some, {reference, _, _}} -> true; _ -> false end end ), Has_typed_body = case erlang:element(7, Operation@1) of {some, Rb@1} -> gleam@list:any( maps:to_list(erlang:element(3, Rb@1)), fun(Ce) -> {_, Mt} = Ce, case erlang:element(2, Mt) of {some, {reference, _, _}} -> true; {some, {inline, {object_schema, _, _, _, _, _, _, _}}} -> true; {some, {inline, {all_of_schema, _, _}}} -> true; _ -> false end end ); _ -> false end, Has_ref_params orelse Has_typed_body end ), Base_imports = case Needs_types of true -> [<<(erlang:element(5, erlang:element(3, Ctx)))/binary, "/types"/utf8>>]; false -> [] end, Imports = case Needs_option of true -> [<<"gleam/option.{type Option}"/utf8>> | Base_imports]; false -> Base_imports end, Sb = begin _pipe = oaspec@util@string_extra:file_header(<<"0.5.0"/utf8>>), oaspec@util@string_extra:imports(_pipe, Imports) end, Sb@2 = gleam@list:fold( Operations, Sb, fun(Sb@1, Op@2) -> {Op_id, Operation@2, _, _} = Op@2, generate_request_type(Sb@1, Op_id, Operation@2, Ctx) end ), oaspec@util@string_extra:to_string(Sb@2). -file("src/oaspec/codegen/types.gleam", 22). ?DOC(" Generate type definitions from OpenAPI schemas.\n"). -spec generate(oaspec@codegen@context:context()) -> list(oaspec@codegen@context:generated_file()). generate(Ctx) -> Types_content = generate_types(Ctx), Request_types_content = generate_request_types(Ctx), Response_types_content = generate_response_types(Ctx), [{generated_file, <<"types.gleam"/utf8>>, Types_content, shared_target}, {generated_file, <<"request_types.gleam"/utf8>>, Request_types_content, shared_target}, {generated_file, <<"response_types.gleam"/utf8>>, Response_types_content, shared_target}].