const { S3Client, PutObjectCommand, DeleteObjectCommand } = require('@aws-sdk/client-s3'); const { v4: uuidv4 } = require('uuid'); const path = require('path'); const fs = require('fs'); const { logger } = require('../middleware/logger'); const exoscaleClient = new S3Client({ region: process.env.EXOSCALE_REGION, endpoint: process.env.EXOSCALE_ENDPOINT, credentials: { accessKeyId: process.env.EXOSCALE_ACCESS_KEY, secretAccessKey: process.env.EXOSCALE_SECRET_KEY, }, forcePathStyle: true, }); const EXOSCALE_BUCKET = process.env.EXOSCALE_BUCKET; async function uploadBuffer(buffer, originalName, mimeType, folder = 'user-uploads') { logger.info('exoscaleUploader.uploadBuffer:start', { originalName, mimeType, folder }); try { const ext = path.extname(originalName); const key = `${folder}/${uuidv4()}${ext}`; const command = new PutObjectCommand({ Bucket: EXOSCALE_BUCKET, Key: key, Body: buffer, ContentType: mimeType, ACL: 'private', }); await exoscaleClient.send(command); logger.info('exoscaleUploader.uploadBuffer:success', { key, mimeType }); return { objectKey: key, url: `${process.env.EXOSCALE_ENDPOINT}/${EXOSCALE_BUCKET}/${key}`, }; } catch (error) { logger.error('exoscaleUploader.uploadBuffer:error', { originalName, error: error.message }); throw error; } } async function uploadFile(filePath, originalName, mimeType, folder = 'user-uploads') { logger.info('exoscaleUploader.uploadFile:start', { filePath, originalName, mimeType, folder }); try { const buffer = fs.readFileSync(filePath); const result = await uploadBuffer(buffer, originalName, mimeType, folder); logger.info('exoscaleUploader.uploadFile:success', { filePath, key: result.objectKey }); return result; } catch (error) { logger.error('exoscaleUploader.uploadFile:error', { filePath, error: error.message }); throw error; } } async function deleteObject(objectKey) { logger.info('exoscaleUploader.deleteObject:start', { objectKey }); try { const command = new DeleteObjectCommand({ Bucket: EXOSCALE_BUCKET, Key: objectKey, }); await exoscaleClient.send(command); logger.info('exoscaleUploader.deleteObject:success', { objectKey }); return true; } catch (error) { logger.error('exoscaleUploader.deleteObject:error', { objectKey, error: error.message }); throw error; } } module.exports = { uploadBuffer, uploadFile, s3: exoscaleClient, // Export the S3 client deleteObject, // Export delete helper };