94 lines
1.9 KiB
JavaScript
94 lines
1.9 KiB
JavaScript
const {
|
|
S3Client,
|
|
PutObjectCommand,
|
|
DeleteObjectCommand,
|
|
} = require("@aws-sdk/client-s3");
|
|
|
|
const config = {
|
|
bucket: process.env.BUCKET_NAME,
|
|
region: process.env.BUCKET_REGION || "us-west-2",
|
|
endpoint: process.env.PARSPACK_S3_ENDPOINT,
|
|
accessKeyId: process.env.BUCKET_ACCESS_KEY,
|
|
secretAccessKey: process.env.BUCKET_SECRET_KEY,
|
|
publicUrl: process.env.BUCKET_PUBLIC_URL || process.env.PARSPACK_S3_ENDPOINT,
|
|
};
|
|
|
|
let s3Client = null;
|
|
|
|
const isConfigured = () =>
|
|
Boolean(
|
|
config.bucket &&
|
|
config.endpoint &&
|
|
config.accessKeyId &&
|
|
config.secretAccessKey
|
|
);
|
|
|
|
const getClient = () => {
|
|
if (!isConfigured()) {
|
|
throw new Error("S3 storage is not configured");
|
|
}
|
|
|
|
if (!s3Client) {
|
|
s3Client = new S3Client({
|
|
region: config.region,
|
|
endpoint: config.endpoint,
|
|
credentials: {
|
|
accessKeyId: config.accessKeyId,
|
|
secretAccessKey: config.secretAccessKey,
|
|
},
|
|
forcePathStyle: true,
|
|
});
|
|
}
|
|
|
|
return s3Client;
|
|
};
|
|
|
|
const normalizeKey = (key) => key.replace(/^\/+/, "");
|
|
|
|
const getPublicUrl = (key) => {
|
|
const normalizedKey = normalizeKey(key);
|
|
const baseUrl = (config.publicUrl || config.endpoint).replace(/\/+$/, "");
|
|
return `${baseUrl}/${normalizedKey}`;
|
|
};
|
|
|
|
const uploadBuffer = async (
|
|
key,
|
|
buffer,
|
|
contentType = "application/octet-stream"
|
|
) => {
|
|
const normalizedKey = normalizeKey(key);
|
|
|
|
await getClient().send(
|
|
new PutObjectCommand({
|
|
Bucket: config.bucket,
|
|
Key: normalizedKey,
|
|
Body: buffer,
|
|
ContentType: contentType,
|
|
ACL: "public-read",
|
|
})
|
|
);
|
|
|
|
return {
|
|
key: normalizedKey,
|
|
url: getPublicUrl(normalizedKey),
|
|
};
|
|
};
|
|
|
|
const deleteObject = async (key) => {
|
|
const normalizedKey = normalizeKey(key);
|
|
|
|
await getClient().send(
|
|
new DeleteObjectCommand({
|
|
Bucket: config.bucket,
|
|
Key: normalizedKey,
|
|
})
|
|
);
|
|
};
|
|
|
|
module.exports = {
|
|
isConfigured,
|
|
getPublicUrl,
|
|
uploadBuffer,
|
|
deleteObject,
|
|
};
|