Skip to content

Commit

Permalink
feat: make with_query composable and right-associative
Browse files Browse the repository at this point in the history
  • Loading branch information
zoedsoupe committed Jan 5, 2025
1 parent 1fb1e3b commit ec5984c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
24 changes: 16 additions & 8 deletions lib/supabase/fetcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ defmodule Supabase.Fetcher do
url: Finch.Request.url(),
options: Finch.request_opts(),
service: Supabase.service(),
query: map,
body_decoder: module,
error_parser: module
}
Expand All @@ -118,7 +119,7 @@ defmodule Supabase.Fetcher do
:client,
:body,
method: :get,
query: "",
query: %{},
options: [],
headers: %{},
body_decoder: Supabase.Fetcher.JSONDecoder,
Expand Down Expand Up @@ -193,12 +194,16 @@ defmodule Supabase.Fetcher do

@doc """
Append query params to the current request builder, it receives an `Enumerable.t()`
and encodes it to string with `URI.encode_query/1`. Note that this function
overwrite the `query` attribute each time is called.
and accumulates it into the current request. This function behaves the same as
`with_headers/2`, so it is **rigt-associative**, meaning that duplicate keys
informed will overwrite the last value.
Finally, before the request is sent, the query will be encoded with `URI.encode_query/1`
"""
@impl true
def with_query(%__MODULE__{} = builder, query) do
%{builder | query: URI.encode_query(query)}
def with_query(%__MODULE__{} = builder, query)
when is_map(query) or is_list(query) do
%{builder | query: merge_headers(builder.query, query)}
end

@doc """
Expand Down Expand Up @@ -241,7 +246,8 @@ defmodule Supabase.Fetcher do
"""
@impl true
def request(%__MODULE__{method: method, headers: headers} = b) do
url = URI.append_query(b.url, b.query)
query = URI.encode_query(b.query)
url = URI.append_query(b.url, query)

method
|> Finch.build(url, headers, b.body)
Expand All @@ -255,7 +261,8 @@ defmodule Supabase.Fetcher do
"""
@impl true
def request_async(%__MODULE__{method: method, headers: headers} = b) do
url = URI.append_query(b.url, b.query)
query = URI.encode_query(b.query)
url = URI.append_query(b.url, query)

ref =
method
Expand Down Expand Up @@ -314,7 +321,8 @@ defmodule Supabase.Fetcher do
"""
@impl true
def stream(%__MODULE__{method: method, headers: headers} = b, on_response \\ nil) do
url = URI.append_query(b.url, b.query)
query = URI.encode_query(b.query)
url = URI.append_query(b.url, query)
req = Finch.build(method, url, headers, b.body)
ref = make_ref()
task = spawn_stream_task(req, ref, b.options)
Expand Down
8 changes: 4 additions & 4 deletions test/supabase/fetcher_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ defmodule Supabase.FetcherTest do
test "appends query parameters", %{client: client} do
fetcher = Fetcher.new(client) |> Fetcher.with_query(%{"key" => "value"})

assert fetcher.query == "key=value"
assert fetcher.query == [{"key", "value"}]
end

test "overwrites existing query parameters", %{client: client} do
test "do not overwrites existing query parameters", %{client: client} do
fetcher =
Fetcher.new(client)
|> Fetcher.with_query(%{"key1" => "value1"})
|> Fetcher.with_query(%{"key2" => "value2"})

assert fetcher.query == "key2=value2"
assert have_headers?(fetcher.query, ["key1", "key2"])
end
end

Expand Down Expand Up @@ -161,7 +161,7 @@ defmodule Supabase.FetcherTest do
assert fetcher.method == :post
assert have_header?(fetcher.headers, "authorization")
assert get_header(fetcher.headers, "authorization") =~ "token"
assert fetcher.query == "key=value"
assert fetcher.query == [{"key", "value"}]
end
end

Expand Down

0 comments on commit ec5984c

Please sign in to comment.