Skip to content

Commit bcdcc5a

Browse files
committed
feat: follow base SDK update
1 parent 26cc513 commit bcdcc5a

File tree

13 files changed

+170
-168
lines changed

13 files changed

+170
-168
lines changed

.github/pull_request_template.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Problem
2+
3+
<!-- what problem is the PR is trying to solve? -->
4+
5+
## Solution
6+
7+
<!-- how is the PR solving the problem? -->
8+
9+
## Rationale
10+
11+
<!-- why was it implemented the way it was? -->

.github/workflows/ci.yml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
lint:
13+
runs-on: ubuntu-latest
14+
15+
strategy:
16+
matrix:
17+
elixir: [1.17.0]
18+
otp: [27.0]
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v3
23+
24+
- name: Set up Elixir
25+
uses: erlef/setup-beam@v1
26+
with:
27+
elixir-version: ${{ matrix.elixir }}
28+
otp-version: ${{ matrix.otp }}
29+
30+
- name: Install dependencies
31+
run: mix deps.get
32+
33+
- name: Clean build
34+
run: mix clean
35+
36+
- name: Check code formatting
37+
run: mix format --check-formatted
38+
39+
- name: Run Credo
40+
run: mix credo --strict

.github/workflows/release.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
env:
9+
MIX_ENV: prod
10+
11+
jobs:
12+
publish:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
elixir: [1.17.0]
17+
otp: [27.0]
18+
steps:
19+
- uses: actions/checkout@v3
20+
- name: Set up Elixir
21+
uses: erlef/setup-beam@v1
22+
with:
23+
elixir-version: ${{ matrix.elixir }}
24+
otp-version: ${{ matrix.otp }}
25+
- name: Publish to Hex
26+
uses: synchronal/hex-publish-action@v3
27+
with:
28+
name: supabase_potion
29+
key: ${{ secrets.HEX_PM_KEY }}
30+
tag-release: true

LICENSE

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2-
Version 2, December 2004
1+
Copyright 2023 zoedsoupe <[email protected]>
32

4-
Copyright (C) 2023 Zoey Pessanha <[email protected]>
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
54

6-
Everyone is permitted to copy and distribute verbatim or modified
7-
copies of this license document, and changing it is allowed as long
8-
as the name is changed.
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
96

10-
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11-
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12-
13-
0. You just DO WHAT THE FUCK YOU WANT TO.
7+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

flake.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
description = "Supabase PostgREST SDK for Elixir";
2+
description = "Supabase SDK for Elixir";
33

44
inputs = {
5-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
5+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
66
flake-parts.url = "github:hercules-ci/flake-parts";
77
systems.url = "github:nix-systems/default";
88
};
@@ -19,9 +19,9 @@
1919
system,
2020
...
2121
}: let
22-
inherit (pkgs.beam.interpreters) erlangR26;
22+
inherit (pkgs.beam.interpreters) erlang_27;
2323
inherit (pkgs.beam) packagesWith;
24-
beam = packagesWith erlangR26;
24+
beam = packagesWith erlang_27;
2525
in {
2626
_module.args.pkgs = import inputs.nixpkgs {
2727
inherit system;
@@ -31,7 +31,7 @@
3131
mkShell {
3232
name = "postgrest-ex";
3333
packages = with pkgs;
34-
[beam.elixir_1_16]
34+
[beam.elixir_1_17]
3535
++ lib.optional stdenv.isLinux [inotify-tools]
3636
++ lib.optional stdenv.isDarwin [
3737
darwin.apple_sdk.frameworks.CoreServices

lib/supabase/postgrest.ex

+37-125
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ defmodule Supabase.PostgREST do
1111

1212
import Kernel, except: [not: 1, and: 2, or: 2, in: 2]
1313

14-
import Supabase.Client, only: [is_client: 1]
15-
14+
alias Supabase.Client
1615
alias Supabase.PostgREST.Error
1716
alias Supabase.PostgREST.FilterBuilder
1817
alias Supabase.PostgREST.QueryBuilder
@@ -34,7 +33,7 @@ defmodule Supabase.PostgREST do
3433
- Supabase documentation on initializing queries: https://supabase.com/docs/reference/javascript/from
3534
"""
3635
@impl true
37-
def from(client, table) when is_client(client) do
36+
def from(%Client{} = client, table) do
3837
QueryBuilder.new(table, client)
3938
end
4039

@@ -102,10 +101,12 @@ defmodule Supabase.PostgREST do
102101
@impl true
103102
def insert(%QueryBuilder{} = q, data, opts \\ []) do
104103
on_conflict = Keyword.get(opts, :on_conflict)
104+
on_conflict = if on_conflict, do: "on_conflict=#{on_conflict}"
105105
upsert = if on_conflict, do: "resolution=merge-duplicates"
106106
returning = Keyword.get(opts, :returning, :representation)
107107
count = Keyword.get(opts, :count, :exact)
108-
prefer = Enum.join([upsert, "return=#{returning}", "count=#{count}"], ",")
108+
prefer = ["return=#{returning}", "count=#{count}", on_conflict, upsert]
109+
prefer = Enum.join(Enum.reject(prefer, &is_nil/1), ",")
109110

110111
case Jason.encode(data) do
111112
{:ok, body} ->
@@ -703,8 +704,7 @@ defmodule Supabase.PostgREST do
703704
def overlaps(%FilterBuilder{} = f, column, values)
704705
when is_list(values) do
705706
values
706-
|> Enum.map(&"%##{&1}")
707-
|> Enum.join(",")
707+
|> Enum.map_join(",", &"%##{&1}")
708708
|> then(&FilterBuilder.add_param(f, column, "{#{&1}}"))
709709
end
710710

@@ -830,7 +830,7 @@ defmodule Supabase.PostgREST do
830830
"""
831831
@impl true
832832
def single(%FilterBuilder{} = f) do
833-
FilterBuilder.add_header(f, "accept", "application/vnd.pgrst,object+json")
833+
FilterBuilder.add_header(f, "accept", "application/vnd.pgrst.object+json")
834834
end
835835

836836
@doc """
@@ -896,19 +896,19 @@ defmodule Supabase.PostgREST do
896896
def execute_to(%FilterBuilder{} = f, schema) when is_atom(schema) do
897897
with {:ok, body} <- execute(f.client, f.method, f.body, f.table, f.headers, f.params) do
898898
if is_list(body) do
899-
Enum.map(body, &struct(schema, &1))
899+
{:ok, Enum.map(body, &struct(schema, &1))}
900900
else
901-
struct(schema, body)
901+
{:ok, struct(schema, body)}
902902
end
903903
end
904904
end
905905

906906
def execute_to(%QueryBuilder{} = q, schema) when is_atom(schema) do
907907
with {:ok, body} <- execute(q.client, q.method, q.body, q.table, q.headers, q.params) do
908908
if is_list(body) do
909-
Enum.map(body, &struct(schema, &1))
909+
{:ok, Enum.map(body, &struct(schema, &1))}
910910
else
911-
struct(schema, body)
911+
{:ok, struct(schema, body)}
912912
end
913913
end
914914
end
@@ -929,35 +929,35 @@ defmodule Supabase.PostgREST do
929929
- Supabase query execution: https://supabase.com/docs/reference/javascript/performing-queries
930930
"""
931931
@impl true
932-
def execute_to_finch_request(%mod{} = q) when Kernel.in(mod, [FilterBuilder, QueryBuilder]) do
933-
with {:ok, %Supabase.Client{} = client} = Supabase.Client.retrieve_client(q.client) do
934-
base_url = Path.join([client.conn.base_url, @api_path, q.table])
935-
accept_profile = {"accept-profile", client.db.schema}
936-
content_profile = {"content-profile", client.db.schema}
937-
additional_headers = Map.to_list(q.headers) ++ [accept_profile, content_profile]
938-
headers = Supabase.Fetcher.apply_client_headers(client, nil, additional_headers)
939-
query = URI.encode_query(q.params)
940-
url = URI.new!(base_url) |> URI.append_query(query)
941-
942-
Supabase.Fetcher.new_connection(q.method, url, q.body, headers)
943-
end
932+
def execute_to_finch_request(%mod{client: client} = q)
933+
when Kernel.in(mod, [FilterBuilder, QueryBuilder]) do
934+
base_url = Path.join([client.conn.base_url, @api_path, q.table])
935+
headers = apply_headers(client, q.headers)
936+
query = URI.encode_query(q.params)
937+
url = URI.new!(base_url) |> URI.append_query(query)
938+
939+
Supabase.Fetcher.new_connection(q.method, url, q.body, headers)
944940
end
945941

946942
defp execute(client, method, body, table, headers, params) do
947-
with {:ok, %Supabase.Client{} = client} = Supabase.Client.retrieve_client(client) do
948-
base_url = Path.join([client.conn.base_url, @api_path, table])
949-
accept_profile = {"accept-profile", client.db.schema}
950-
content_profile = {"content-profile", client.db.schema}
951-
additional_headers = Map.to_list(headers) ++ [accept_profile, content_profile]
952-
headers = Supabase.Fetcher.apply_client_headers(client, nil, additional_headers)
953-
query = URI.encode_query(params)
954-
url = URI.new!(base_url) |> URI.append_query(query)
955-
request = request_fun_from_method(method)
956-
957-
url
958-
|> request.(body, headers)
959-
|> parse_response()
960-
end
943+
base_url = Path.join([client.conn.base_url, @api_path, table])
944+
headers = apply_headers(client, headers)
945+
query = URI.encode_query(params)
946+
url = URI.new!(base_url) |> URI.append_query(query)
947+
request = request_fun_from_method(method)
948+
949+
url
950+
|> request.(body, headers)
951+
|> parse_response()
952+
end
953+
954+
defp apply_headers(client, headers) do
955+
accept_profile = {"accept-profile", client.db.schema}
956+
content_profile = {"content-profile", client.db.schema}
957+
content_type = {"content-type", "application/json"}
958+
additional_headers = Map.to_list(headers) ++ [accept_profile, content_profile, content_type]
959+
960+
Supabase.Fetcher.apply_client_headers(client, nil, additional_headers)
961961
end
962962

963963
defp request_fun_from_method(:get), do: &Supabase.Fetcher.get/3
@@ -984,92 +984,4 @@ defmodule Supabase.PostgREST do
984984
defp success_resp?(status) do
985985
Kernel.in(status, 200..399)
986986
end
987-
988-
defmacrop wrap_postgrest_functions do
989-
quote unquote: false, bind_quoted: [module: __MODULE__] do
990-
for {fun, arity} <- module.__info__(:functions) do
991-
cond do
992-
fun == :from ->
993-
quote do
994-
@doc """
995-
Check `Supabase.PostgREST.#{unquote(fun)}/#{unquote(arity)}`
996-
"""
997-
def unquote(fun)(schema) do
998-
apply(unquote(module), unquote(fun), [@client, schema])
999-
end
1000-
end
1001-
1002-
arity == 1 ->
1003-
quote do
1004-
@doc """
1005-
Check `Supabase.PostgREST.#{unquote(fun)}/#{unquote(arity)}`
1006-
"""
1007-
def unquote(fun)(data) do
1008-
apply(unquote(module), unquote(fun), [data])
1009-
end
1010-
end
1011-
1012-
true ->
1013-
args = for idx <- 1..arity, do: Macro.var(:"arg#{idx}", module)
1014-
1015-
quote do
1016-
@doc """
1017-
Check `Supabase.PostgREST.#{unquote(fun)}/#{unquote(arity)}`
1018-
"""
1019-
def unquote(fun)(unquote_splicing(args)) do
1020-
args = [unquote_splicing(args)]
1021-
apply(unquote(module), unquote(fun), args)
1022-
end
1023-
end
1024-
end
1025-
end
1026-
end
1027-
end
1028-
1029-
defmacro __using__([{:client, client} | opts]) do
1030-
config = Macro.escape(Keyword.get(opts, :config, %{}))
1031-
1032-
quote location: :keep do
1033-
@client unquote(client)
1034-
1035-
def child_spec(opts) do
1036-
%{
1037-
id: __MODULE__,
1038-
start: {__MODULE__, :start_link, [opts]},
1039-
type: :supervisor
1040-
}
1041-
end
1042-
1043-
def start_link(opts \\ []) do
1044-
manage_clients? = Application.get_env(:supabase_potion, :manage_clients, true)
1045-
1046-
if manage_clients? do
1047-
Supabase.init_client(unquote(client), unquote(config))
1048-
else
1049-
base_url =
1050-
Application.get_env(:supabase_potion, :supabase_base_url) ||
1051-
raise Supabase.MissingSupabaseConfig, :url
1052-
1053-
api_key =
1054-
Application.get_env(:supabase_potion, :supabase_api_key) ||
1055-
raise Supabase.MissingSupabaseConfig, :key
1056-
1057-
config =
1058-
unquote(config)
1059-
|> Map.put(:conn, %{base_url: base_url, api_key: api_key})
1060-
|> Map.put(:name, unquote(client))
1061-
1062-
opts = [name: unquote(client), client_info: config]
1063-
Supabase.Client.start_link(opts)
1064-
end
1065-
|> then(fn
1066-
{:ok, pid} -> {:ok, pid}
1067-
{:error, {:already_started, pid}} -> {:ok, pid}
1068-
err -> err
1069-
end)
1070-
end
1071-
1072-
unquote(wrap_postgrest_functions())
1073-
end
1074-
end
1075987
end

lib/supabase/postgrest/error.ex

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Supabase.PostgREST.Error do
2+
@moduledoc false
3+
24
@derive Jason.Encoder
35
defstruct [:hint, :details, :code, :message]
46

lib/supabase/postgrest/filter_builder.ex

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Supabase.PostgREST.FilterBuilder do
2+
@moduledoc false
3+
24
alias Supabase.PostgREST.QueryBuilder
35

46
defstruct [:method, :body, :table, :headers, :params, :client]

0 commit comments

Comments
 (0)