-module(langfuse_client@client). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/langfuse_client/client.gleam"). -export([new/3, send_get/4]). -export_type([client/0, error/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( " HTTP client for a Langfuse project. Holds the base URL and API key pair\n" " used to authenticate against `/api/public/*` endpoints. Domain-specific\n" " modules (e.g. `langfuse_client/score`) drive the actual requests via `send_get`.\n" "\n" " The pure pieces (types, `new`) compile on both the Erlang and JavaScript\n" " targets; the HTTP-issuing pieces are Erlang-only because they depend on\n" " `gleam_httpc`.\n" ). -type client() :: {client, binary(), binary(), binary()}. -type error() :: {http_error, binary()} | {bad_status, integer(), binary()} | {bad_url, binary()} | {decode_error, gleam@json:decode_error()}. -file("src/langfuse_client/client.gleam", 50). ?DOC( " Build a client. Trailing slashes on `base_url` are stripped so callers\n" " can pass either form.\n" ). -spec new(binary(), binary(), binary()) -> client(). new(Base_url, Public_key, Secret_key) -> gleam@bool:guard( not gleam_stdlib:string_ends_with(Base_url, <<"/"/utf8>>), ({client, Base_url, Public_key, Secret_key}), fun() -> {client, gleam@string:drop_end(Base_url, 1), Public_key, Secret_key} end ). -file("src/langfuse_client/client.gleam", 114). -spec decode_body( gleam@http@response:response(binary()), gleam@dynamic@decode:decoder(FFC) ) -> {ok, FFC} | {error, error()}. decode_body(Resp, Decoder) -> gleam@bool:guard( (erlang:element(2, Resp) < 200) orelse (erlang:element(2, Resp) >= 300), {error, {bad_status, erlang:element(2, Resp), erlang:element(4, Resp)}}, fun() -> _pipe = gleam@json:parse(erlang:element(4, Resp), Decoder), gleam@result:map_error( _pipe, fun(Field@0) -> {decode_error, Field@0} end ) end ). -file("src/langfuse_client/client.gleam", 108). -spec send_raw(gleam@http@request:request(binary())) -> {ok, gleam@http@response:response(binary())} | {error, error()}. send_raw(Req) -> _pipe = gleam@httpc:send(Req), gleam@result:map_error( _pipe, fun(E) -> {http_error, gleam@string:inspect(E)} end ). -file("src/langfuse_client/client.gleam", 102). -spec auth_header(client()) -> binary(). auth_header(Client) -> Creds = <<<<(erlang:element(3, Client))/binary, ":"/utf8>>/binary, (erlang:element(4, Client))/binary>>, <<"Basic "/utf8, (gleam_stdlib:base64_encode(gleam_stdlib:identity(Creds), true))/binary>>. -file("src/langfuse_client/client.gleam", 85). -spec build_request(client(), binary()) -> {ok, gleam@http@request:request(binary())} | {error, error()}. build_request(Client, Path) -> Url = <<(erlang:element(2, Client))/binary, Path/binary>>, gleam@result:'try'( begin _pipe = gleam_stdlib:uri_parse(Url), gleam@result:replace_error(_pipe, {bad_url, Url}) end, fun(Parsed) -> gleam@result:'try'( begin _pipe@1 = gleam@http@request:from_uri(Parsed), gleam@result:replace_error(_pipe@1, {bad_url, Url}) end, fun(Req) -> _pipe@2 = Req, _pipe@3 = gleam@http@request:set_method(_pipe@2, get), _pipe@4 = gleam@http@request:prepend_header( _pipe@3, <<"authorization"/utf8>>, auth_header(Client) ), _pipe@5 = gleam@http@request:prepend_header( _pipe@4, <<"accept"/utf8>>, <<"application/json"/utf8>> ), {ok, _pipe@5} end ) end ). -file("src/langfuse_client/client.gleam", 70). ?DOC(false). -spec send_get( client(), binary(), list({binary(), binary()}), gleam@dynamic@decode:decoder(FEQ) ) -> {ok, FEQ} | {error, error()}. send_get(Client, Path, Query, Decoder) -> gleam@result:'try'( build_request(Client, Path), fun(Req) -> Req@1 = gleam@http@request:set_query(Req, Query), gleam@result:'try'( send_raw(Req@1), fun(Resp) -> decode_body(Resp, Decoder) end ) end ).