// /components/files/fileService.js const fs = require('fs/promises'); const path = require('path'); const config = require('../../config/config'); const { uploadToTempBucket, commitTempFile, generatePresignedUrl, getObjectBuffer, deleteFromBucket } = require('../../utils/s3Client'); const AppError = require('../../utils/AppError'); const unlinkQuietly = async (filePath) => { if (!filePath) return; try { await fs.unlink(filePath); } catch { // temp disk file may already be gone } }; const uploadTempFile = async (file) => { const originalName = file?.originalname || file?.originalName; const mimeType = file?.mimetype || file?.mimeType || 'application/octet-stream'; const source = file?.path || file?.buffer; if (!source || !originalName) { throw new AppError('FILE_REQUIRED'); } const ext = path.extname(originalName); const uniquePrefix = `${Date.now()}-${Math.round(Math.random() * 1E9)}`; const tempFileName = `temp-${uniquePrefix}${ext}`; try { const result = await uploadToTempBucket(source, tempFileName, mimeType); return { tempFileName: result.tempFileName, originalName, mimeType, bucket: result.bucket }; } finally { await unlinkQuietly(file.path); } }; const getPresignedUrl = async (filename, bucket = null) => { if (!filename) { throw new AppError('VALIDATION_FAILED', null, 'Filename is required'); } const targetBucket = bucket || config.S3_TEMP_BUCKET; const signedUrl = await generatePresignedUrl(filename, targetBucket); return { filename, bucket: targetBucket, presignedUrl: signedUrl, signedUrl, expiresInSeconds: config.SIGNED_URL_EXPIRES_IN }; }; const getFileContent = async (filename, bucket = null) => { if (!filename) { throw new AppError('VALIDATION_FAILED', null, 'Filename is required'); } return getObjectBuffer(filename, bucket || config.S3_TEMP_BUCKET); }; const commitFile = async (tempFileName, targetFileName = null, targetBucket = 'certificates') => { return commitTempFile(tempFileName, targetFileName, targetBucket); }; const deleteFile = async (filename, bucket = null) => { return deleteFromBucket(filename, bucket || config.S3_TEMP_BUCKET); }; module.exports = { uploadTempFile, getPresignedUrl, getFileContent, commitFile, deleteFile };