imk/backend/imk-backend/src/s3/s3.service.ts
2024-11-02 00:08:04 +01:00

103 lines
2.8 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import {
S3Client,
DeleteObjectCommand,
GetObjectCommand,
ListObjectsCommand,
PutObjectCommand,
} from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { Upload } from '@aws-sdk/lib-storage';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class S3Service {
private s3Client: S3Client;
private readonly logger = new Logger(S3Service.name);
constructor(private configService: ConfigService) {
this.s3Client = new S3Client({
region: this.configService.get('AWS_REGION'),
endpoint: this.configService.get('AWS_ENDPOINT_URL'),
credentials: {
accessKeyId: this.configService.get('AWS_ACCESS_KEY_ID'),
secretAccessKey: this.configService.get('AWS_SECRET_ACCESS_KEY'),
},
forcePathStyle: true, // Needed for non-AWS S3 compatible services
});
}
async getObject(key: string) {
try {
const command = new GetObjectCommand({
Bucket: this.configService.get('AWS_S3_BUCKET_NAME'),
Key: key,
});
const response = await this.s3Client.send(command);
return response;
} catch (error) {
this.logger.error(`Error getting object from S3: ${error.message}`);
throw error;
}
}
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('AWS_S3_BUCKET_NAME'),
Key: key,
Body: file.buffer,
ContentType: file.mimetype,
});
await this.s3Client.send(command);
return key;
} catch (error) {
this.logger.error(`Error uploading file to S3: ${error.message}`);
throw error;
}
}
async deleteFile(key: string): Promise<void> {
try {
const command = new DeleteObjectCommand({
Bucket: this.configService.get('AWS_S3_BUCKET_NAME'),
Key: key,
});
await this.s3Client.send(command);
} catch (error) {
this.logger.error(`Error deleting file from S3: ${error.message}`);
throw error;
}
}
async getFileUrl(key: string): Promise<string> {
const command = new GetObjectCommand({
Bucket: this.configService.get('AWS_S3_BUCKET_NAME'),
Key: key,
});
const url = await getSignedUrl(this.s3Client, command, { expiresIn: 3600 }); // URL expires in 1 hour
return url;
}
async testConnection(): Promise<boolean> {
try {
await this.getObject('test-connection');
return true;
} catch (error) {
if (error.name === 'NoSuchKey') {
// This is expected as we're just testing connection
return true;
}
this.logger.error('Failed to connect to S3', error);
return false;
}
}
}