Files
buzz-sheet/lib/media/storage.ts
T
gunshiz dc5c667b4e
CI / Verify (push) Successful in 1m0s
CI / Build immutable images and deploy (push) Failing after 2m38s
feat(guides): add structured image-first editor
2026-08-29 13:30:52 +00:00

32 lines
1.0 KiB
TypeScript

import type { S3Client } from "bun";
let client: S3Client | undefined;
let loading: Promise<S3Client> | undefined;
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`${name} is required for media storage.`);
return value;
}
export async function getMediaStorage(): Promise<S3Client> {
if (client) return client;
if (!loading) {
loading = import("bun").then(({ S3Client: BunS3Client }) => new BunS3Client({
accessKeyId: required("S3_ACCESS_KEY_ID"),
secretAccessKey: required("S3_SECRET_ACCESS_KEY"),
bucket: required("S3_BUCKET"),
endpoint: required("S3_ENDPOINT"),
region: process.env.S3_REGION || "auto",
virtualHostedStyle: process.env.S3_VIRTUAL_HOSTED_STYLE === "true",
}));
}
client = await loading;
return client;
}
export function publicMediaUrl(objectKey: string): string {
const base = required("S3_PUBLIC_URL").replace(/\/+$/u, "");
return `${base}/${objectKey.split("/").map(encodeURIComponent).join("/")}`;
}