- {getIdFromStorageUrl(url)}
+
+ {uploadedAt
+ ?
+ : '—'}
{isAdding || isComplete
@@ -66,9 +68,10 @@ export default function AdminUploadsTable({
: status === 'adding'
? statusMessage ?? 'Adding ...'
: 'Waiting'
- : uploadedAt
- ?
- : '—'}
+ : size
+ // eslint-disable-next-line max-len
+ ? `${size} ${getExtensionFromStorageUrl(url)?.toUpperCase()}`
+ : getExtensionFromStorageUrl(url)?.toUpperCase()}
diff --git a/src/platforms/storage/aws-s3.ts b/src/platforms/storage/aws-s3.ts
index 63884a68..af418912 100644
--- a/src/platforms/storage/aws-s3.ts
+++ b/src/platforms/storage/aws-s3.ts
@@ -6,6 +6,7 @@ import {
PutObjectCommand,
} from '@aws-sdk/client-s3';
import { StorageListResponse, generateStorageId } from '.';
+import { formatBytesToMB } from '@/utility/number';
const AWS_S3_BUCKET = process.env.NEXT_PUBLIC_AWS_S3_BUCKET ?? '';
const AWS_S3_REGION = process.env.NEXT_PUBLIC_AWS_S3_REGION ?? '';
@@ -70,10 +71,11 @@ export const awsS3List = async (
Bucket: AWS_S3_BUCKET,
Prefix,
}))
- .then((data) => data.Contents?.map(({ Key, LastModified }) => ({
+ .then((data) => data.Contents?.map(({ Key, LastModified, Size }) => ({
url: urlForKey(Key),
fileName: Key ?? '',
uploadedAt: LastModified,
+ size: Size ? formatBytesToMB(Size) : undefined,
})) ?? []);
export const awsS3Delete = async (Key: string) => {
diff --git a/src/platforms/storage/cloudflare-r2.ts b/src/platforms/storage/cloudflare-r2.ts
index 6276a47a..4d2d83b3 100644
--- a/src/platforms/storage/cloudflare-r2.ts
+++ b/src/platforms/storage/cloudflare-r2.ts
@@ -7,6 +7,7 @@ import {
} from '@aws-sdk/client-s3';
import { StorageListResponse, generateStorageId } from '.';
import { removeUrlProtocol } from '@/utility/url';
+import { formatBytesToMB } from '@/utility/number';
const CLOUDFLARE_R2_BUCKET =
process.env.NEXT_PUBLIC_CLOUDFLARE_R2_BUCKET ?? '';
@@ -90,10 +91,11 @@ export const cloudflareR2List = async (
Bucket: CLOUDFLARE_R2_BUCKET,
Prefix,
}))
- .then((data) => data.Contents?.map(({ Key, LastModified }) => ({
+ .then((data) => data.Contents?.map(({ Key, LastModified, Size }) => ({
url: urlForKey(Key),
fileName: Key ?? '',
uploadedAt: LastModified,
+ size: Size ? formatBytesToMB(Size) : undefined,
})) ?? []);
export const cloudflareR2Delete = async (Key: string) => {
diff --git a/src/platforms/storage/index.ts b/src/platforms/storage/index.ts
index 63af85d4..f581ceba 100644
--- a/src/platforms/storage/index.ts
+++ b/src/platforms/storage/index.ts
@@ -33,11 +33,14 @@ import { PATH_API_PRESIGNED_URL } from '@/app/paths';
export const generateStorageId = () => generateNanoid(16);
-export type StorageListResponse = {
+export type StorageListItem = {
url: string
fileName: string
uploadedAt?: Date
-}[];
+ size?: string
+};
+
+export type StorageListResponse = StorageListItem[];
export type StorageType =
'vercel-blob' |
diff --git a/src/platforms/storage/vercel-blob.ts b/src/platforms/storage/vercel-blob.ts
index 2fdc49d8..69289211 100644
--- a/src/platforms/storage/vercel-blob.ts
+++ b/src/platforms/storage/vercel-blob.ts
@@ -1,7 +1,8 @@
import { PATH_API_VERCEL_BLOB_UPLOAD } from '@/app/paths';
import { copy, del, list, put } from '@vercel/blob';
import { upload } from '@vercel/blob/client';
-import { fileNameForStorageUrl } from '.';
+import { fileNameForStorageUrl, StorageListResponse } from '.';
+import { formatBytesToMB } 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,
@@ -56,9 +57,12 @@ export const vercelBlobCopy = (
export const vercelBlobDelete = (fileName: string) => del(fileName);
-export const vercelBlobList = (prefix: string) => list({ prefix })
- .then(({ blobs }) => blobs.map(({ url, uploadedAt }) => ({
+export const vercelBlobList = (
+ prefix: string,
+): Promise