import { v2 as cloudinary, UploadApiResponse } from "cloudinary"; import status from "http-status"; import { AppError } from "../shared/errors/app-error"; import { envVars } from "./env"; cloudinary.config({ cloud_name: envVars.CLOUDINARY.CLOUDINARY_CLOUD_NAME, api_key: envVars.CLOUDINARY.CLOUDINARY_API_KEY, api_secret: envVars.CLOUDINARY.CLOUDINARY_API_SECRET, }); export const uploadFileToCloudinary = async ( buffer: Buffer, fileName: string, ): Promise => { if (!buffer || !fileName) { throw new AppError( status.BAD_REQUEST, "File buffer and file name are required for upload", ); } const extension = fileName.split(".").pop()?.toLocaleLowerCase(); const fileNameWithoutExtension = fileName .split(".") .slice(0, -1) .join(".") .toLowerCase() .replace(/\s+/g, "-") // eslint-disable-next-line no-useless-escape .replace(/[^a-z0-9\-]/g, ""); const uniqueName = Math.random().toString(36).substring(2) + "-" + Date.now() + "-" + fileNameWithoutExtension; const folder = extension === "pdf" ? "pdfs" : extension === "mp4" ? "videos" : "images"; return new Promise((resolve, reject) => { cloudinary.uploader .upload_stream( { resource_type: "auto", public_id: `app/${folder}/${uniqueName}`, folder: `app/${folder}`, }, (error, result) => { if (error) { return reject( new AppError( status.INTERNAL_SERVER_ERROR, "Failed to upload file to Cloudinary", ), ); } resolve(result as UploadApiResponse); }, ) .end(buffer); }); }; export const deleteFileFromCloudinary = async (url: string) => { try { const regex = /\/v\d+\/(.+?)(?:\.[a-zA-Z0-9]+)+$/; const match = url.match(regex); if (match && match[1]) { const publicId = match[1]; // try several resource types to ensure deletion for image/video/raw const tryTypes: Array<"image" | "video" | "raw"> = [ "image", "video", "raw", ]; for (const t of tryTypes) { try { await cloudinary.uploader.destroy(publicId, { resource_type: t }); } catch { // continue trying other types } } console.log(`File ${publicId} deleted from cloudinary`); } } catch (error) { console.error("Error deleting file from Cloudinary:", error); throw new AppError( status.INTERNAL_SERVER_ERROR, "Failed to delete file from Cloudinary", ); } }; export const cloudinaryUpload = cloudinary;