#File Upload
Alepha handles multipart/form-data uploads through the t.file() schema type. Multipart parsing is built into AlephaServer and active by default.
#Defining Upload Endpoints
Use t.file() in a body schema. When the body contains a file field, the action automatically expects multipart/form-data:
1import { t } from "alepha"; 2import { $action } from "alepha/server"; 3import { $bucket } from "alepha/bucket"; 4 5class UploadController { 6 bucket = $bucket(); 7 8 upload = $action({ 9 method: "POST",10 path: "/upload",11 schema: {12 body: t.object({13 file: t.file(),14 description: t.optional(t.text()),15 }),16 response: t.object({ id: t.text() }),17 },18 handler: async ({ body }) => {19 const fileId = await this.bucket.upload(body.file);20 return { id: fileId };21 },22 });23}
#File Object
The uploaded file implements the FileLike interface:
1interface FileLike { 2 name: string; // Original filename 3 type: string; // MIME type (e.g. "image/png") 4 size: number; // Size in bytes 5 lastModified: number; // Timestamp in milliseconds 6 filepath?: string; // Temporary file path on disk 7 8 stream(): StreamLike; // Read as stream 9 arrayBuffer(): Promise<ArrayBuffer>; // Read into memory10 text(): Promise<string>; // Read as text11}
During the request, uploaded files are written to temporary files in the OS temp directory. They are automatically cleaned up after the response is sent. This approach keeps memory usage low for large files.
FileLike is a minimal interface inspired by the Web File API. It allows to use browser input file directly without mapping!
#Mixed Fields
Combine file fields with regular form fields in the same schema. Non-file fields are extracted from the form data and decoded according to their schema type:
1schema: {2 body: t.object({3 avatar: t.file(),4 username: t.text(),5 bio: t.optional(t.text()),6 }),7}
#Permanent Storage
Temporary files are deleted after the request completes. To keep files permanently, store them using $bucket:
1import { $bucket } from "alepha/bucket";2 3class FileService {4 bucket = $bucket();5 6 async store(file: FileLike): Promise<string> {7 return await this.bucket.upload(file);8 }9}
$bucket supports multiple backends: S3, Cloudflare R2, Vercel Blob, and local filesystem.