import { S3Client, PutObjectCommand, GetObjectCommand, } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; const s3 = new S3Client({ region: "auto", endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`, credentials: { accessKeyId: process.env.R2_ACCESS_KEY!, secretAccessKey: process.env.R2_SECRET_KEY!, }, }); export async function getPresignedUploadUrl(key: string) { const command = new PutObjectCommand({ Bucket: process.env.R2_BUCKET!, Key: key, ContentType: "image/webp", }); return getSignedUrl(s3, command, { expiresIn: 3600 }); } export function getPublicUrl(key: string) { return `${process.env.R2_PUBLIC_URL}/${key}`; } export async function getPresignedReadUrl(key: string) { const command = new GetObjectCommand({ Bucket: process.env.R2_BUCKET!, Key: key, }); return getSignedUrl(s3, command, { expiresIn: 60 }); } export function keyFromPublicUrl(publicUrl: string): string | null { const prefix = process.env.R2_PUBLIC_URL!; if (!publicUrl.startsWith(prefix)) return null; return publicUrl.replace(prefix, "").replace(/^\//, ""); } export async function signUrl(publicUrl: string) { const key = keyFromPublicUrl(publicUrl); if (key === null) return publicUrl; return getPresignedReadUrl(key); } export async function signCoverUrls( items: T[] ): Promise { return Promise.all( items.map(async (item) => ({ ...item, coverUrl: await signUrl(item.coverUrl), })) ); }