#Buckets
$bucket provides a file storage abstraction that works across multiple backends: local filesystem, S3-compatible stores, Cloudflare R2, Vercel Blob, Azure Blob Storage, and in-memory (for testing).
1import { $bucket } from "alepha/bucket";
#Defining a Bucket
Declare a bucket as a class property with optional MIME type and size constraints:
1import { $bucket } from "alepha/bucket"; 2 3class MediaService { 4 images = $bucket({ 5 name: "user-images", 6 mimeTypes: ["image/jpeg", "image/png", "image/webp"], 7 maxSize: 5, // MB 8 }); 9 10 documents = $bucket({11 name: "documents",12 mimeTypes: ["application/pdf", "text/plain"],13 maxSize: 50, // MB14 });15}
#Options
| Option | Type | Default | Description |
|---|---|---|---|
name |
string |
Property key name | Unique bucket identifier used for storage partitioning |
mimeTypes |
string[] |
All types allowed | Allowed MIME types. Rejects uploads with non-matching types |
maxSize |
number |
10 |
Maximum file size in MB |
description |
string |
- | Human-readable description of the bucket's purpose |
provider |
Service or "memory" |
Injected FileStorageProvider |
Override the storage backend for this bucket |
#Methods
#upload
Upload a file. Returns a string file ID.
1const fileId = await this.images.upload(file);
The file parameter accepts a FileLike object (compatible with the browser File API). Upload validates MIME type and file size against bucket constraints. Throws InvalidFileError if validation fails.
You can override bucket-level constraints per upload:
1const fileId = await this.images.upload(file, {2 mimeTypes: ["image/png"],3 maxSize: 2,4});
#download
Download a file by its ID. Returns a FileLike object.
1const file = await this.documents.download(fileId);
#exists
Check whether a file exists in the bucket.
1const found = await this.images.exists(fileId);
#delete
Permanently delete a file from the bucket.
1await this.images.delete(fileId);
#Storage Providers
The default provider depends on the environment:
- Test / Serverless:
MemoryFileStorageProvider(in-memory, lost on restart) - Other environments:
LocalFileStorageProvider(writes to local filesystem)
#Available Providers
| Provider | Package | Description |
|---|---|---|
MemoryFileStorageProvider |
alepha/bucket |
In-memory storage for testing |
LocalFileStorageProvider |
alepha/bucket |
Local filesystem storage |
CloudflareR2Provider |
alepha/bucket |
Cloudflare R2 (S3-compatible) |
S3FileStorageProvider |
@alepha/bucket-s3 |
AWS S3 / MinIO |
VercelFileStorageProvider |
@alepha/bucket-vercel |
Vercel Blob |
AzureBlobStorageProvider |
@alepha/bucket-azure |
Azure Blob Storage |
#Configuring a Provider
Override the default provider globally:
1import { AlephaBucket, FileStorageProvider } from "alepha/bucket";2import { S3FileStorageProvider } from "@alepha/bucket-s3";3 4const alepha = Alepha.create()5 .with(AlephaBucket)6 .with({ provide: FileStorageProvider, use: S3FileStorageProvider });
Or per bucket:
1import { S3FileStorageProvider } from "@alepha/bucket-s3"; 2 3class MediaService { 4 images = $bucket({ 5 name: "user-images", 6 provider: S3FileStorageProvider, 7 }); 8 9 tempFiles = $bucket({10 name: "temp",11 provider: "memory",12 });13}
#Events
Bucket operations emit lifecycle events:
| Event | Payload |
|---|---|
bucket:file:uploaded |
{ id, file, bucket, options } |
bucket:file:deleted |
{ id, bucket } |
These events can be used to trigger side effects such as creating database records, generating thumbnails, or sending notifications.
#Testing
In tests, the MemoryFileStorageProvider is used by default. Use MemoryFileStorageProvider from alepha/bucket to inspect stored files in test assertions:
1const alepha = Alepha.create(); 2 3class TestApp { 4 media = $bucket({ name: "test-media" }); 5} 6 7const app = alepha.inject(TestApp); 8await alepha.start(); 9 10const fileId = await app.media.upload(someFile);11const exists = await app.media.exists(fileId);12expect(exists).toBe(true);