1
mirror of https://github.com/jakejarvis/domainstack.io.git synced 2025-12-02 19:33:48 -05:00
Files
domainstack.io/lib/blob.ts

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;
}