diff options
| author | schererleander <leander@schererleander.de> | 2025-07-02 22:17:57 +0200 |
|---|---|---|
| committer | schererleander <leander@schererleander.de> | 2025-07-02 22:17:57 +0200 |
| commit | ab03900adf080da08a0b2a3628fd0dcf0af28420 (patch) | |
| tree | a54ddb49b949929c5c6b4b0bd2b7ca5c504da54d /src/lib/minio.ts | |
| parent | 198f95f079078e60e05d1ea6607ee14f79721a7e (diff) | |
feat: add libraries and utilities
Diffstat (limited to 'src/lib/minio.ts')
| -rw-r--r-- | src/lib/minio.ts | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/lib/minio.ts b/src/lib/minio.ts new file mode 100644 index 0000000..04bf32d --- /dev/null +++ b/src/lib/minio.ts @@ -0,0 +1,99 @@ +import { Client } from 'minio' +import { Readable } from 'stream' + +const minioClient = new Client({ + endPoint: process.env.MINIO_ENDPOINT_HOST || 'localhost', + port: parseInt(process.env.MINIO_ENDPOINT_PORT || '9000', 10), + useSSL: false, //INFO: Set to true if using HTTPS + accessKey: process.env.MINIO_ACCESS_KEY || '', + secretKey: process.env.MINIO_SECRET_KEY || '', +}) + +const BUCKET_NAME = 'widget-storage' + +export async function ensureBucketExists() { + try { + const exists = await minioClient.bucketExists(BUCKET_NAME) + if (!exists) { + await minioClient.makeBucket(BUCKET_NAME, 'us-east-1') + console.log(`Created bucket: ${BUCKET_NAME}`) + + // Set bucket policy for public read access to profile images + const policy = { + Version: '2012-10-17', + Statement: [ + { + Effect: 'Allow', + Principal: { AWS: ['*'] }, + Action: ['s3:GetObject'], + Resource: [`arn:aws:s3:::${BUCKET_NAME}/users/*/profile/*`] + } + ] + } + + await minioClient.setBucketPolicy(BUCKET_NAME, JSON.stringify(policy)) + console.log(`Set bucket policy for ${BUCKET_NAME}`) + } + } catch (error) { + console.error('Error ensuring bucket exists:', error) + throw error + } +} + +export async function uploadToMinio( + key: string, + buffer: Buffer, + contentType: string +): Promise<string> { + try { + await ensureBucketExists() + + const stream = Readable.from(buffer) + + await minioClient.putObject(BUCKET_NAME, key, stream, buffer.length, { + 'Content-Type': contentType, + 'Cache-Control': 'max-age=31536000', // 1 year cache + }) + + const url = `${process.env.MINIO_ENDPOINT ? `http://${process.env.MINIO_ENDPOINT}:9000` : 'http://localhost:9000'}/${BUCKET_NAME}/${key}` + + return url + } catch (error) { + console.error('Error uploading to MinIO:', error) + throw error + } +} + +export async function deleteFromMinio(key: string): Promise<void> { + try { + await minioClient.removeObject(BUCKET_NAME, key) + console.log(`Deleted file: ${key}`) + } catch (error) { + console.error('Error deleting from MinIO:', error) + throw error + } +} + +export async function getPresignedUploadUrl( + key: string, + expiresIn: number = 3600 +): Promise<string> { + try { + await ensureBucketExists() + return await minioClient.presignedPutObject(BUCKET_NAME, key, expiresIn) + } catch (error) { + console.error('Error generating presigned URL:', error) + throw error + } +} + +export async function getFileInfo(key: string) { + try { + return await minioClient.statObject(BUCKET_NAME, key) + } catch (error) { + console.error('Error getting file info:', error) + throw error + } +} + +export default minioClient
\ No newline at end of file |
