Skip to main content

File Uploads

The Store wire supports file uploads to Amazon S3, Google Cloud Storage, or local disk.

Providers

ProviderDescription
s3Amazon S3 or S3-compatible (MinIO, DigitalOcean Spaces)
gcsGoogle Cloud Storage
localLocal filesystem (development only)

Configuration

Amazon S3

store({
uploads: {
provider: "s3",
bucket: "my-app-uploads",
region: "us-east-1",
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
maxFileSize: "10mb",
allowedTypes: ["image/*", "application/pdf", "text/*"],
},
});

S3-Compatible (MinIO)

store({
uploads: {
provider: "s3",
bucket: "my-bucket",
endpoint: "http://localhost:9000",
accessKeyId: "minioadmin",
secretAccessKey: "minioadmin",
forcePathStyle: true,
},
});

Local Disk

store({
uploads: {
provider: "local",
directory: "./uploads",
servePublicly: true,
publicPath: "/files",
},
});

Uploading Files

Programmatic

import fs from "fs";

const buffer = fs.readFileSync("photo.jpg");

const file = await app.store.upload({
buffer,
filename: "photo.jpg",
contentType: "image/jpeg",
metadata: {
userId: "user-123",
category: "avatar",
},
});

console.log(file._id); // MongoDB ObjectId
console.log(file.url); // Public URL to the file
console.log(file.size); // File size in bytes

REST API

curl -X POST http://localhost:3000/store/upload \
-H "Authorization: Bearer eyJhbGci..." \
-F "file=@photo.jpg" \
-F "metadata={\"category\":\"avatar\"}"

Response (201):

{
"_id": "65a1b2c3d4e5f6a7b8c9d0e1",
"filename": "photo.jpg",
"originalName": "photo.jpg",
"contentType": "image/jpeg",
"size": 245760,
"url": "https://my-bucket.s3.amazonaws.com/uploads/abc123-photo.jpg",
"metadata": { "category": "avatar" },
"createdAt": "2025-01-15T10:30:00.000Z"
}

Listing Files

curl "http://localhost:3000/store/files?limit=20&contentType=image/*" \
-H "Authorization: Bearer eyJhbGci..."

Response (200):

{
"files": [
{
"_id": "65a1b2c3d4e5f6a7b8c9d0e1",
"filename": "photo.jpg",
"contentType": "image/jpeg",
"size": 245760,
"url": "https://...",
"createdAt": "2025-01-15T10:30:00.000Z"
}
],
"total": 42,
"limit": 20,
"offset": 0
}

Deleting Files

// Programmatic
await app.store.deleteFile(fileId);
# REST API
curl -X DELETE http://localhost:3000/store/files/65a1b2c3d4e5f6a7b8c9d0e1 \
-H "Authorization: Bearer eyJhbGci..."

File Validation

Configure allowed file types and maximum size:

store({
uploads: {
maxFileSize: "10mb",
allowedTypes: [
"image/jpeg",
"image/png",
"image/webp",
"application/pdf",
],
},
});

Wildcard types are supported: "image/*" matches any image type.