Current section
Files
Jump to
Current section
Files
src/gleamql.erl
-module(gleamql).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/gleamql.gleam").
-export([new/0, set_query/2, set_variable/3, set_host/2, set_path/2, set_header/3, set_default_content_type_header/1, send/2, set_decoder/2]).
-export_type([request/1, graph_q_l_error/0, gql_success/1, gql_errors/0, gql_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(
" Query a GraphQL server with `gleamql`.\n"
"\n"
" ```gleam\n"
" gleamql.new()\n"
" |> gleamql.set_query(country_query)\n"
" |> gleamql.set_variable(\"code\", json.string(\"GB\"))\n"
" |> gleamql.set_host(\"countries.trevorblades.com\")\n"
" |> gleamql.set_path(\"/graphql\")\n"
" |> gleamql.set_header(\"Content-Type\", \"application/json\")\n"
" |> gleamql.set_decoder(dynamic.decode1(\n"
" Data,\n"
" field(\"country\", of: dynamic.decode1(Country, field(\"name\", of: string))),\n"
" ))\n"
" |> gleamql.send(hackney.send)\n"
" ```\n"
"\n"
).
-type request(HHP) :: {request,
gleam@http@request:request(binary()),
gleam@option:option(binary()),
gleam@option:option(list({binary(), gleam@json:json()})),
gleam@option:option(gleam@dynamic@decode:decoder(HHP))}.
-type graph_q_l_error() :: {error_message, binary()} |
{unexpected_status, integer()} |
{unrecognised_response, binary()} |
unknown_error.
-type gql_success(HHQ) :: {success_response, HHQ}.
-type gql_errors() :: {error_response, list(gql_error())}.
-type gql_error() :: {gql_error, binary()}.
-file("src/gleamql.gleam", 63).
?DOC(
" Construct a GleamQL Request\n"
"\n"
" Use with set functions to customise.\n"
).
-spec new() -> request(any()).
new() ->
{request,
begin
_pipe = gleam@http@request:new(),
gleam@http@request:set_method(_pipe, post)
end,
none,
none,
none}.
-file("src/gleamql.gleam", 75).
?DOC(" Set the query of the request\n").
-spec set_query(request(HHT), binary()) -> request(HHT).
set_query(Req, Query) ->
_record = Req,
{request,
erlang:element(2, _record),
{some, Query},
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 85).
?DOC(
" Set a variable that is needed in the request query\n"
"\n"
" ```gleam\n"
" gleamql.set_variable(\"code\", json.string(\"GB\"))\n"
" ```\n"
).
-spec set_variable(request(HHW), binary(), gleam@json:json()) -> request(HHW).
set_variable(Req, Key, Value) ->
Variables = [{Key, Value} |
begin
_pipe = erlang:element(4, Req),
gleam@option:unwrap(_pipe, gleam@list:new())
end],
_record = Req,
{request,
erlang:element(2, _record),
erlang:element(3, _record),
{some, Variables},
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 139).
-spec handle_status_ok(request(HIJ), gleam@http@response:response(binary())) -> {ok,
gleam@option:option(HIJ)} |
{error, graph_q_l_error()}.
handle_status_ok(Req, Resp) ->
case erlang:element(5, Req) of
{some, Decoder} ->
case gleam@json:parse(
erlang:element(4, Resp),
begin
gleam@dynamic@decode:field(
<<"data"/utf8>>,
Decoder,
fun(Data) ->
gleam@dynamic@decode:success(
{success_response, Data}
)
end
)
end
) of
{ok, Response} ->
{ok, {some, erlang:element(2, Response)}};
{error, _} ->
{error, {unrecognised_response, erlang:element(4, Resp)}}
end;
none ->
{ok, none}
end.
-file("src/gleamql.gleam", 158).
-spec handle_status_not_ok(gleam@http@response:response(binary())) -> {ok,
gleam@option:option(any())} |
{error, graph_q_l_error()}.
handle_status_not_ok(Resp) ->
case gleam@json:parse(
erlang:element(4, Resp),
begin
gleam@dynamic@decode:field(
<<"errors"/utf8>>,
gleam@dynamic@decode:list(
begin
gleam@dynamic@decode:field(
<<"message"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Message) ->
gleam@dynamic@decode:success(
{gql_error, Message}
)
end
)
end
),
fun(Errors) ->
gleam@dynamic@decode:success({error_response, Errors})
end
)
end
) of
{ok, Response} ->
case begin
_pipe = erlang:element(2, Response),
gleam@list:first(_pipe)
end of
{ok, Error} ->
{error, {error_message, erlang:element(2, Error)}};
{error, _} ->
{error, {unrecognised_response, erlang:element(4, Resp)}}
end;
{error, _} ->
{error, {unexpected_status, erlang:element(2, Resp)}}
end.
-file("src/gleamql.gleam", 192).
?DOC(
" Set the host of the request.\n"
"\n"
" ```gleam\n"
" gleamql.set_host(\"countries.trevorblades.com\")\n"
" ```\n"
).
-spec set_host(request(HIU), binary()) -> request(HIU).
set_host(Req, Host) ->
_record = Req,
{request,
begin
_pipe = erlang:element(2, Req),
gleam@http@request:set_host(_pipe, Host)
end,
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 206).
?DOC(
" Set the path of the request.\n"
"\n"
" ```gleam\n"
" gleamql.set_path(\"/graphql\")\n"
" ```\n"
).
-spec set_path(request(HIX), binary()) -> request(HIX).
set_path(Req, Path) ->
_record = Req,
{request,
begin
_pipe = erlang:element(2, Req),
gleam@http@request:set_path(_pipe, Path)
end,
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 222).
?DOC(
" Set the header with the given value under the given header key.\n"
"\n"
" If already present, it is replaced.\n"
"\n"
" ```gleam\n"
" gleamql.set_header(\"Content-Type\", \"application/json\")\n"
" ```\n"
).
-spec set_header(request(HJA), binary(), binary()) -> request(HJA).
set_header(Req, Key, Value) ->
_record = Req,
{request,
begin
_pipe = erlang:element(2, Req),
gleam@http@request:set_header(_pipe, Key, Value)
end,
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 238).
?DOC(
" Set the `Content-Type` header to `application/json`\n"
"\n"
" If already present, it is replaced.\n"
"\n"
" ```gleam\n"
" gleamql.set_default_content_type_header()\n"
" ```\n"
).
-spec set_default_content_type_header(request(HJD)) -> request(HJD).
set_default_content_type_header(Req) ->
_record = Req,
{request,
begin
_pipe = erlang:element(2, Req),
gleam@http@request:set_header(
_pipe,
<<"Content-Type"/utf8>>,
<<"application/json"/utf8>>
)
end,
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record)}.
-file("src/gleamql.gleam", 246).
-spec status_is_ok(integer()) -> boolean().
status_is_ok(Status) ->
Status =:= 200.
-file("src/gleamql.gleam", 99).
?DOC(
" Send the built request to a GraphQL server.\n"
"\n"
" A HTTP client is needed to send the request, see https://github.com/gleam-lang/http#client-adapters.\n"
).
-spec send(
request(HHZ),
fun((gleam@http@request:request(binary())) -> {ok,
gleam@http@response:response(binary())} |
{error, any()})
) -> {ok, gleam@option:option(HHZ)} | {error, graph_q_l_error()}.
send(Req, Send) ->
Request = begin
_pipe = erlang:element(2, Req),
gleam@http@request:set_body(
_pipe,
begin
_pipe@4 = gleam@json:object(
[{<<"query"/utf8>>,
begin
_pipe@1 = erlang:element(3, Req),
_pipe@2 = gleam@option:unwrap(
_pipe@1,
<<""/utf8>>
),
gleam@json:string(_pipe@2)
end},
{<<"variables"/utf8>>,
gleam@json:object(
begin
_pipe@3 = erlang:element(4, Req),
gleam@option:unwrap(
_pipe@3,
gleam@list:new()
)
end
)}]
),
gleam@json:to_string(_pipe@4)
end
)
end,
gleam@result:'try'(
begin
_pipe@5 = Request,
_pipe@6 = Send(_pipe@5),
gleam@result:map_error(_pipe@6, fun(_) -> unknown_error end)
end,
fun(Resp) ->
case begin
_pipe@7 = erlang:element(2, Resp),
status_is_ok(_pipe@7)
end of
true ->
handle_status_ok(Req, Resp);
false ->
handle_status_not_ok(Resp)
end
end
).
-file("src/gleamql.gleam", 261).
?DOC(
" Set the decoder that will be used to deserialize the graphql response.\n"
"\n"
" If not given, the response will not be deserialized.\n"
"\n"
" ```gleam\n"
" gleamql.set_decoder(dynamic.decode1(\n"
" Data,\n"
" field(\"country\", of: dynamic.decode1(Country, field(\"name\", of: string))),\n"
" ))\n"
" ```\n"
).
-spec set_decoder(request(HJG), gleam@dynamic@decode:decoder(HJG)) -> request(HJG).
set_decoder(Req, Decoder) ->
_record = Req,
{request,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
{some, Decoder}}.