/** * Utilities for mission-related file paths and uploads */ import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; // Initialize S3 client for Minio const s3Client = new S3Client({ region: 'us-east-1', endpoint: 'https://dome-api.slm-lab.net', credentials: { accessKeyId: '4aBT4CMb7JIMMyUtp4Pl', secretAccessKey: 'HGn39XhCIlqOjmDVzRK9MED2Fci2rYvDDgbLFElg' }, forcePathStyle: true // Required for MinIO }); // Generate the mission logo path in Minio export function getMissionLogoPath(userId: string, missionId: string, fileExtension: string): string { // Use a consistent path structure: missions/{missionId}/logo{extension} return `missions/${missionId}/logo${fileExtension}`; } // Generate the mission attachment path in Minio export function getMissionAttachmentPath(userId: string, missionId: string, filename: string): string { // Use a consistent path structure: missions/{missionId}/attachments/{filename} return `missions/${missionId}/attachments/${filename}`; } // Helper function to ensure a path has the missions/ prefix export function ensureMissionsPrefix(path: string): string { return path.startsWith('missions/') ? path : `missions/${path}`; } // Helper function to construct a public URL for a mission file export function getMissionFileUrl(path: string): string { const normalizedPath = ensureMissionsPrefix(path); return `/api/missions/image/${normalizedPath}`; } // Helper function to delete a mission logo export async function deleteMissionLogo(missionId: string, logoPath: string): Promise { try { const normalizedPath = ensureMissionsPrefix(logoPath); // Add your S3/MinIO deletion logic here console.log('Deleting mission logo:', { missionId, originalPath: logoPath, normalizedPath }); } catch (error) { console.error('Error deleting mission logo:', { error, missionId, logoPath, errorType: error instanceof Error ? error.constructor.name : typeof error, message: error instanceof Error ? error.message : String(error) }); throw error; } } // Upload a mission logo to Minio export async function uploadMissionLogo(userId: string, missionId: string, file: File): Promise<{ filePath: string }> { try { console.log('Starting logo upload:', { userId, missionId, fileName: file.name, fileSize: file.size, fileType: file.type }); const fileExtension = file.name.substring(file.name.lastIndexOf('.')); const filePath = getMissionLogoPath(userId, missionId, fileExtension); const minioPath = filePath.replace(/^missions\//, ''); // Remove prefix for Minio // Convert File to Buffer const arrayBuffer = await file.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); console.log('Uploading to Minio:', { bucket: 'missions', key: minioPath, contentType: file.type }); await s3Client.send(new PutObjectCommand({ Bucket: 'missions', Key: minioPath, Body: buffer, ContentType: file.type, ACL: 'public-read' })); console.log('Logo upload successful:', { filePath, minioPath }); return { filePath }; } catch (error) { console.error('Error uploading mission logo:', { error, userId, missionId, fileName: file.name, errorType: error instanceof Error ? error.constructor.name : typeof error, message: error instanceof Error ? error.message : String(error) }); throw error; } } // Upload a mission attachment to Minio export async function uploadMissionAttachment( userId: string, missionId: string, file: File ): Promise<{ filename: string; filePath: string; fileType: string; fileSize: number; }> { try { console.log('Starting attachment upload:', { userId, missionId, fileName: file.name, fileSize: file.size, fileType: file.type }); const filePath = getMissionAttachmentPath(userId, missionId, file.name); const minioPath = filePath.replace(/^missions\//, ''); // Remove prefix for Minio // Convert File to Buffer const arrayBuffer = await file.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); console.log('Uploading to Minio:', { bucket: 'missions', key: minioPath, contentType: file.type }); await s3Client.send(new PutObjectCommand({ Bucket: 'missions', Key: minioPath, Body: buffer, ContentType: file.type, ACL: 'public-read' })); console.log('Attachment upload successful:', { filePath, minioPath }); return { filename: file.name, filePath, fileType: file.type, fileSize: file.size }; } catch (error) { console.error('Error uploading mission attachment:', { error, userId, missionId, fileName: file.name, errorType: error instanceof Error ? error.constructor.name : typeof error, message: error instanceof Error ? error.message : String(error) }); throw error; } } // Generate a presigned URL for direct upload to Minio (for logo) export async function generateMissionLogoUploadUrl( userId: string, missionId: string, fileExtension: string ): Promise<{ uploadUrl: string; filePath: string }> { const filePath = getMissionLogoPath(userId, missionId, fileExtension); const minioPath = filePath.replace(/^missions\//, ''); // TODO: Implement presigned URL generation // This would require additional AWS SDK functionality throw new Error('Presigned URL generation not implemented'); } // Generate a presigned URL for direct upload to Minio (for attachment) export async function generateMissionAttachmentUploadUrl( userId: string, missionId: string, filename: string ): Promise<{ uploadUrl: string; filePath: string }> { const filePath = getMissionAttachmentPath(userId, missionId, filename); const minioPath = filePath.replace(/^missions\//, ''); // TODO: Implement presigned URL generation // This would require additional AWS SDK functionality throw new Error('Presigned URL generation not implemented'); }