@tmlmobilidade/interfaces
Version:
This package provides SDK-style connectors for interacting with databases (e.g., stops, plans, rides, alerts) and external providers (e.g., authentication, storage). It simplifies data access and integration across projects.
181 lines (180 loc) • 5.91 kB
JavaScript
/* * */
import { CopyObjectCommand, CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NotFound, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
/* * */
export class S3StorageProvider {
bucketName;
s3Client;
constructor(config) {
this.s3Client = new S3Client({
credentials: {
accessKeyId: config.access_key_id,
secretAccessKey: config.secret_access_key,
},
endpoint: config.endpoint,
region: config.region,
});
this.bucketName = config.bucket_name;
}
/**
* Checks if the bucket exists and creates it if it doesn't.
*/
async checkBucket() {
try {
await this.s3Client.send(new HeadBucketCommand({ Bucket: this.bucketName }));
}
catch (error) {
if (error instanceof NotFound) {
await this.s3Client.send(new CreateBucketCommand({ Bucket: this.bucketName }));
}
}
}
/**
* Copies a file from one path to another.
* @param source - The source file path and name in S3.
* @param destination - The destination file path and name in S3.
*/
async copyFile(source, destination) {
try {
await this.s3Client.send(new CopyObjectCommand({
Bucket: this.bucketName,
CopySource: `${this.bucketName}/${source}`,
Key: destination,
}));
console.log(`File copied successfully from ${this.bucketName}/${source} to ${this.bucketName}/${destination}`);
}
catch (error) {
console.error('Error copying file:', error);
throw error;
}
}
/**
* Deletes a file from S3.
* @param key - The file path and name in S3.
*/
async deleteFile(key) {
try {
const command = new DeleteObjectCommand({
Bucket: this.bucketName,
Key: key,
});
await this.s3Client.send(command);
console.log(`File deleted successfully from ${this.bucketName}/${key}`);
}
catch (error) {
console.error('Error deleting file:', error);
throw error;
}
}
/**
* Deletes multiple files from S3.
* @param keys - The file paths and names in S3.
*/
async deleteFiles(keys) {
try {
const command = new DeleteObjectsCommand({
Bucket: this.bucketName,
Delete: { Objects: keys.map(key => ({ Key: key })) },
});
await this.s3Client.send(command);
}
catch (error) {
console.error('Error deleting files:', error);
throw error;
}
}
/**
* Downloads a file from S3.
* @param key - The file path and name in S3.
* @returns The file as a readable stream.
*/
async downloadFile(key) {
try {
const command = new GetObjectCommand({
Bucket: this.bucketName,
Key: key,
});
const response = await this.s3Client.send(command);
if (!response.Body) {
throw new Error(`Failed to download file: ${key} does not exist.`);
}
return response.Body;
}
catch (error) {
console.error('Error downloading file:', error);
throw error;
}
}
/**
* Checks if a file exists in S3.
* @param key - The file path and name in S3.
* @returns True if the file exists, false otherwise.
*/
async fileExists(key) {
try {
const command = new HeadObjectCommand({ Bucket: this.bucketName, Key: key });
await this.s3Client.send(command);
return true;
}
catch (error) {
if (error instanceof NotFound) {
return false;
}
throw error;
}
}
/**
* Get the signed URL of a file from the storage.
* @param key - The file path and name in the storage.
* @returns The signed URL of the file.
*/
async getFileUrl(key) {
const command = new GetObjectCommand({
Bucket: this.bucketName,
Key: key,
});
return getSignedUrl(this.s3Client, command, {
expiresIn: 60 * 60 * 24, // 1 day
});
}
/**
* Lists files in an S3 bucket.
* @param prefix - Filter by prefix (optional).
* @returns Array of file keys in the bucket.
*/
async listFiles(prefix) {
try {
const command = new ListObjectsV2Command({
Bucket: this.bucketName,
Prefix: prefix,
});
const response = await this.s3Client.send(command);
return response.Contents ? response.Contents.map(item => item.Key || '') : [];
}
catch (error) {
console.error('Error listing files:', error);
throw error;
}
}
/**
* Uploads a file to S3.
* @param key - The file path and name in S3.
* @param body - The content to upload, either as a string, buffer, or readable stream.
*/
async uploadFile(key, body) {
try {
await this.checkBucket();
const command = new PutObjectCommand({
Body: body,
Bucket: this.bucketName,
Key: key,
});
await this.s3Client.send(command);
console.log(`File uploaded successfully to ${this.bucketName}/${key}`);
}
catch (error) {
console.error('Error uploading file:', error);
throw error;
}
}
}