* Begin storing optimized photo files * Increase optimized image size to 1080 * Refactor photo/storage modules * Refine storage file naming api * Simplify photo storage api * Finalize photo storage api * Start storing/serving optimized photos * Finalize optimized photo asset generation * Temporarily allow static optimization on PREVIEW branches * Restore static optimization as production-only * Remove og image inline-flex class * Tweak convert upload signature * Refactor optimized file storage * Display optimized files when they exist in photo form * Create small disclosure component * Report photo storage files more accurately * Sort optimized files * Generate optimized storage files when updating/syncing photos * Include source bucket when copying files with MinIO * Make deleting files more resilient
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { PATH_API_VERCEL_BLOB_UPLOAD } from '@/app/path';
|
|
import { copy, del, list, put } from '@vercel/blob';
|
|
import { upload } from '@vercel/blob/client';
|
|
import { getFileNamePartsFromStorageUrl, StorageListResponse } from '.';
|
|
import { formatBytes } from '@/utility/number';
|
|
|
|
const VERCEL_BLOB_STORE_ID = process.env.BLOB_READ_WRITE_TOKEN?.match(
|
|
/^vercel_blob_rw_([a-z0-9]+)_[a-z0-9]+$/i,
|
|
)?.[1].toLowerCase();
|
|
|
|
export const VERCEL_BLOB_BASE_URL = VERCEL_BLOB_STORE_ID
|
|
? `https://${VERCEL_BLOB_STORE_ID}.public.blob.vercel-storage.com`
|
|
: undefined;
|
|
|
|
export const isUrlFromVercelBlob = (url?: string) =>
|
|
VERCEL_BLOB_BASE_URL &&
|
|
url?.startsWith(VERCEL_BLOB_BASE_URL);
|
|
|
|
export const vercelBlobUploadFromClient = async (
|
|
file: File | Blob,
|
|
fileName: string,
|
|
): Promise<string> =>
|
|
upload(
|
|
fileName,
|
|
file, {
|
|
access: 'public',
|
|
handleUploadUrl: PATH_API_VERCEL_BLOB_UPLOAD,
|
|
},
|
|
)
|
|
.then(({ url }) => url);
|
|
|
|
export const vercelBlobPut = (
|
|
file: Buffer,
|
|
fileName: string,
|
|
): Promise<string> =>
|
|
put(fileName, file, { access: 'public' })
|
|
.then(({ url }) => url);
|
|
|
|
export const vercelBlobCopy = (
|
|
sourceUrl: string,
|
|
destinationFileName: string,
|
|
addRandomSuffix?: boolean,
|
|
): Promise<string> =>
|
|
copy(
|
|
sourceUrl,
|
|
destinationFileName,
|
|
{ access: 'public', addRandomSuffix },
|
|
)
|
|
.then(({ url }) => url);
|
|
|
|
export const vercelBlobDelete = (fileName: string) => del(fileName);
|
|
|
|
export const vercelBlobList = (
|
|
prefix: string,
|
|
): Promise<StorageListResponse> => list({ prefix })
|
|
.then(({ blobs }) => blobs.map(({ url, uploadedAt, size }) => ({
|
|
url,
|
|
fileName: getFileNamePartsFromStorageUrl(url).fileName,
|
|
uploadedAt,
|
|
size: formatBytes(size),
|
|
})));
|