Plugin: File Storage
Relevant source files
The following files were used as context for generating this wiki page:The File Storage plugin for Better Auth Kit provides a generic interface to manage uploading, deleting, and downloading files from a configurable file storage service. It is designed to be provider-agnostic, allowing developers to integrate with various storage solutions like UploadThing by implementing a simple storage provider interface.
The plugin dynamically creates API endpoints based on a user-defined file router, enabling different configurations for various file types or use cases within an application. It handles the server-side logic for file operations and also exposes a dedicated endpoint for retrieving files, acting as a proxy between the client and the underlying storage provider.
Sources: packages/plugins/file-storage/README.md, packages/plugins/file-storage/package.json, packages/plugins/file-storage/src/index.ts:31-34
Architecture Overview
The plugin operates by connecting a client application to a storage provider through a set of dynamically generated API endpoints. The core components are the fileRouter, which defines the available file routes, and the storageProvider, which implements the actual file handling logic.
This diagram illustrates the high-level data flow for a file upload operation.
Core Components
fileStorage Function
This is the main entry point for the plugin. It takes a configuration object and returns a BetterAuthPlugin instance with the necessary endpoints and metadata.
Sources: packages/plugins/file-storage/src/index.ts:31-34
Configuration (FileStorageOptions)
The plugin is initialized with a configuration object that defines its behavior.
| Option | Type | Description |
|---|---|---|
storageProvider | StorageProvider | An object that implements the uploadFile and deleteFile methods to interact with the actual file storage service. |
fileRouter | Record<string, FileRoute> | An object where each key represents a file path (e.g., "profileImages") and the value is a FileRoute object defining permissions and limits. |
Sources: packages/plugins/file-storage/src/index.ts:32
An example of a storage provider is @better-auth-kit/fs-uploadthing, which integrates with UploadThing.
Sources: packages/libraries/fs-uploadthing/package.json
File Router (fileRouter)
The fileRouter is a key part of the configuration. It allows developers to define multiple, distinct "routes" for file uploads. Each route is an entry in the fileRouter object, where the key becomes part of the API endpoint path. This enables different validation rules, permissions, or storage logic for different types of files (e.g., user avatars vs. project documents).
Sources: packages/plugins/file-storage/src/index.ts:35-37
API Endpoints
The plugin dynamically generates endpoints for uploading and deleting files based on the keys provided in the fileRouter configuration. It also provides a static endpoint for retrieving files.
Dynamic Endpoints
For each path defined in fileRouter, the following endpoints are created:
| Endpoint Name | Method | Path | Request Body | Response Type |
|---|---|---|---|---|
upload<TransformedPath> | POST | /file-storage/upload/:path | z.instanceof(File) | UploadReturnType |
delete<TransformedPath> | POST | /file-storage/delete/:path | (Not specified) | DeleteReturnType |
The <TransformedPath> is the PascalCased version of the path key from the fileRouter.
Sources: packages/plugins/file-storage/src/index.ts:37-64
Static Endpoint
A single endpoint is available for fetching files.
| Endpoint Name | Method | Path | Description |
|---|---|---|---|
getFile | GET | /fs/:path/:key | Retrieves a file by its path and key, fetching it from the provider's URL and streaming it to the client. |
Sources: packages/plugins/file-storage/src/index.ts:94-138
Operational Flows
File Upload Flow
The following sequence diagram details the process of uploading a file.
This flow shows the client sending a file, the API using the configured storage provider to perform the upload, and returning a set of URLs to the client. The fileStorageURL is a proxied URL through the Better Auth backend.
Sources: packages/plugins/file-storage/src/index.ts:41-57
File Retrieval Flow
This diagram shows how a client retrieves a previously uploaded file.
The system first looks up the file's metadata in the local database via the adapter. If found, it fetches the actual file content from the external URL provided by the storage provider and streams it back to the client.
Sources: packages/plugins/file-storage/src/index.ts:94-138, packages/cli/src/commands/db/database-explorer-plugin.ts:40-53
Database Interaction
The getFile endpoint implies the existence of a fileStorage table or collection in the database, which is managed by the Better Auth adapter. This table is used to map the internal file path and key to the external URL provided by the storage provider.
The inferred schema for this table is as follows:
This structure is derived from the findOne query within the getFile endpoint implementation.
Sources: packages/plugins/file-to-storage/src/index.ts:106-119
Error Codes
The plugin defines a set of specific error codes to provide clear feedback on failed operations.
| Code | Description |
|---|---|
FILE_TOO_LARGE | The uploaded file exceeds the configured size limit for the route. |
INVALID_FILE_TYPE | The file's MIME type is not allowed for the route. |
USER_NOT_LOGGED_IN | An unauthenticated user attempted an action that requires authentication. |
USER_NOT_FOUND | The user associated with the request could not be found. |
USER_NOT_ALLOWED | The authenticated user does not have permission to perform the action. |
INVALID_BLOB | The provided file data is invalid or corrupt. |
FILE_NOT_FOUND | The requested file does not exist. |
MISSING_REQUEST_BODY | The request is missing the expected body. |
USER_DOES_NOT_OWN_IMAGE | A user is attempting to delete a file they do not own. |
FAILED_TO_UPLOAD_IMAGE | The storage provider failed to upload the image for an unknown reason. |