const File = require('./fileModel') const AppError = require('../../globalErrorHandler/AppError') const util = require('util') const fs = require('fs') const { uploadObject, deleteObject, listOfObjects, signedUrl, copyObject, removeObject, } = require('../../utils/upload/bucket') const deleteTempFile = util.promisify(fs.unlink) const bucketSingleUpload = async (file, bucketName) => { const fileData = { originalName: file.originalname, filename: file.filename, path: file.path, } const result = await uploadObject(fileData, bucketName) const data = { fileURL: result.fileURL, fileName: result.fileName, fileEndpoint: result.fileEndpoint, bucketName, } // Delete file from uploads folder await deleteTempFile(file.path) const fileRecord = await createFile(data) return { status: 'success', fileRecord, } } const bucketMultiUpload = async (files, bucketName) => { const results = [] for (let file of files) { const result = await bucketSingleUpload(file, bucketName) results.push(result) } return results } const bucketDeleteFile = async (fileName, bucketName) => { let exportedFileName = getLastUrlSegment(fileName) await deleteObject(exportedFileName, bucketName) await deleteFile(exportedFileName) return { fileName } } const getLastUrlSegment = (url) => { if (!url.includes('/')) { return url } const cleanUrl = url.endsWith('/') ? url.slice(0, -1) : url const segments = cleanUrl.split('/') return segments[segments.length - 1] } const getAllFiles = async () => { return File.find({}, null, null) } const getFile = async (fileId) => { const file = await File.findById(fileId, null, null) if (!file) { throw new AppError('NoFileFound', 404, {}) } return file } const createFile = async (data) => { return File.create(data, null) } const updateFile = async (fileId, data) => { const file = await File.findOneAndUpdate({ _id: fileId }, data, null) if (!file) { throw AppError('NoFileFound', 404, {}) } return file } const deleteFile = async (fileName) => { await File.findOneAndDelete({ fileName }, null) return null } const bucketGetFiles = async (bucketName) => { return listOfObjects(bucketName) } const getSignedUrl = async (fileName, bucketName) => { if (!fileName) { return } return signedUrl(bucketName, fileName) } const getMultipleSignedUrls = async (fileNameArray, bucketName) => { const urls = [] for (let fileName of fileNameArray) { urls.push({ url: await getSignedUrl(fileName, bucketName), fileName: fileName}) } return urls } const moveFromTempToMain = async (files, targetBucket) => { const tempBucket = 'temp' for (const file of files) { await copyObject(targetBucket, file, `${tempBucket}/${file}`) await removeObject(tempBucket, file) } } const getImage = async (bucketName, fileName) => { if (!fileName) { throw new AppError('NoFileFound', 404, {}) } // Get signed URL from the file service const signedUrl = await getSignedUrl(fileName, bucketName); if (!signedUrl) { return null; } // Fetch the image from the signed URL const response = await fetch(signedUrl); if (!response.ok) { throw new AppError('NoFileFound', 404, {}) } // Get the content type from the response headers const contentType = response.headers.get('content-type'); // Convert the response to a buffer const buffer = await response.arrayBuffer(); // Return both the buffer and content type return { buffer: Buffer.from(buffer), contentType }; }; module.exports = { moveFromTempToMain, getMultipleSignedUrls, getSignedUrl, createFile, updateFile, deleteFile, getAllFiles, getFile, bucketSingleUpload, bucketMultiUpload, bucketDeleteFile, bucketGetFiles, getImage, }