#storage #supabase #supabase-storage

supabase-storage-rs

Supabase storage implementation following the official client libraries

6 releases

new 0.1.5 Dec 4, 2024
0.1.4 Dec 3, 2024
0.1.1 Nov 26, 2024

#183 in Database interfaces

Download history 265/week @ 2024-11-25 567/week @ 2024-12-02

832 downloads per month

MIT/Apache

69KB
1K SLoC

Supabase Storage

Crates.io License Crates.io Version docs.rs

This is a Rust implementation of the supabase storage client. The goal is to have feature parity and an easy-to-use API.

Currently this software is functional, but not yet battle-tested.

Installation

Cargo

cargo add supabase-storage-rs

Usage

Create a Storage Client

// You can manually pass in the values
let auth_client = StorageClient::new(project_url, api_key, jwt_secret).unwrap();

// Or you can use environment variables
// Requires `SUPABASE_URL` and`SUPABASE_API_KEY` environment variables
let auth_client = StorageClient::new_from_env().unwrap();

Create a Bucket

Create a new storage bucket. Returns the bucket name (not ID) on success.

let name = client
   .create_bucket(
       "a-cool-name-for-a-bucket",
       None,    // Optional bucket ID
       false,   // Public bucket
       None,    // Allowed MIME types
       None     // File size limit
   )
   .await
   .unwrap();

Delete a Bucket

client.delete_bucket("a-cool-name-for-a-bucket").await.unwrap();

Update a Bucket

client
   .update_bucket(
       "bucket_id",
       true,  // Make bucket public
       None,  // Keep existing MIME types
       None   // Keep existing size limit
   )
   .await
   .unwrap();

Get a Bucket

let bucket = client.get_bucket("a-cool-name-for-a-bucket-with-options").await.unwrap();

// Returns a `Bucket`
pub struct Bucket {
    pub id: String,              // Bucket ID
    pub name: String,            // Bucket name
    pub owner: String,           // Owner's ID
    pub public: bool,            // Public/private status
    pub file_size_limit: Option<i64>,         // Max file size in bytes
    pub allowed_mime_types: Option<Vec<String>>, // Allowed file types
    pub created_at: String,      // Creation timestamp
    pub updated_at: String,      // Last update timestamp
}

List Files in a Bucket

let options = FileSearchOptions {
   limit: Some(5),     // List up to five files
   offset: Some(1),    // Skip the first file
   sort_by: Some(SortBy {
       column: Column::Name,  // Sort by name
       order: Order::Asc,    // In ascending order
   }),
   search: None,       // No search string
};

client
   .list_files(
       "bucket_id", 
       "folder/",   // Path prefix to search
       Some(options) 
   )
   .await
   .unwrap();

List Buckets

let buckets = client.list_buckets().await.unwrap();

Empty a Bucket

let empty = client.empty_bucket("bucket_id").await.unwrap();

Upload a File

let object = client
   .upload_file(
       "bucket_id",
       file,               // File data to upload
       "path/to/file.txt", // Destination path
       Some(options)       // Upload options
   )
   .await
   .unwrap();

Update a File

let object = client
   .update_file(
       "bucket_id",
       file,               // File data
       "path/to/file.txt", // File path
       Some(options)       // File options
   )
   .await
   .unwrap();

Download a File

let file = client
   .download_file(
       "bucket_id",
       "path/to/file.txt", // File path
       Some(options)       // Download options
   )
   .await
   .unwrap();

Copy a File

// Copy within same bucket, including metadata
let key = client
   .copy_file(
       "from_bucket",
       None,                  // Same bucket
       "3.txt",               // Source path
       Some("folder/4.txt"),  // Destination path
       true                   // Copy metadata
   )
   .await
   .unwrap();

// Copy between different buckets
let key = client
   .copy_file(
       "from_bucket",
       Some("to_bucket"),    // Destination bucket
       "a.txt",              // Source path
       Some("folder/b.txt"), // Destination path
       true                  // Copy metadata
   )
   .await
   .unwrap();

Delete a File

let message = client
   .delete_file(
       "upload_tests",         // Bucket ID
       "tests/signed_upload"   // File path
   )
   .await
   .unwrap();

Create a Signed URL

let signed_url = client
   .create_signed_url(
       "bucket_id",        // Bucket ID
       "folder/file.txt",  // File path
       12431234            // Expiry time in seconds
   )
   .await
   .unwrap();

Create Multiple Signed URLs

let urls = client
   .create_multiple_signed_urls(
       "bucket_id",
       vec!["1.txt", "2.txt", "3.txt"], // File paths
       100_000                          // Expiry time in seconds
   )
   .await
   .unwrap();

Create a Signed Upload URL

Returns SignedUploadUrlResponse containing:

url: Path without hostname token: Authorization token

let signed = client
   .create_signed_upload_url(
       "list_files",  // Bucket ID
       "42.txt"       // File path
   )
   .await
   .unwrap();

Upload to a Signed URL

let object = client
   .upload_to_signed_url(
       "bucket_id",
       "upload_token",      // Token from SignedUploadUrlResponse
       file,                // File data as Vec<u8>
       "path/to/file.txt",  // File path
       None                 // File options
   )
   .await
   .unwrap();

Get Public URL

// Basic usage
let url = client
   .get_public_url(
       "photos",                 // Bucket ID
       "vacations/beach.jpg",    // File path
       None                      // No options
   )
   .await
   .unwrap();

// With image transformation
let options = DownloadOptions {
   transform: Some(Transform { 
       width: 300,
       ..Default::default() 
   }),
   download: Some(true)
};

let url = client
   .get_public_url(
       "photos",
       "vacations/beach.jpg",
       Some(options)
   )
   .await
   .unwrap();

Features

  • Create Bucket
  • Delete Bucket
  • Update Buckets
  • Get Bucket
  • List Buckets
  • Empty Bucket
  • Upload a file
  • Update a file
  • Download a file
  • List files in a bucket
  • Replace a file in a bucket
  • Move a file in a bucket
  • Copy a file in a bucket
  • Delete files in a bucket
  • Create signed URL
  • Create multiple signed URLs
  • Create signed upload URLs
  • Upload to a signed URL
  • Retrieve public URL

Contributions

Contributors are always welcome. I only ask that you add or update tests to cover your changes. Until this crate reaches 1.0.0 we're in the "move fast and break things" phase. Don't concern yourself with elegance.

Dependencies

~5–16MB
~204K SLoC