60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
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<T extends { coverUrl: string }>(
|
|
items: T[]
|
|
): Promise<T[]> {
|
|
return Promise.all(
|
|
items.map(async (item) => ({
|
|
...item,
|
|
coverUrl: await signUrl(item.coverUrl),
|
|
}))
|
|
);
|
|
}
|