diff --git a/components/admin/AdminStorageItem.vue b/components/admin/AdminStorageItem.vue new file mode 100644 index 000000000..f317bf879 --- /dev/null +++ b/components/admin/AdminStorageItem.vue @@ -0,0 +1,18 @@ + + + diff --git a/components/admin/AdminStorageTree.vue b/components/admin/AdminStorageTree.vue new file mode 100644 index 000000000..33b316fb9 --- /dev/null +++ b/components/admin/AdminStorageTree.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/pages/admin/storage.vue b/pages/admin/storage.vue new file mode 100644 index 000000000..1233e5c03 --- /dev/null +++ b/pages/admin/storage.vue @@ -0,0 +1,55 @@ + + + diff --git a/server/api/admin/storage/metas.get.ts b/server/api/admin/storage/metas.get.ts new file mode 100644 index 000000000..dd1ac1a66 --- /dev/null +++ b/server/api/admin/storage/metas.get.ts @@ -0,0 +1,22 @@ +export default defineEventHandler(async (event) => { + const { isGranted } = await useAuthentication(event); + if (!isGranted('code')) { + throw createError({ + status: 401, + statusMessage: 'Unauthorised', + }); + } + + const keys = (await useStorage().getKeys()) + .filter((key) => !key.startsWith('build') && !key.startsWith('root') && !key.startsWith('src')) + .toSorted(); + return await Promise.all(keys.map(async (key) => { + const meta = await useStorage().getMeta(key); + return { + key, + size: meta.size, + atime: meta.atime, + mtime: meta.mtime, + }; + })); +}); diff --git a/src/helpers.ts b/src/helpers.ts index de04327f1..de1929e2a 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -563,6 +563,16 @@ export const filterObjectKeys = , K extends keyof }, {} as Pick); }; +export const formatSize = (number: number): string => { + if (number > 1000000) { + return `${Math.round(10 * number / 1000000) / 10}\u00a0MB`; + } + if (number > 1000) { + return `${Math.round(10 * number / 1000) / 10}\u00a0kB`; + } + return number.toString(); +}; + export const executeUnlessPrerendering = (fn: () => void): (() => void) => { return () => { if ((document as any).prerendering) {