126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
const {
|
|
S3Client,
|
|
PutObjectCommand,
|
|
GetObjectCommand,
|
|
ListObjectsV2Command,
|
|
DeleteObjectCommand,
|
|
CopyObjectCommand
|
|
} = require("@aws-sdk/client-s3");
|
|
const { defaultProvider } = require("@aws-sdk/credential-provider-node");
|
|
const { InstanceRegion } = require("./instanceMgr");
|
|
const { isString, isEmpty } = require("lodash");
|
|
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
|
|
|
|
const createS3Client = () => {
|
|
const S3Options = {
|
|
region: InstanceRegion(),
|
|
credentials: defaultProvider()
|
|
};
|
|
|
|
const isLocal = isString(process.env?.LOCALSTACK_HOSTNAME) && !isEmpty(process.env?.LOCALSTACK_HOSTNAME);
|
|
|
|
if (isLocal) {
|
|
S3Options.endpoint = `http://${process.env.LOCALSTACK_HOSTNAME}:4566`;
|
|
S3Options.forcePathStyle = true; // Needed for LocalStack to avoid bucket name as hostname
|
|
}
|
|
|
|
const s3Client = new S3Client(S3Options);
|
|
|
|
/**
|
|
* Uploads a file to the specified S3 bucket and key.
|
|
*/
|
|
const uploadFileToS3 = async ({ bucketName, key, content, contentType }) => {
|
|
const params = {
|
|
Bucket: bucketName,
|
|
Key: key,
|
|
Body: content,
|
|
ContentType: contentType ?? "application/json"
|
|
};
|
|
const command = new PutObjectCommand(params);
|
|
return await s3Client.send(command);
|
|
};
|
|
|
|
/**
|
|
* Downloads a file from the specified S3 bucket and key.
|
|
*/
|
|
const downloadFileFromS3 = async ({ bucketName, key }) => {
|
|
const params = { Bucket: bucketName, Key: key };
|
|
const command = new GetObjectCommand(params);
|
|
const data = await s3Client.send(command);
|
|
return data.Body;
|
|
};
|
|
|
|
/**
|
|
* Lists objects in the specified S3 bucket.
|
|
*/
|
|
const listFilesInS3Bucket = async (bucketName, prefix = "") => {
|
|
const params = { Bucket: bucketName, Prefix: prefix };
|
|
const command = new ListObjectsV2Command(params);
|
|
const data = await s3Client.send(command);
|
|
return data.Contents || [];
|
|
};
|
|
|
|
/**
|
|
* Deletes a file from the specified S3 bucket and key.
|
|
*/
|
|
const deleteFileFromS3 = async ({ bucketName, key }) => {
|
|
const params = { Bucket: bucketName, Key: key };
|
|
const command = new DeleteObjectCommand(params);
|
|
return await s3Client.send(command);
|
|
};
|
|
|
|
/**
|
|
* Copies a file within S3 from a source bucket/key to a destination bucket/key.
|
|
*/
|
|
const copyFileInS3 = async ({ sourceBucket, sourceKey, destinationBucket, destinationKey }) => {
|
|
const params = {
|
|
CopySource: `/${sourceBucket}/${sourceKey}`,
|
|
Bucket: destinationBucket,
|
|
Key: destinationKey
|
|
};
|
|
const command = new CopyObjectCommand(params);
|
|
return await s3Client.send(command);
|
|
};
|
|
|
|
/**
|
|
* Checks if a file exists in the specified S3 bucket and key.
|
|
*/
|
|
const fileExistsInS3 = async ({ bucketName, key }) => {
|
|
try {
|
|
await downloadFileFromS3({ bucketName, key });
|
|
return true;
|
|
} catch (error) {
|
|
if (error.name === "NoSuchKey" || error.name === "NotFound") {
|
|
return false;
|
|
}
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const getPresignedUrl = async ({ bucketName, key }) => {
|
|
const command = new PutObjectCommand({
|
|
Bucket: bucketName,
|
|
Key: key,
|
|
StorageClass: "INTELLIGENT_TIERING"
|
|
});
|
|
const presignedUrl = await getSignedUrl(s3Client, command, { expiresIn: 360 });
|
|
return presignedUrl;
|
|
}
|
|
|
|
return {
|
|
uploadFileToS3,
|
|
downloadFileFromS3,
|
|
listFilesInS3Bucket,
|
|
deleteFileFromS3,
|
|
copyFileInS3,
|
|
fileExistsInS3,
|
|
getPresignedUrl,
|
|
...s3Client
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
module.exports = createS3Client();
|