Crates.io | supabase-rust-gftd |
lib.rs | supabase-rust-gftd |
version | |
source | src |
created_at | 2025-04-21 08:05:54.065538+00 |
updated_at | 2025-04-25 17:26:38.630168+00 |
description | Rust client for Supabase |
homepage | |
repository | https://github.com/jun784/supabase-rust |
max_upload_size | |
id | 1642437 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
Rust client library for Supabase - A Rust implementation compatible with JavaScript's supabase-js.
This section explains the current implementation status and compatibility with the JavaScript version of Supabase (v2.x).
Module | Status | API Compatibility | Notes |
---|---|---|---|
Auth | ✅ | 38/40 (95%) | Email/password auth, OAuth, Phone auth, MFA, Password reset, Admin API implemented. |
PostgresT | ⚠️ | ~88% (27/30 - Type Safety Removed) | Core functions (CRUD, filtering, RPC, transactions) implemented. Test coverage improved for basic CRUD, filters, and modifiers. Prefer: return=representation header correctly added for mutations. NOTE: Type-safe ops removed. Requires local patch for empty INSERT/UPDATE/DELETE responses with certain PostgREST versions. |
Storage | ✅ | 20/20 (100%) | File moving (move_object ) added. Image transformation and extensions beyond JS version. Low test coverage noted. |
Realtime | ❌ | 11/14 (~80%) | Core PubSub, DB changes, Presence implemented. Tests have critical timeout issues and very low coverage. Needs significant tests, docs & refactoring (large lib.rs ). |
Functions | ⚠️ | 5/6 (85%) | Basic and streaming functionality implemented, enhancing binary support. Missing automated tests. Examples require Edge Function setup. |
Migration | 🚧 | N/A | Utility crate for database migrations using sea-orm-migration /refinery . Status: In Development/Experimental (Not Implemented). |
Status Icons: ✅ Implemented & Tested (Basic), ⚠️ Implemented (Low Test/Docs/Needs Refactor), ❌ Critical Issues (Tests Failing/Timeout), 🚧 In Development/Not Implemented
@supabase/auth-js
)API Compatibility: 38/40 (95%)
@supabase/postgrest-js
)API Compatibility: ~88% (27/30 - Type Safety Feature Removed)
Status: Core library tests improved, covering basic CRUD, filters, modifiers, and error handling. Prefer: return=representation
header is now correctly added for insert
/update
/delete
. NOTE: Local PostgREST instances (like v12.2.11) might return empty responses for successful INSERT/UPDATE/DELETE, requiring a local patch to crates/postgrest/src/lib.rs
to handle these cases. Type-safe operations removed.
insert_typed
, etc.) - Removed.Row Level Security (RLS) is a powerful PostgreSQL security feature that enables row-level access control for database tables. The Supabase Rust client allows you to work with RLS as follows:
Using admin role to bypass RLS policies:
// Note: Using this method requires a service role key
let service_client = supabase.with_service_key("your-service-role-key");
// Access all user data by bypassing RLS
let all_users = service_client
.from("users")
.select("*")
.ignore_rls() // Bypass RLS policies
.execute()
.await?;
Typical RLS setup to allow users to access only their own data:
-- Enable RLS on table
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- Set policy that allows viewing only owned profiles
CREATE POLICY "Profiles are viewable by owners only"
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
-- Set policy that allows updating only owned profiles
CREATE POLICY "Profiles are updatable by owners only"
ON profiles
FOR UPDATE
USING (auth.uid() = user_id);
// Authenticate user
let session = supabase
.auth()
.sign_in_with_password(SignInWithPasswordCredentials {
email: "user@example.com".to_string(),
password: "password123".to_string(),
..Default::default()
})
.await?;
// Access data with session JWT token
// RLS policies are automatically applied
let my_profile = supabase
.from("profiles")
.select("*")
.with_auth(&session.access_token) // Set JWT token
.execute()
.await?;
// Results only include profiles owned by the current user
For more complex use cases, dynamic filtering with functions and JSONB data is possible:
-- Access control based on user roles
CREATE POLICY "Admins can access all data"
ON documents
FOR ALL
USING (
auth.jwt() ->> 'role' = 'admin'
OR auth.uid() = owner_id
);
// Users with admin role can see all documents
// Regular users can only see their own documents
let documents = supabase
.from("documents")
.select("*")
.with_auth(&session.access_token) // Set JWT token
.execute()
.await?;
ignore_rls()
only on backend servers, never expose to clients// Always use verified tokens
if let Some(verified_token) = supabase.auth().verify_token(&input_token).await? {
// Access data with verified token
let data = supabase
.from("secured_table")
.select("*")
.with_auth(&verified_token)
.execute()
.await?;
}
@supabase/storage-js
)API Compatibility: 20/20 (100%)
move_object
)@supabase/realtime-js
)API Compatibility: 11/14 (~80%) | Tests: ❌ (Critical Timeout Issues & Very Low Coverage) | Docs: ⚠️ (Needs More Examples) | Code Structure: ⚠️ (Large lib.rs
- Needs Refactoring)
RealtimeError
)Arc
, RwLock
, mpsc
) used for concurrency.test_connect_disconnect
) are timing out, indicating potential connection or disconnection logic problems. Test coverage is extremely low.@supabase/functions-js
)API Compatibility: ~5/6 (~85%) | Tests: ❌ (Missing - High Priority)
invoke_binary
returns Bytes
)supabase-js
is generally high.move_object
.storage::move_object
requires dedicated tests.storage_example.rs
contains dead code warnings that need to be addressed. Examples should be verified against the latest crate versions.crates/realtime/tests/integration_test.rs
(test_connect_disconnect
).storage::move_object
: Add specific integration tests for the newly added file move functionality.storage_example.rs
Warnings: Remove or utilize the dead code identified by the compiler warnings.lib.rs
into smaller, more manageable modules.supabase-js
for any potentially valuable features not yet implemented (e.g., advanced RLS support, recursive Storage folder operations).crates/migration
utility.Add the crate to your Cargo.toml
:
[dependencies]
supabase-rust = "0.2.0"
use supabase_rust::{Supabase, PostgrestError};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Profile {
id: String,
username: String,
avatar_url: Option<String>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize client
let supabase = Supabase::new("https://your-project.supabase.co", "your-anon-key");
// Authenticate
let session = supabase
.auth()
.sign_in_with_password("user@example.com", "password123")
.await?;
// Query data with authentication
let profiles: Vec<Profile> = supabase
.from("profiles")
.select("*")
.with_auth(&session.access_token)
.execute()
.await?
.data()?;
println!("Retrieved profiles: {:?}", profiles);
Ok(())
}
// Start a transaction
let transaction = supabase.from("profiles").transaction();
// Perform operations within transaction
let update_result = transaction
.from("profiles")
.update(json!({ "status": "active" }))
.eq("id", "123")
.execute()
.await?;
let insert_result = transaction
.from("logs")
.insert(json!({ "user_id": "123", "action": "status_update" }))
.execute()
.await?;
// Commit the transaction (or rollback on error)
transaction.commit().await?;
// Upload an image
let path = "avatars/profile.jpg";
supabase
.storage()
.from("public-bucket")
.upload(path, file_bytes)
.await?;
// Generate image transformation URL (resize to 100x100, format as webp)
let transform_url = supabase
.storage()
.from("public-bucket")
.get_public_transform_url(path, |transform| {
transform
.width(100)
.height(100)
.format("webp")
.quality(80)
});
// Subscribe to database changes
let subscription = supabase
.realtime()
.channel("schema-db-changes")
.on_postgres_changes("profiles", |changes| {
changes
.event("INSERT")
.event("UPDATE")
.event("DELETE")
})
.subscribe(move |payload| {
println!("Change detected: {:?}", payload);
})
.await?;
// Later, unsubscribe when no longer needed
subscription.unsubscribe().await?;
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
The project is organized as a Cargo workspace to manage different Supabase features as separate crates:
crates/
: Contains the core implementation for each Supabase service:
auth
: Authentication (High Priority - Core functionality)postgrest
: Database interactions (High Priority - Core functionality)storage
: File storage (Medium Priority - Needs significant test coverage)realtime
: Realtime subscriptions (Medium Priority - Needs significant tests, docs, refactoring)functions
: Edge function invocation (Medium Priority - Needs significant tests)migration
: Database migration utilities (Low Priority - Not Implemented)src/
: The main supabase-rust
library crate that ties the modules together.examples/
: Usage examples for each module (High Priority - Needs fixing and maintenance).tests/
: Integration tests (Medium Priority - Coverage needs expansion).supabase/
: Supabase-specific configuration or migration files (related to the migration
crate).docs/
: Additional documentation (Low Priority - Needs population).Cargo.toml
: Workspace and root crate definition.Makefile
: Development and build tasks.Current priorities are increasing test coverage across all modules, stabilizing the examples, refactoring the Realtime crate, and starting the implementation of the Migration crate.
The /examples
directory contains various usage examples for the different crates.
Prerequisites:
examples/.env
:
SUPABASE_URL
: Your Supabase project URL.SUPABASE_KEY
: Your Supabase project anon
key.SUPABASE_SERVICE_ROLE_KEY
: (Required for auth_admin_example
) Your Supabase project service_role
key.functions_example
and functions_binary_example
: Deployed Edge Functions (hello-world
, generate-image
, etc.) in your Supabase project.storage_example
: A Storage bucket configured in your Supabase project.Running Examples:
cd examples
./setup_db.sh
(or ensure the tasks
table exists with RLS policies from schema/create_tables.sql
).cargo run --bin <example_name>
(e.g., cargo run --bin auth_example
).Current Status (Post-Fixes - Needs Verification):
Example | Status | Notes |
---|---|---|
auth_example |
✅ Runs | |
database_example |
✅ Runs (with patch) | Requires local patch to crates/postgrest/src/lib.rs to handle empty INSERT/UPDATE/DELETE responses from local PostgREST v12.2.11. |
storage_example |
✅ Runs (Needs Verification) | Attempted fix for auth header. Still requires bucket setup in Supabase project. |
realtime_example |
✅ Runs (Needs Verification) | Attempted fix for type error. |
postgrest_example |
✅ Runs (Needs Verification) | Attempted fix for COUNT filter error. |
functions_example |
❌ Fails (Setup Required) | Fails due to missing hello-world Edge Function. Requires Supabase project setup. |
auth_admin_example |
❌ Fails (Setup Required) | Panics due to missing SUPABASE_SERVICE_ROLE_KEY environment variable. Requires setup. |
functions_binary_example |
❌ Fails (Setup Required) | Fails due to missing Edge Functions (e.g., generate-image ). Requires Supabase project setup. |
While core functionality exists, this library is not yet recommended for production use due to the following:
Storage
, Realtime
, Functions
) lack adequate test coverage, increasing the risk of undiscovered bugs.Realtime
crate requires significant refactoring, documentation improvement, and testing before being considered stable.Migration
crate is not yet implemented.Focus areas for achieving production readiness are comprehensive testing, Realtime module stabilization, and Migration crate implementation.