Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@ Then you can use
client.SignInWithEmailPassword(USER_EMAIL, USER_PASSWORD)

```

### Configure HTTP Proxy

To configure an HTTP Proxy for the Supabase client, you can use the `Proxy` field in `ClientOptions`. Here's an example:

```go
client, err := supabase.NewClient(API_URL, API_KEY, &supabase.ClientOptions{
Proxy: "http://your-proxy-url:port",
})
if err != nil {
fmt.Println("cannot initalize client", err)
}
data, count, err := client.From("countries").Select("*", "exact", false).Execute()
```
27 changes: 23 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package supabase
import (
"errors"
"log"
"net/http"
"net/url"
"time"

"github.com/supabase-community/functions-go"
Expand Down Expand Up @@ -32,11 +34,13 @@ type Client struct {
type clientOptions struct {
url string
headers map[string]string
proxy *url.URL
}

type ClientOptions struct {
Headers map[string]string
Schema string
Proxy string
}

// NewClient creates a new Supabase client.
Expand Down Expand Up @@ -72,12 +76,27 @@ func NewClient(url, key string, options *ClientOptions) (*Client, error) {
schema = "public"
}

client.rest = postgrest.NewClient(url+REST_URL, schema, headers)
client.Storage = storage_go.NewClient(url+STORAGE_URL, key, headers)
if options != nil && options.Proxy != "" {
proxyURL, err := url.Parse(options.Proxy)
if err != nil {
return nil, err
}
client.options.proxy = proxyURL
}

httpClient := &http.Client{}
if client.options.proxy != nil {
httpClient.Transport = &http.Transport{
Proxy: http.ProxyURL(client.options.proxy),
}
}

client.rest = postgrest.NewClientWithHTTPClient(url+REST_URL, schema, headers, httpClient)
client.Storage = storage_go.NewClientWithHTTPClient(url+STORAGE_URL, key, headers, httpClient)
// ugly to make auth client use custom URL
tmp := gotrue.New(url, key)
tmp := gotrue.NewWithHTTPClient(url, key, httpClient)
client.Auth = tmp.WithCustomGoTrueURL(url + AUTH_URL)
client.Functions = functions.NewClient(url+FUNCTIONS_URL, key, headers)
client.Functions = functions.NewClientWithHTTPClient(url+FUNCTIONS_URL, key, headers, httpClient)

return client, nil
}
Expand Down
93 changes: 93 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package supabase_test

import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

"github.com/supabase-community/supabase-go"
Expand Down Expand Up @@ -47,3 +49,94 @@ func TestFunctions(t *testing.T) {
result, err := client.Functions.Invoke("hello_world", map[string]interface{}{"name": "world"})
fmt.Println(result, err)
}

func TestFromWithProxy(t *testing.T) {
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"name":"Test Country"}]`))
}))
defer proxy.Close()

client, err := supabase.NewClient(API_URL, API_KEY, &supabase.ClientOptions{Proxy: proxy.URL})
if err != nil {
t.Fatalf("cannot initialize client: %v", err)
}

data, count, err := client.From("countries").Select("*", "exact", false).Execute()
if err != nil {
t.Fatalf("error executing query: %v", err)
}

expected := `[{"id":1,"name":"Test Country"}]`
if string(data) != expected {
t.Errorf("expected %s, got %s", expected, string(data))
}
if count != 1 {
t.Errorf("expected count 1, got %d", count)
}
}

func TestRpcWithProxy(t *testing.T) {
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`"Hello, world!"`))
}))
defer proxy.Close()

client, err := supabase.NewClient(API_URL, API_KEY, &supabase.ClientOptions{Proxy: proxy.URL})
if err != nil {
t.Fatalf("cannot initialize client: %v", err)
}

result := client.Rpc("hello_world", "", nil)
expected := `"Hello, world!"`
if result != expected {
t.Errorf("expected %s, got %s", expected, result)
}
}

func TestStorageWithProxy(t *testing.T) {
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"id":"bucket-id","name":"Test Bucket"}`))
}))
defer proxy.Close()

client, err := supabase.NewClient(API_URL, API_KEY, &supabase.ClientOptions{Proxy: proxy.URL})
if err != nil {
t.Fatalf("cannot initialize client: %v", err)
}

result, err := client.Storage.GetBucket("bucket-id")
if err != nil {
t.Fatalf("error getting bucket: %v", err)
}

expected := `{"id":"bucket-id","name":"Test Bucket"}`
if result != expected {
t.Errorf("expected %s, got %s", expected, result)
}
}

func TestFunctionsWithProxy(t *testing.T) {
proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message":"Hello, world!"}`))
}))
defer proxy.Close()

client, err := supabase.NewClient(API_URL, API_KEY, &supabase.ClientOptions{Proxy: proxy.URL})
if err != nil {
t.Fatalf("cannot initialize client: %v", err)
}

result, err := client.Functions.Invoke("hello_world", map[string]interface{}{"name": "world"})
if err != nil {
t.Fatalf("error invoking function: %v", err)
}

expected := `{"message":"Hello, world!"}`
if result != expected {
t.Errorf("expected %s, got %s", expected, result)
}
}