Skip to content

Commit

Permalink
feat: prepare for refactored minor version
Browse files Browse the repository at this point in the history
- remove unecessary and confuse option `manege_clients`
  - users should manage OTP process on their own
  - client struct should be simpler to use and manage
  - client initialization should be very explicit
    - no more infinite ways to "start" a client, just create a raw struct
- remove old documentation
- update elixir and erlang OTP source versions
- remove usage of earthly on top of old github actions
- add support for local dev with `asdf`
- add local `.env.dev` for usage with supabase cli
  • Loading branch information
zoedsoupe committed Aug 30, 2024
1 parent 6947423 commit 867af6d
Show file tree
Hide file tree
Showing 26 changed files with 231 additions and 659 deletions.
2 changes: 2 additions & 0 deletions .env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export SUPABASE_URL=http://127.0.0.1:54321
export SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
61 changes: 31 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,39 @@ name: ci

on:
push:
branches: [ main ]
branches:
- main
pull_request:
branches: [ main ]
branches:
- main

jobs:
build:
lint:
runs-on: ubuntu-latest
env:
GHCR_USERNAME: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
FORCE_COLOR: 1

strategy:
matrix:
elixir: [1.17.0]
otp: [27.0]

steps:
- uses: actions/checkout@v3
- name: Put back the git branch into git (Earthly uses it for tagging)
run: |
branch=""
if [ -n "$GITHUB_HEAD_REF" ]; then
branch="$GITHUB_HEAD_REF"
else
branch="${GITHUB_REF##*/}"
fi
git checkout -b "$branch" || true
- name: Docker Login
run: docker login https://ghcr.io --username "$GHCR_USERNAME" --password "$GHCR_TOKEN"
- name: Download latest earthly
run: "sudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly && chmod +x /usr/local/bin/earthly'"

- name: Earthly version
run: earthly --version

- name: Run CI
run: earthly -P +ci

- name: Run Tests
run: earthly -P +test
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: ${{ matrix.elixir }}
otp-version: ${{ matrix.otp }}

- name: Install dependencies
run: mix deps.get

- name: Clean build
run: mix clean

- name: Check code formatting
run: mix format --check-formatted

- name: Run Credo
run: mix credo --strict
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
elixir: [1.15.7]
otp: [26.1.2]
elixir: [1.17.0]
otp: [27.0]
steps:
- uses: actions/checkout@v3
- name: Set up Elixir
Expand Down
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
erlang 27.0
elixir 1.17.0-otp-27
33 changes: 0 additions & 33 deletions Earthfile

This file was deleted.

14 changes: 4 additions & 10 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright 2023 zoedsoupe <[email protected]>

Copyright (C) 2023 Zoey Pessanha <[email protected]>
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:

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

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.
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.
103 changes: 7 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ To install the base SDK:
```elixir
def deps do
[
{:supabase_potion, "~> 0.3"}
{:supabase_potion, "~> 0.4"}
]
end
```

### Clients

A `Supabase.Client` is an Agent that holds general information about Supabase, that can be used to intereact with any of the children integrations, for example: `Supabase.Storage` or `Supabase.UI`.
A `Supabase.Client` holds general information about Supabase, that can be used to intereact with any of the children integrations, for example: `Supabase.Storage` or `Supabase.UI`.

`Supabase.Client` is defined as:

- `:name` - the name of the client, started by `start_link/1`
- `:conn` - connection information, the only required option as it is vital to the `Supabase.Client`.
- `:base_url` - The base url of the Supabase API, it is usually in the form `https://<app-name>.supabase.io`.
- `:api_key` - The API key used to authenticate requests to the Supabase API.
Expand All @@ -40,19 +39,6 @@ A `Supabase.Client` is an Agent that holds general information about Supabase, t
- `:storage` - storage type
- `:storage_key` - storage key

## Usage

The Supabase Elixir SDK provides a flexible way to manage `Supabase.Client` instances, which can, in turn, manage multiple `Supabase.Client` instances. Here's a brief overview of the key concepts:

### Starting a Client

You can start a client using the `Supabase.Client.start_link/1` function. However, it's recommended to use `Supabase.init_client!/1`, which allows you to pass client options and automatically manage `Supabase.Client` processes.

```elixir
iex> Supabase.Client.init_client!(%{conn: %{base_url: "<supa-url>", api_key: "<supa-key>"}})
{:ok, #PID<0.123.0>}
```

## Configuration

Ensure your Supabase configurations are set:
Expand All @@ -61,100 +47,25 @@ Ensure your Supabase configurations are set:
import Config

config :supabase,
manage_clients: false,
supabase_base_url: System.fetch_env!("SUPABASE_BASE_URL"),
supabase_api_key: System.fetch_env!("SUPABASE_API_KEY"),
```

- `supabase_base_url`: The base URL of your Supabase project! More information on how to find it can be seen on the [next section](#how-to-find-my-supabase-base-url?)
- `supabase_api_key`: The secret of your Supabase project! More information on how to find it can be seen on the [next section](#how-to-find-my-supabase-api-key?)
- `manage_clients`: Enable or disable the internal client management by the library. Defauls to `true`, see more on the [library supervisor documentation](https://hexdocs.pm/supabase_potion/Supabase.ClientSupervisor.html).

Make sure to set the environment variables `SUPABASE_BASE_URL` and `SUPABASE_API_KEY`.

## Manually starting Clients

If you want to manually manage Clients, firstly you need to disable the config:

```elixir
import Config

config :supabase_potion, manage_clients: false
```

Then you need to start the Clients managements processes, that consists on:
- `Supabase.ClientSupervisor`: a DynamicSupervisor to manage multiple Supabase clients
- `Supabase.ClientRegistry`: a Registry to easily find a Supabase client

You can start them on your application startup, often on your `MyApp.Application`:

```elixir
defmodule MyApp.Application do
use Application

@impl true
def start(_type, _args) do
children = [
# rest of your Supervisor's children...
# is recommended to start registry **before**
# the Supervsior
Supabase.ClientRegistry
Supabase.ClientSupervisor
]
end

# rest of module...
end
```
## Starting a Client

Now you can start to initialize Clients! as pointed on [Staring a Client](#starting-a-client) section.

However, maybe you can full control of your Supabase Clients, then, you can start Clients individually on your application startup, like:
You can start a client using the `Supabase.init_client/1` or `Supabase.init_client!/1` function.

```elixir
defmodule MyApp.Application do
use Application

@impl true
def start(_type, _args) do
supabase_config = supabase_client_config()
supabase_opts = [name: MyApp.SupabaseClient, client_info: supabase_config]

children = [
# rest of your Supervisor's children...
{Supabase.Client, supabase_opts}
]
end

defp supabase_client_config do
%{
# you can skip the `conn` config if you already set on config.exs
conn: %{
api_key: "my-super-secret-api-key",
base_url: "https://my-project-id.supabase.co",
access_token: "my-scoped-access-token",
},
db: %{schema: "my-schema"} # default to "public",
# global headers to be used on Supabase API requests
global: %{headers: %{"content-type": "application/json"}},
auth: %{
# below are the defaults values
auto_refresh_token: true,
debug: false,
detect_session_in_url: true,
flow_type: :implicit,
persist_session: true,
storage: "my-storage",
storage_key: "my-storage-key"
}
}
end

# rest of module...
end
iex> Supabase.init_client!(%{conn: %{base_url: "<supa-url>", api_key: "<supa-key>"}})
{:ok, %Supabase.Client{}}
```

#### TODO
> Note that if you already set up supabase potion options on your application config, you can safely use `Supabase.init_client/0` or `Supabase.init_client!/0`
### How to find my Supabase base URL?

Expand Down
1 change: 0 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Config

if config_env() == :dev do
config :supabase_potion,
manage_clients: true,
supabase_base_url: System.get_env("SUPABASE_URL"),
supabase_api_key: System.get_env("SUPABASE_KEY")
end
8 changes: 4 additions & 4 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
description = "Supabase SDK for Elixir";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/default";
};
Expand All @@ -19,9 +19,9 @@
system,
...
}: let
inherit (pkgs.beam.interpreters) erlangR26;
inherit (pkgs.beam.interpreters) erlang_27;
inherit (pkgs.beam) packagesWith;
beam = packagesWith erlangR26;
beam = packagesWith erlang_27;
in {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
Expand All @@ -31,7 +31,7 @@
mkShell {
name = "supabase-ex";
packages = with pkgs;
[beam.elixir_1_16]
[beam.elixir_1_17]
++ lib.optional stdenv.isLinux [inotify-tools]
++ lib.optional stdenv.isDarwin [
darwin.apple_sdk.frameworks.CoreServices
Expand Down
Loading

0 comments on commit 867af6d

Please sign in to comment.