imk/backend/imk-backend/src/s3/s3.service.ts
2024-11-02 09:26:40 +01:00

72 lines
2.4 KiB
TypeScript

import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { S3File } from '../interfaces/s3-file.interface';
@Injectable()
export class S3Service {
private readonly s3Client: S3Client;
private readonly logger = new Logger(S3Service.name);
constructor(private readonly configService: ConfigService) {
this.s3Client = new S3Client({
region: this.configService.get<string>('AWS_REGION'),
credentials: {
accessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
secretAccessKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
},
endpoint: this.configService.get<string>('AWS_ENDPOINT_URL'),
forcePathStyle: true, // Required for Contabo Object Storage
});
}
async uploadFile(file: Express.Multer.File, folder: string): Promise<string> {
try {
const key = `${folder}/${Date.now()}-${file.originalname}`;
const command = new PutObjectCommand({
Bucket: this.configService.get<string>('AWS_S3_BUCKET_NAME'),
Key: key,
Body: file.buffer,
ContentType: file.mimetype,
});
await this.s3Client.send(command);
this.logger.debug(`File uploaded successfully: ${key}`);
return key;
} catch (error) {
this.logger.error(`Error uploading file to S3: ${error.message}`);
throw new InternalServerErrorException('Failed to upload file to storage');
}
}
async getFile(key: string): Promise<S3File> {
try {
const command = new GetObjectCommand({
Bucket: this.configService.get<string>('AWS_S3_BUCKET_NAME'),
Key: key,
});
const response = await this.s3Client.send(command);
const chunks = [];
for await (const chunk of response.Body as any) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
return {
buffer,
contentType: response.ContentType || 'application/octet-stream',
contentLength: response.ContentLength || buffer.length,
fileName: key.split('/').pop() || 'download',
};
} catch (error) {
this.logger.error(`Error getting file from S3: ${error.message}`);
throw new InternalServerErrorException('Failed to retrieve file from storage');
}
}
}