supabase

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2023 License: MIT Imports: 18 Imported by: 0

README

supabase-go

Unofficial Supabase client for Go. It is an amalgamation of all the libraries similar to the official Supabase client.

Installation

go get github.com/nedpals/supabase-go

Usage

Replace the <SUPABASE-URL> and <SUPABASE-URL> placeholders with values from https://supabase.com/dashboard/project/YOUR_PROJECT/settings/api

Authenticate
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
    "context"
)

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  ctx := context.Background()
  user, err := supabase.Auth.SignUp(ctx, supa.UserCredentials{
    Email:    "example@example.com",
    Password: "password",
  })
  if err != nil {
    panic(err)
  }

  fmt.Println(user)
}
Sign-In
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
    "context"
)

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  ctx := context.Background()
  user, err := supabase.Auth.SignIn(ctx, supa.UserCredentials{
    Email:    "example@example.com",
    Password: "password",
  })
  if err != nil {
    panic(err)
  }

  fmt.Println(user)
}
Insert
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
)

type Country struct {
  ID      int    `json:"id"`
  Name    string `json:"name"`
  Capital string `json:"capital"`
}

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  row := Country{
    ID:      5,
    Name:    "Germany",
    Capital: "Berlin",
  }

  var results []Country
  err := supabase.DB.From("countries").Insert(row).Execute(&results)
  if err != nil {
    panic(err)
  }

  fmt.Println(results) // Inserted rows
}
Select
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
)

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  var results map[string]interface{}
  err := supabase.DB.From("countries").Select("*").Single().Execute(&results)
  if err != nil {
    panic(err)
  }

  fmt.Println(results) // Selected rows
}
Update
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
)

type Country struct {
  Name    string `json:"name"`
  Capital string `json:"capital"`
}

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  row := Country{
    Name:    "France",
    Capital: "Paris",
  }

  var results map[string]interface{}
  err := supabase.DB.From("countries").Update(row).Eq("id", "5").Execute(&results)
  if err != nil {
    panic(err)
  }

  fmt.Println(results) // Updated rows
}
Delete
package main 
import (
    supa "github.com/nedpals/supabase-go"
    "fmt"
)

func main() {
  supabaseUrl := "<SUPABASE-URL>"
  supabaseKey := "<SUPABASE-KEY>"
  supabase := supa.CreateClient(supabaseUrl, supabaseKey)

  var results map[string]interface{}
  err := supabase.DB.From("countries").Delete().Eq("name", "France").Execute(&results)
  if err != nil {
    panic(err)
  }

  fmt.Println(results) // Empty - nothing returned from delete
}

Roadmap

  • Auth support (1)
  • DB support (2)
  • Realtime
  • Storage
  • Testing

(1) - Thin API wrapper. Does not rely on the GoTrue library for simplicity (2) - Through postgrest-go

I just implemented features which I actually needed for my project for now. If you like to implement these features, feel free to submit a pull request as stated in the Contributing section below.

Design Goals

It tries to mimick as much as possible the official Javascript client library in terms of ease-of-use and in setup process.

Contributing

Submitting a pull request

  • Fork it (https://github.com/nedpals/supabase-go/fork)
  • Create your feature branch (git checkout -b my-new-feature)
  • Commit your changes (git commit -am 'Add some feature')
  • Push to the branch (git push origin my-new-feature)
  • Create a new Pull Request

Contributors

Documentation

Index

Constants

View Source
const (
	AuthEndpoint    = "auth/v1"
	AdminEndpoint   = "auth/v1/admin"
	RestEndpoint    = "rest/v1"
	StorageEndpoint = "storage/v1"
)

Variables

View Source
var ErrNotFound = errors.New("file not found")

Functions

This section is empty.

Types

type Admin

type Admin struct {
	// contains filtered or unexported fields
}

func (*Admin) CreateUser

func (a *Admin) CreateUser(ctx context.Context, params AdminUserParams) (*AdminUser, error)

Create a user

func (a *Admin) GenerateLink(ctx context.Context, params GenerateLinkParams) (*GenerateLinkResponse, error)

Update a user

func (*Admin) GetUser

func (a *Admin) GetUser(ctx context.Context, userID string) (*AdminUser, error)

Retrieve the user

func (*Admin) UpdateUser

func (a *Admin) UpdateUser(ctx context.Context, userID string, params AdminUserParams) (*AdminUser, error)

Update a user

type AdminUser

type AdminUser struct {
	ID string `json:"id" db:"id"`

	Aud   string `json:"aud" db:"aud"`
	Role  string `json:"role" db:"role"`
	Email string `json:"email" db:"email"`

	EmailConfirmedAt *time.Time `json:"email_confirmed_at,omitempty" db:"email_confirmed_at"`
	InvitedAt        *time.Time `json:"invited_at,omitempty" db:"invited_at"`

	Phone            string     `json:"phone" db:"phone"`
	PhoneConfirmedAt *time.Time `json:"phone_confirmed_at,omitempty" db:"phone_confirmed_at"`

	ConfirmationSentAt *time.Time `json:"confirmation_sent_at,omitempty" db:"confirmation_sent_at"`

	RecoverySentAt *time.Time `json:"recovery_sent_at,omitempty" db:"recovery_sent_at"`

	EmailChange       string     `json:"new_email,omitempty" db:"email_change"`
	EmailChangeSentAt *time.Time `json:"email_change_sent_at,omitempty" db:"email_change_sent_at"`

	PhoneChange       string     `json:"new_phone,omitempty" db:"phone_change"`
	PhoneChangeSentAt *time.Time `json:"phone_change_sent_at,omitempty" db:"phone_change_sent_at"`

	ReauthenticationSentAt *time.Time `json:"reauthentication_sent_at,omitempty" db:"reauthentication_sent_at"`

	LastSignInAt *time.Time `json:"last_sign_in_at,omitempty" db:"last_sign_in_at"`

	AppMetaData  JSONMap `json:"app_metadata" db:"raw_app_meta_data"`
	UserMetaData JSONMap `json:"user_metadata" db:"raw_user_meta_data"`

	Factors    []Factor   `json:"factors,omitempty" has_many:"factors"`
	Identities []Identity `json:"identities" has_many:"identities"`

	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at" db:"updated_at"`
	BannedUntil *time.Time `json:"banned_until,omitempty" db:"banned_until"`
	DeletedAt   *time.Time `json:"deleted_at,omitempty" db:"deleted_at"`
}

type AdminUserParams

type AdminUserParams struct {
	Role         string  `json:"role"`
	Email        string  `json:"email"`
	Phone        string  `json:"phone"`
	Password     *string `json:"password"`
	EmailConfirm bool    `json:"email_confirm"`
	PhoneConfirm bool    `json:"phone_confirm"`
	UserMetadata JSONMap `json:"user_metadata"`
	AppMetadata  JSONMap `json:"app_metadata"`
	BanDuration  string  `json:"ban_duration"`
}

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

func (*Auth) ExchangeCode

func (a *Auth) ExchangeCode(ctx context.Context, opts ExchangeCodeOpts) (*AuthenticatedDetails, error)

ExchangeCode takes an auth code and PCKE verifier and returns the current user if succeeded.

func (*Auth) InviteUserByEmail

func (a *Auth) InviteUserByEmail(ctx context.Context, email string) (*User, error)

InviteUserByEmail sends an invite link to the given email. Returns a user.

func (*Auth) RefreshUser

func (a *Auth) RefreshUser(ctx context.Context, userToken string, refreshToken string) (*AuthenticatedDetails, error)

SignIn enters the user credentials and returns the current user if succeeded.

func (*Auth) ResetPasswordForEmail

func (a *Auth) ResetPasswordForEmail(ctx context.Context, email string) error

ResetPasswordForEmail sends a password recovery link to the given e-mail address.

func (a *Auth) SendMagicLink(ctx context.Context, email string) error

SendMagicLink sends a link to a specific e-mail address for passwordless auth.

func (*Auth) SignIn

func (a *Auth) SignIn(ctx context.Context, credentials UserCredentials) (*AuthenticatedDetails, error)

SignIn enters the user credentials and returns the current user if succeeded.

func (*Auth) SignInWithProvider

func (a *Auth) SignInWithProvider(opts ProviderSignInOptions) (*ProviderSignInDetails, error)

SignInWithProvider returns a URL for signing in via OAuth

func (*Auth) SignOut

func (a *Auth) SignOut(ctx context.Context, userToken string) error

SignOut revokes the users token and session.

func (*Auth) SignUp

func (a *Auth) SignUp(ctx context.Context, credentials UserCredentials) (*User, error)

SignUp registers the user's email and password to the database.

func (*Auth) UpdateUser

func (a *Auth) UpdateUser(ctx context.Context, userToken string, updateData map[string]interface{}) (*User, error)

UpdateUser updates the user information

func (*Auth) User

func (a *Auth) User(ctx context.Context, userToken string) (*User, error)

User retrieves the user information based on the given token

type AuthenticatedDetails

type AuthenticatedDetails struct {
	AccessToken          string `json:"access_token"`
	TokenType            string `json:"token_type"`
	ExpiresIn            int    `json:"expires_in"`
	RefreshToken         string `json:"refresh_token"`
	User                 User   `json:"user"`
	ProviderToken        string `json:"provider_token"`
	ProviderRefreshToken string `json:"provider_refresh_token"`
}

type BucketOption

type BucketOption struct {
	Id     string `json:"id"`
	Name   string `json:"name"`
	Public bool   `json:"public"`
}

type Client

type Client struct {
	BaseURL string

	HTTPClient *http.Client
	Admin      *Admin
	Auth       *Auth
	Storage    *Storage
	DB         *postgrest.Client
	// contains filtered or unexported fields
}

func CreateClient

func CreateClient(baseURL string, supabaseKey string, debug ...bool) *Client

CreateClient creates a new Supabase client

type ErrorResponse

type ErrorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"msg"`
}

func (*ErrorResponse) Error

func (err *ErrorResponse) Error() string

type ExchangeCodeOpts

type ExchangeCodeOpts struct {
	AuthCode     string `json:"auth_code"`
	CodeVerifier string `json:"code_verifier"`
}

type Factor

type Factor struct {
	ID           string    `json:"id" db:"id"`
	CreatedAt    time.Time `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time `json:"updated_at" db:"updated_at"`
	Status       string    `json:"status" db:"status"`
	FriendlyName string    `json:"friendly_name,omitempty" db:"friendly_name"`
	FactorType   string    `json:"factor_type" db:"factor_type"`
}

type FileErrorResponse

type FileErrorResponse struct {
	Status     string `json:"statusCode"`
	ShortError string `json:"error"`
	Message    string `json:"message"`
}

func (*FileErrorResponse) Error

func (err *FileErrorResponse) Error() string

type FileObject

type FileObject struct {
	Name           string      `json:"name"`
	BucketId       string      `json:"bucket_id"`
	Owner          string      `json:"owner"`
	Id             string      `json:"id"`
	UpdatedAt      string      `json:"updated_at"`
	CreatedAt      string      `json:"created_at"`
	LastAccessedAt string      `json:"last_accessed_at"`
	Metadata       interface{} `json:"metadata"`
	Buckets        bucket      `json:"buckets"`
}

type FileResponse

type FileResponse struct {
	Key     string `json:"key"`
	Message string `json:"message"`
}

type FileSearchOptions

type FileSearchOptions struct {
	Limit  int    `json:"limit"`
	Offset int    `json:"offset"`
	SortBy SortBy `json:"sortBy"`
}

type FlowType

type FlowType string
const (
	Implicit FlowType = "implicit"
	PKCE     FlowType = "pkce"
)

type GenerateLinkParams

type GenerateLinkParams struct {
	Type       string                 `json:"type"`
	Email      string                 `json:"email"`
	NewEmail   string                 `json:"new_email"`
	Password   string                 `json:"password"`
	Data       map[string]interface{} `json:"data"`
	RedirectTo string                 `json:"redirect_to"`
}

type GenerateLinkResponse

type GenerateLinkResponse struct {
	AdminUser
	ActionLink       string `json:"action_link"`
	EmailOtp         string `json:"email_otp"`
	HashedToken      string `json:"hashed_token"`
	VerificationType string `json:"verification_type"`
	RedirectTo       string `json:"redirect_to"`
}

type Identity

type Identity struct {
	ID           string     `json:"id" db:"id"`
	UserID       string     `json:"user_id" db:"user_id"`
	IdentityData JSONMap    `json:"identity_data,omitempty" db:"identity_data"`
	Provider     string     `json:"provider" db:"provider"`
	LastSignInAt *time.Time `json:"last_sign_in_at,omitempty" db:"last_sign_in_at"`
	CreatedAt    time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time  `json:"updated_at" db:"updated_at"`
}

type JSONMap

type JSONMap map[string]interface{}

type ListFileRequest

type ListFileRequest struct {
	Limit  int    `json:"limit"`
	Offset int    `json:"offset"`
	SortBy SortBy `json:"sortBy"`
	Prefix string `json:"prefix"`
}

type PKCEParams

type PKCEParams struct {
	Challenge       string
	ChallengeMethod string
	Verifier        string
}

adapted from https://go-review.googlesource.com/c/oauth2/+/463979/9/pkce.go#64

type ProviderSignInDetails

type ProviderSignInDetails struct {
	URL          string `json:"url"`
	Provider     string `json:"provider"`
	CodeVerifier string `json:"code_verifier"`
}

type ProviderSignInOptions

type ProviderSignInOptions struct {
	Provider   string   `url:"provider"`
	RedirectTo string   `url:"redirect_to"`
	Scopes     []string `url:"scopes"`
	FlowType   FlowType
}

type SignedUrlResponse

type SignedUrlResponse struct {
	SignedUrl string `json:"signedURL"`
}

type SortBy

type SortBy struct {
	Column string `json:"column"`
	Order  string `json:"order"`
}

type Storage

type Storage struct {
	// contains filtered or unexported fields
}

func (*Storage) CreateBucket

func (s *Storage) CreateBucket(ctx context.Context, option BucketOption) (*bucket, error)

CreateBucket creates a new storage bucket @param: option: a bucketOption with the name and id of the bucket you want to create @returns: bucket: a response with the details of the bucket of the bucket created

func (*Storage) DeleteBucket

func (s *Storage) DeleteBucket(ctx context.Context, id string) (*bucketResponse, error)

DeleteBucket deletes a bucket by its id, a bucket can't be deleted except emptied @param: id: the id of the bucket @returns bucketMessage: a successful response message or failed

func (*Storage) EmptyBucket

func (s *Storage) EmptyBucket(ctx context.Context, id string) (*bucketMessage, error)

EmptyBucket empties the object of a bucket by id @param: id: the id of the bucket @returns bucketMessage: a successful response message or failed

func (*Storage) From

func (s *Storage) From(bucketId string) *file

func (*Storage) GetBucket

func (s *Storage) GetBucket(ctx context.Context, id string) (*bucketResponse, error)

GetBucket retrieves a bucket by its id @param: id: the id of the bucket @returns: bucketResponse: a response with the details of the bucket

func (*Storage) ListBuckets

func (s *Storage) ListBuckets(ctx context.Context) (*[]bucketResponse, error)

ListBucket retrieves all buckets ina supabase storage @returns: []bucketResponse: a response with the details of all the bucket

func (*Storage) UpdateBucket

func (s *Storage) UpdateBucket(ctx context.Context, id string, option BucketOption) (*bucketMessage, error)

UpdateBucket updates a bucket by its id @param: id: the id of the bucket @param: option: the options to be updated @returns bucketMessage: a successful response message or failed

type User

type User struct {
	ID                 string    `json:"id"`
	Aud                string    `json:"aud"`
	Role               string    `json:"role"`
	Email              string    `json:"email"`
	InvitedAt          time.Time `json:"invited_at"`
	ConfirmedAt        time.Time `json:"confirmed_at"`
	ConfirmationSentAt time.Time `json:"confirmation_sent_at"`
	AppMetadata        struct {
		// contains filtered or unexported fields
	} `json:"app_metadata"`
	UserMetadata map[string]interface{} `json:"user_metadata"`
	CreatedAt    time.Time              `json:"created_at"`
	UpdatedAt    time.Time              `json:"updated_at"`
}

type UserCredentials

type UserCredentials struct {
	Email    string
	Password string
	Data     interface{}
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL