You've already forked domainstack.io
mirror of
https://github.com/jakejarvis/domainstack.io.git
synced 2025-12-02 19:33:48 -05:00
63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
import "server-only";
|
|
|
|
import { del, put } from "@vercel/blob";
|
|
import { createLogger } from "@/lib/logger/server";
|
|
|
|
const logger = createLogger({ source: "blob" });
|
|
|
|
/**
|
|
* Upload a buffer to Vercel Blob storage
|
|
*/
|
|
export async function putBlob(options: {
|
|
pathname: string;
|
|
body: Buffer;
|
|
contentType?: string;
|
|
cacheControlMaxAge?: number;
|
|
}): Promise<{ url: string; pathname: string }> {
|
|
const blob = await put(options.pathname, options.body, {
|
|
access: "public",
|
|
contentType: options.contentType,
|
|
cacheControlMaxAge: options.cacheControlMaxAge,
|
|
allowOverwrite: true, // TODO: temporary fix until KV/blob storage self-heals
|
|
});
|
|
|
|
return {
|
|
url: blob.url,
|
|
pathname: options.pathname,
|
|
};
|
|
}
|
|
|
|
export type DeleteResult = Array<{
|
|
url: string;
|
|
deleted: boolean;
|
|
error?: string;
|
|
}>;
|
|
|
|
/**
|
|
* Delete one or more blobs by URL, tracking each URL's deletion status individually
|
|
*/
|
|
export async function deleteBlobs(urls: string[]): Promise<DeleteResult> {
|
|
const results: DeleteResult = [];
|
|
if (!urls.length) return results;
|
|
|
|
// Process each URL individually to track per-URL success/failure
|
|
for (const url of urls) {
|
|
try {
|
|
await del(url, { token: process.env.BLOB_READ_WRITE_TOKEN });
|
|
results.push({ url, deleted: true });
|
|
} catch (err) {
|
|
const message = (err as Error)?.message || "unknown";
|
|
logger.error(
|
|
"delete failed",
|
|
err instanceof Error ? err : new Error(String(err)),
|
|
{
|
|
url,
|
|
},
|
|
);
|
|
results.push({ url, deleted: false, error: message });
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|