UNPKG

@clipwhisperer/common

Version:

ClipWhisperer Common - Shared library providing core utilities, database schemas, authentication, bucket management, and common functionality across all ClipWhisperer microservices

183 lines (158 loc) 5.41 kB
import { Client } from "minio"; import { createVaultClient } from "./vault.js"; import z from "zod"; export type BucketManagerParams = { vault: { path: string; schema: z.ZodObject<any>; }; }; export default class BucketManager { private minioClient: Client | null = null; public readonly initializationPromise: Promise<void>; private isInitialized: boolean = false; /** * Initializes the bucket manager * @param params - The parameters for the bucket manager */ constructor(params: BucketManagerParams) { this.initializationPromise = this.initialize(params); } /** * Initializes the bucket manager's minio client * @param params - The parameters for the bucket manager */ private async initialize(params: BucketManagerParams) { try { const vault = createVaultClient(); const apiKeys = await vault.readSecret( params.vault.path, params.vault.schema ); const minioConfig = { endPoint: process.env.MINIO_ENDPOINT || "localhost", port: parseInt(process.env.MINIO_PORT || "9000"), useSSL: process.env.MINIO_USE_SSL === "true", accessKey: apiKeys.MINIO_ACCESS_KEY, secretKey: apiKeys.MINIO_SECRET_KEY, }; this.minioClient = new Client(minioConfig); this.isInitialized = true; console.log("✅ Bucket manager initialized successfully"); } catch (error) { console.error("Error initializing bucket manager:", error); this.isInitialized = false; throw error; } } /** * Ensures the bucket manager is initialized before proceeding */ private async ensureInitialized(): Promise<void> { if (!this.isInitialized) { await this.initializationPromise; } if (!this.minioClient) { throw new Error("Minio client not initialized"); } } /** * Checks if a bucket exists and creates it if it doesn't * @param bucketName - The name of the bucket to check * @returns {Promise<boolean>} True if the bucket exists, false otherwise */ async checkBucketExists(bucketName: string): Promise<boolean> { await this.ensureInitialized(); const exists = await this.minioClient!.bucketExists(bucketName); if (!exists) { await this.minioClient!.makeBucket(bucketName); console.log(`✅ Created bucket: ${bucketName}`); } return exists; } /** * Uploads a file to a bucket * @param bucketName - The name of the bucket to upload to * @param filePath - The path to the file to upload * @param objectName - The name of the object to upload * @param metadata - Optional metadata to add to the file */ async uploadFile( bucketName: string, filePath: string, objectName: string, metadata?: Record<string, string> ) { await this.ensureInitialized(); await this.checkBucketExists(bucketName); await this.minioClient!.fPutObject( bucketName, objectName, filePath, metadata ); console.log(`✅ Successfully uploaded: ${bucketName}/${objectName}`); } /** * Gets a video file from a bucket * @param bucketName - The name of the bucket * @param videoUuid - The UUID of the video * @param uuid - The user UUID * @returns {Promise<string>} The URL or path to the video file */ async getVideo( bucketName: string, videoUuid: string, uuid: string ): Promise<string> { await this.ensureInitialized(); await this.checkBucketExists(bucketName); const objectName = `${uuid}/${videoUuid}/video.mp4`; // Check if the video exists try { await this.minioClient!.statObject(bucketName, objectName); console.log(`✅ Video found: ${bucketName}/${objectName}`); // Return the presigned URL for the video (valid for 1 hour) const presignedUrl = await this.minioClient!.presignedGetObject( bucketName, objectName, 3600 ); return presignedUrl; } catch (error) { console.error(`❌ Video not found: ${bucketName}/${objectName}`); throw new Error(`Video not found: ${objectName}`); } } /** * Gets a thumbnail image from a bucket * @param bucketName - The name of the bucket * @param videoUuid - The UUID of the video * @param uuid - The user UUID * @returns {Promise<string>} The URL or path to the thumbnail image */ async getThumbnail( bucketName: string, videoUuid: string, uuid: string ): Promise<string> { await this.ensureInitialized(); await this.checkBucketExists(bucketName); const objectName = `${uuid}/${videoUuid}/thumbnail.jpg`; // Check if the thumbnail exists try { await this.minioClient!.statObject(bucketName, objectName); console.log(`✅ Thumbnail found: ${bucketName}/${objectName}`); // Return the presigned URL for the thumbnail (valid for 1 hour) const presignedUrl = await this.minioClient!.presignedGetObject( bucketName, objectName, 3600 ); return presignedUrl; } catch (error) { console.error(`❌ Thumbnail not found: ${bucketName}/${objectName}`); throw new Error(`Thumbnail not found: ${objectName}`); } } }