feat: implement full CRUD functionality for projects with image upload support and admin dashboard management
This commit is contained in:
38
src/core/storage/minio.ts
Normal file
38
src/core/storage/minio.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
||||
|
||||
export const s3Client = new S3Client({
|
||||
region: "us-east-1",
|
||||
endpoint: process.env.MINIO_ENDPOINT || "http://localhost:9000",
|
||||
forcePathStyle: true, // Required for MinIO
|
||||
credentials: {
|
||||
accessKeyId: process.env.MINIO_ACCESS_KEY || "admin",
|
||||
secretAccessKey: process.env.MINIO_SECRET_KEY || "password123",
|
||||
},
|
||||
});
|
||||
|
||||
export const BUCKET_NAME = process.env.MINIO_BUCKET_NAME || "portfolio";
|
||||
|
||||
/**
|
||||
* Uploads a file to MinIO and returns the public URL
|
||||
*/
|
||||
export async function uploadFileToMinio(file: File): Promise<string> {
|
||||
const bytes = await file.arrayBuffer();
|
||||
const buffer = Buffer.from(bytes);
|
||||
|
||||
// Generate unique filename to prevent overwriting
|
||||
const uniqueName = `${Date.now()}-${file.name.replace(/[^a-zA-Z0-9.-]/g, "_")}`;
|
||||
|
||||
await s3Client.send(
|
||||
new PutObjectCommand({
|
||||
Bucket: BUCKET_NAME,
|
||||
Key: uniqueName,
|
||||
Body: buffer,
|
||||
ContentType: file.type,
|
||||
// Setting ACL public-read ensures the frontend can display the image natively
|
||||
// NOTE: Ensure the MinIO bucket policy itself allows public read if ACL doesn't stick
|
||||
// ACL: "public-read",
|
||||
})
|
||||
);
|
||||
|
||||
return `${process.env.MINIO_ENDPOINT}/${BUCKET_NAME}/${uniqueName}`;
|
||||
}
|
||||
Reference in New Issue
Block a user