UNPKG

create-apppaaaul

Version:

Create projects as paaauldev would

125 lines (100 loc) 3.74 kB
import { S3Client, PutObjectCommand, DeleteObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; // Configuración del cliente S3 para Cloudflare R2 const createS3Client = () => { const endpoint = process.env.CLOUDFLARE_ENDPOINT; const accessKeyId = process.env.CLOUDFLARE_ACCESS_KEY; const secretAccessKey = process.env.CLOUDFLARE_SECRET_KEY; if (!endpoint || !accessKeyId || !secretAccessKey) { throw new Error("Cloudflare R2 environment variables are not properly configured"); } return new S3Client({ region: "auto", endpoint, credentials: { accessKeyId, secretAccessKey, }, }); }; export interface UploadUrlResponse { presignedUrl: string; publicUrl: string; key: string; } export async function generateUploadUrl( fileName: string, fileType: string, userId: string, ): Promise<UploadUrlResponse> { const s3Client = createS3Client(); const bucketName = process.env.CLOUDFLARE_BUCKET; const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; if (!bucketName) { throw new Error("CLOUDFLARE_BUCKET environment variable is not set"); } if (!accountId) { throw new Error("CLOUDFLARE_ACCOUNT_ID environment variable is not set"); } // Generar nombre único para el archivo const timestamp = Date.now(); const sanitizedFileName = fileName.replace(/[^a-zA-Z0-9.-]/g, "_"); const key = `tickets/${userId}/${timestamp.toString()}-${sanitizedFileName}`; // Crear comando para subir archivo const putCommand = new PutObjectCommand({ Bucket: bucketName, Key: key, ContentType: fileType, }); // Generar URL presignada (válida por 5 minutos) const presignedUrl = await getSignedUrl(s3Client, putCommand, { expiresIn: 300, // 5 minutos }); // URL pública del archivo (después de ser subido) const publicDomain = process.env.CLOUDFLARE_PUBLIC_URL; const publicUrl = publicDomain ? `${publicDomain}/${key}` : `https://${bucketName}.${accountId}.r2.cloudflarestorage.com/${key}`; return { presignedUrl, publicUrl, key, }; } // Función para eliminar un archivo de R2 export async function deleteFile(key: string): Promise<void> { const s3Client = createS3Client(); const bucketName = process.env.CLOUDFLARE_BUCKET; if (!bucketName) { throw new Error("CLOUDFLARE_BUCKET environment variable is not set"); } const deleteCommand = new DeleteObjectCommand({ Bucket: bucketName, Key: key, }); await s3Client.send(deleteCommand); } // Función para extraer la key de una URL pública export function extractKeyFromUrl(publicUrl: string): string | null { try { // Obtener el dominio público configurado const publicDomain = process.env.CLOUDFLARE_PUBLIC_URL; if (publicDomain && publicUrl.startsWith(publicDomain)) { // URL con dominio personalizado: https://images.skinsbrain.com/tickets/user123/1234567890-image.jpg return publicUrl.replace(`${publicDomain}/`, ""); } // URL estándar de R2: https://bucket.accountid.r2.cloudflarestorage.com/tickets/user123/1234567890-image.jpg const bucketName = process.env.CLOUDFLARE_BUCKET; const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; if (bucketName && accountId) { const standardDomain = `https://${bucketName}.${accountId}.r2.cloudflarestorage.com/`; if (publicUrl.startsWith(standardDomain)) { return publicUrl.replace(standardDomain, ""); } } return null; } catch (error) { console.error("Error extracting key from URL:", error); return null; } }