-module(libero@codegen). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/libero/codegen.gleam"). -export([module_to_underscored/1, to_pascal_case/1, module_to_mjs_path/2, build_module_alias_map/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(" Cross-cutting naming helpers used by codegen submodules.\n"). -file("src/libero/codegen.gleam", 10). ?DOC( " Convert a Gleam module path like \"shared/discount\" to a flat\n" " underscore-separated alias. e.g. \"shared/discount\" -> \"shared_discount\".\n" ). -spec module_to_underscored(binary()) -> binary(). module_to_underscored(Module_path) -> gleam@string:replace(Module_path, <<"/"/utf8>>, <<"_"/utf8>>). -file("src/libero/codegen.gleam", 15). ?DOC(" Convert a snake_case name to PascalCase.\n"). -spec to_pascal_case(binary()) -> binary(). to_pascal_case(Name) -> _pipe = Name, _pipe@1 = gleam@string:split(_pipe, <<"_"/utf8>>), _pipe@2 = gleam@list:map( _pipe@1, fun(Word) -> case gleam_stdlib:string_pop_grapheme(Word) of {ok, {First, Rest}} -> <<(string:uppercase(First))/binary, Rest/binary>>; {error, nil} -> Word end end ), gleam@string:join(_pipe@2, <<""/utf8>>). -file("src/libero/codegen.gleam", 30). ?DOC( " Convert a Gleam module path to its compiled .mjs bundle path.\n" " The package name is the Gleam package that owns the module (determines\n" " the top-level directory in the JS build output).\n" ). -spec module_to_mjs_path(binary(), binary()) -> binary(). module_to_mjs_path(Module_path, Package) -> <<<<<>/binary, Module_path/binary>>/binary, ".mjs"/utf8>>. -file("src/libero/codegen.gleam", 40). ?DOC( " Build a resolver function that maps a module path to its import alias.\n" " Uses the last segment when unique, or the full underscored path when\n" " two or more modules share the same last segment.\n" ). -spec build_module_alias_map(list(binary())) -> gleam@dict:dict(binary(), binary()). build_module_alias_map(Modules) -> Modules@1 = gleam@list:unique(Modules), Segment_counts = gleam@list:fold( Modules@1, maps:new(), fun(Acc, Module_path) -> Segment = libero@field_type:last_segment(Module_path), Count = case gleam_stdlib:map_get(Acc, Segment) of {ok, N} -> N + 1; {error, nil} -> 1 end, gleam@dict:insert(Acc, Segment, Count) end ), gleam@list:fold( Modules@1, maps:new(), fun(Acc@1, Module_path@1) -> Segment@1 = libero@field_type:last_segment(Module_path@1), Alias = case gleam_stdlib:map_get(Segment_counts, Segment@1) of {ok, N@1} when N@1 > 1 -> module_to_underscored(Module_path@1); _ -> Segment@1 end, gleam@dict:insert(Acc@1, Module_path@1, Alias) end ).