-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved documentation throughout crate
- Loading branch information
1 parent
3e11bf5
commit ffe3dbd
Showing
8 changed files
with
227 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
pub(crate) mod postgrest_rs; | ||
pub mod postgrest_rs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,49 @@ | ||
//! # Examples | ||
//! # suparust | ||
//! | ||
//! Simple example: | ||
//! ``` | ||
//! A crate for interacting with Supabase. Also supports WASM targets. | ||
//! | ||
//! ## Usage | ||
//! | ||
//! Create your Supabase client with `Supabase::new` and start using it. The client will automatically | ||
//! handle authentication for you after you have logged in with the client. | ||
//! | ||
//! ### Postgrest | ||
//! | ||
//! Use the functions [`from`](Supabase::from) and [`rpc`](Supabase::rpc) to get a [`postgrest::Builder`] that | ||
//! you can use to build your queries. The builder will automatically have authentication (if it's available) | ||
//! when it's first created. | ||
//! | ||
//! ### Storage | ||
//! | ||
//! Use the function [`storage`](Supabase::storage) to get a one-time-use [`storage::Storage`] client for interacting | ||
//! with the storage part of Supabase. The client will automatically have authentication (if it's available) | ||
//! when it's first created. | ||
//! | ||
//! ### Auth | ||
//! | ||
//! Auth functions are available directly on the Supabase client. Use the functions [`login_with_email`](Supabase::login_with_email), | ||
//! and [`logout`](Supabase::logout) for basic authentication. The client will automatically handle | ||
//! refreshing if needed when making requests. | ||
//! | ||
//! The session refresh happens if it is less than [`auth::SESSION_REFRESH_GRACE_PERIOD_SECONDS`] seconds | ||
//! from expiring. This means that you should not keep authenticated builders/temporary clients for | ||
//! too long before using them, as they might time out. | ||
//! | ||
//! <div class="warning"> | ||
//! Don't keep authenticated builders/clients from postgrest and storage too long, as they might | ||
//! time out after some time. See details in Auth description above. | ||
//! </div> | ||
//! | ||
//! ## Examples | ||
//! | ||
//! ### Simple postgrest example | ||
//! ```no_run | ||
//! # pub async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
//! let client = suparust::Supabase::new( | ||
//! "https://your.postgrest.endpoint", | ||
//! "your_api_key", | ||
//! None, | ||
//! suparust::SessionChangeListener::Ignore); | ||
//! suparust::auth::SessionChangeListener::Ignore); | ||
//! | ||
//! client.login_with_email( | ||
//! "[email protected]", | ||
|
@@ -30,25 +66,68 @@ | |
//! | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
//! | ||
//! ### Storage example | ||
//! ```no_run | ||
//! # pub async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
//! let client = suparust::Supabase::new( | ||
//! "https://your.postgrest.endpoint", | ||
//! "your_api_key", | ||
//! None, | ||
//! suparust::auth::SessionChangeListener::Ignore); | ||
//! | ||
//! // Login here | ||
//! | ||
//! # use suparust::storage::object::*; | ||
//! let list_request = ListRequest::new("my_folder".to_string()) | ||
//! .limit(10) | ||
//! .sort_by("my_column", SortOrder::Ascending); | ||
//! let objects = client | ||
//! .storage() | ||
//! .await | ||
//! .object() | ||
//! .list("my_bucket", list_request) | ||
//! .await?; | ||
//! | ||
//! let object_names = objects | ||
//! .iter() | ||
//! .map(|object| object.name.clone()); | ||
//! | ||
//! let mut downloaded_objects = vec![]; | ||
//! | ||
//! for object in objects { | ||
//! let downloaded = client | ||
//! .storage() | ||
//! .await | ||
//! .object() | ||
//! .get_one("my_bucket", &object.name) | ||
//! .await?; | ||
//! downloaded_objects.push(downloaded); | ||
//! } | ||
//! | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
mod auth; | ||
pub mod auth; | ||
mod external; | ||
mod postgrest; | ||
pub mod postgrest; | ||
pub mod storage; | ||
#[cfg(test)] | ||
mod tests; | ||
|
||
use std::sync::Arc; | ||
pub use supabase_auth::models::{LogoutScope, Session, User}; | ||
use tokio::sync::RwLock; | ||
|
||
pub type Result<Type> = std::result::Result<Type, SupabaseError>; | ||
|
||
/// The main Supabase client. This is safely cloneable. | ||
#[derive(Clone)] | ||
pub struct Supabase { | ||
auth: Arc<supabase_auth::models::AuthClient>, | ||
session: Arc<RwLock<Option<Session>>>, | ||
session_listener: SessionChangeListener, | ||
session: Arc<RwLock<Option<auth::Session>>>, | ||
session_listener: auth::SessionChangeListener, | ||
postgrest: Arc<RwLock<external::postgrest_rs::Postgrest>>, | ||
storage_client: reqwest::Client, | ||
api_key: String, | ||
|
@@ -57,9 +136,11 @@ pub struct Supabase { | |
|
||
#[derive(thiserror::Error, Debug)] | ||
pub enum SupabaseError { | ||
/// Failed to refresh session | ||
#[error("Failed to refresh session: {0}")] | ||
SessionRefresh(supabase_auth::error::Error), | ||
#[error("Missing authentication information")] | ||
/// Missing authentication information. Maybe you are not logged in? | ||
#[error("Missing authentication information. Maybe you are not logged in?")] | ||
MissingAuthenticationInformation, | ||
#[error("Request failed")] | ||
Reqwest(#[from] reqwest::Error), | ||
|
@@ -69,19 +150,58 @@ pub enum SupabaseError { | |
Internal(#[from] Box<dyn std::error::Error + Send + Sync>), | ||
} | ||
|
||
#[derive(Clone)] | ||
pub enum SessionChangeListener { | ||
Ignore, | ||
Sync(std::sync::mpsc::Sender<Session>), | ||
Async(tokio::sync::mpsc::Sender<Session>), | ||
} | ||
|
||
impl Supabase { | ||
/// Create a new Supabase client | ||
/// | ||
/// # Arguments | ||
/// * `url` - The URL of the Postgrest endpoint | ||
/// * `api_key` - The API key for the Postgrest endpoint | ||
/// * `session` - An optional session to use for authentication. This is typically session | ||
/// information that is either gotten through the listener (next parameter to this function), | ||
/// or externally if you get a valid session from somewhere else (e.g. a magic link). | ||
/// * `session_listener` - A listener for session changes. This can be used to listen for session | ||
/// changes and e.g. update a saved state for use at next run. If you don't need this, you | ||
/// can use `SessionChangeListener::Ignore`. | ||
/// | ||
/// # Example | ||
/// | ||
/// ## Basic usage | ||
/// ```no_run | ||
/// # use suparust::*; | ||
/// let client = Supabase::new( | ||
/// "https://your.postgrest.endpoint", | ||
/// "your_api_key", | ||
/// None, | ||
/// auth::SessionChangeListener::Ignore); | ||
/// ``` | ||
/// | ||
/// ## Persist session information | ||
/// ```no_run | ||
/// # use suparust::*; | ||
/// # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> { | ||
/// # let load_session = || None; | ||
/// | ||
/// let loaded_session = load_session(); // Load session from somewhere | ||
/// | ||
/// let (sender, receiver) = std::sync::mpsc::channel(); | ||
/// | ||
/// let client = Supabase::new( | ||
/// "https://your.postgrest.endpoint", | ||
/// "your_api_key", | ||
/// loaded_session, | ||
/// auth::SessionChangeListener::Sync(sender)); | ||
/// | ||
/// let session = receiver.recv()?; | ||
/// | ||
/// # let save_session = | _session | (); | ||
/// save_session(session); | ||
/// # Ok(()) | ||
/// # } | ||
pub fn new( | ||
url: &str, | ||
api_key: &str, | ||
session: Option<Session>, | ||
session_listener: SessionChangeListener, | ||
session: Option<auth::Session>, | ||
session_listener: auth::SessionChangeListener, | ||
) -> Self { | ||
let mut postgrest = external::postgrest_rs::Postgrest::new(format!("{url}/rest/v1")) | ||
.insert_header("apikey", api_key); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.