59 lines
1.4 KiB
JavaScript
59 lines
1.4 KiB
JavaScript
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3")
|
|
|
|
function createR2Client() {
|
|
const endpoint = process.env.R2_ENDPOINT
|
|
const accessKeyId = process.env.R2_ACCESS_KEY_ID
|
|
const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY
|
|
|
|
if (!endpoint || !accessKeyId || !secretAccessKey) {
|
|
throw new Error("R2 config missing (R2_ENDPOINT/R2_ACCESS_KEY_ID/R2_SECRET_ACCESS_KEY)")
|
|
}
|
|
|
|
return new S3Client({
|
|
region: process.env.R2_REGION || "auto",
|
|
endpoint,
|
|
credentials: { accessKeyId, secretAccessKey },
|
|
})
|
|
}
|
|
|
|
let r2Client = null
|
|
|
|
function getR2Client() {
|
|
if (!r2Client) r2Client = createR2Client()
|
|
return r2Client
|
|
}
|
|
|
|
function encodeObjectKey(key) {
|
|
return String(key)
|
|
.split("/")
|
|
.map((part) => encodeURIComponent(part))
|
|
.join("/")
|
|
}
|
|
|
|
function toStoredPath(key) {
|
|
const normalized = String(key || "").replace(/^\/+/, "")
|
|
return `/${encodeObjectKey(normalized)}`
|
|
}
|
|
|
|
async function uploadImage({ bucket, path, fileBuffer, contentType }) {
|
|
if (!path || !fileBuffer) throw new Error("uploadImage params missing")
|
|
|
|
const targetBucket = bucket || process.env.R2_BUCKET_NAME
|
|
if (!targetBucket) throw new Error("R2 bucket missing (R2_BUCKET_NAME)")
|
|
|
|
const r2 = getR2Client()
|
|
|
|
await r2.send(
|
|
new PutObjectCommand({
|
|
Bucket: targetBucket,
|
|
Key: path,
|
|
Body: fileBuffer,
|
|
ContentType: contentType || "image/webp",
|
|
})
|
|
)
|
|
|
|
return toStoredPath(path)
|
|
}
|
|
|
|
module.exports = { uploadImage }
|