import { Client } from 'minio'; import { MinioConfig } from '../config'; /** * Service for handling MinIO operations */ export class MinioService { private client: Client; private bucketName: string; private readonly defaultExpiry = 60 * 60; // 1 hour in seconds private initialized = false; /** * Creates a new MinioService instance * @param config - MinIO configuration */ constructor(config: MinioConfig) { this.client = new Client(config); this.bucketName = config.bucketName; } /** * Initializes the MinIO service by ensuring the bucket exists */ public async initialize(): Promise { if (this.initialized) { return; } const bucketExists = await this.client.bucketExists(this.bucketName); if (!bucketExists) { await this.client.makeBucket(this.bucketName, 'us-east-1'); // Set the bucket policy to allow public read access const policy = { Version: '2012-10-17', Statement: [ { Effect: 'Allow', Principal: { AWS: ['*'] }, Action: ['s3:GetObject'], Resource: [`arn:aws:s3:::${this.bucketName}/*`], }, ], }; await this.client.setBucketPolicy( this.bucketName, JSON.stringify(policy) ); } this.initialized = true; } /** * Generates a presigned URL for uploading a file * @param objectName - Name of the object to upload * @param expiryInSeconds - Expiry time in seconds (default: 1 hour) * @returns Presigned URL for uploading */ public async generateUploadUrl( objectName: string, expiryInSeconds: number = this.defaultExpiry ): Promise { return this.client.presignedPutObject( this.bucketName, objectName, expiryInSeconds ); } /** * Generates a presigned URL for downloading a file * @param objectName - Name of the object to download * @param expiryInSeconds - Expiry time in seconds (default: 1 hour) * @returns Presigned URL for downloading */ public async generateDownloadUrl( objectName: string, expiryInSeconds: number = this.defaultExpiry ): Promise { return this.client.presignedGetObject( this.bucketName, objectName, expiryInSeconds ); } /** * Checks if an object exists in the bucket * @param objectName - Name of the object to check * @returns True if the object exists, false otherwise */ public async objectExists(objectName: string): Promise { try { await this.client.statObject(this.bucketName, objectName); return true; } catch (_error) { return false; } } /** * Deletes an object from the bucket * @param objectName - Name of the object to delete */ public async deleteObject(objectName: string): Promise { await this.client.removeObject(this.bucketName, objectName); } }