diff --git a/packages/plugin-cloud-storage/src/client/createClientUploadHandler.tsx b/packages/plugin-cloud-storage/src/client/createClientUploadHandler.tsx index a53c16d551..0aab613fe0 100644 --- a/packages/plugin-cloud-storage/src/client/createClientUploadHandler.tsx +++ b/packages/plugin-cloud-storage/src/client/createClientUploadHandler.tsx @@ -10,6 +10,7 @@ type ClientUploadHandlerProps> = { collectionSlug: UploadCollectionSlug enabled?: boolean extra: T + prefix?: string serverHandlerPath: string } @@ -21,6 +22,7 @@ export const createClientUploadHandler = >({ collectionSlug: UploadCollectionSlug extra: T file: File + prefix?: string serverHandlerPath: string serverURL: string updateFilename: (value: string) => void @@ -31,6 +33,7 @@ export const createClientUploadHandler = >({ collectionSlug, enabled, extra, + prefix, serverHandlerPath, }: ClientUploadHandlerProps) { const { setUploadHandler } = useUploadHandlers() @@ -51,6 +54,7 @@ export const createClientUploadHandler = >({ collectionSlug, extra, file, + prefix, serverHandlerPath, serverURL, updateFilename, diff --git a/packages/plugin-cloud-storage/src/utilities/getFilePrefix.ts b/packages/plugin-cloud-storage/src/utilities/getFilePrefix.ts index fd9778acb5..6e2771f51d 100644 --- a/packages/plugin-cloud-storage/src/utilities/getFilePrefix.ts +++ b/packages/plugin-cloud-storage/src/utilities/getFilePrefix.ts @@ -1,14 +1,26 @@ import type { CollectionConfig, PayloadRequest, UploadConfig } from 'payload' export async function getFilePrefix({ + clientUploadContext, collection, filename, req, }: { + clientUploadContext?: unknown collection: CollectionConfig filename: string req: PayloadRequest }): Promise { + // Prioritize from clientUploadContext if there is: + if ( + clientUploadContext && + typeof clientUploadContext === 'object' && + 'prefix' in clientUploadContext && + typeof clientUploadContext.prefix === 'string' + ) { + return clientUploadContext.prefix + } + const imageSizes = (collection?.upload as UploadConfig)?.imageSizes || [] const files = await req.payload.find({ diff --git a/packages/plugin-cloud-storage/src/utilities/initClientUploads.ts b/packages/plugin-cloud-storage/src/utilities/initClientUploads.ts index 316995c380..6b8b454e73 100644 --- a/packages/plugin-cloud-storage/src/utilities/initClientUploads.ts +++ b/packages/plugin-cloud-storage/src/utilities/initClientUploads.ts @@ -63,11 +63,23 @@ export const initClientUploads = , T> for (const collectionSlug in collections) { const collection = collections[collectionSlug] + let prefix: string | undefined + + if ( + collection && + typeof collection === 'object' && + 'prefix' in collection && + typeof collection.prefix === 'string' + ) { + prefix = collection.prefix + } + config.admin.components.providers.push({ clientProps: { collectionSlug, enabled, extra: extraClientHandlerProps ? extraClientHandlerProps(collection) : undefined, + prefix, serverHandlerPath, }, path: clientHandler, diff --git a/packages/storage-azure/src/client/AzureClientUploadHandler.ts b/packages/storage-azure/src/client/AzureClientUploadHandler.ts index c61251fea6..f615962dc6 100644 --- a/packages/storage-azure/src/client/AzureClientUploadHandler.ts +++ b/packages/storage-azure/src/client/AzureClientUploadHandler.ts @@ -2,7 +2,7 @@ import { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client' export const AzureClientUploadHandler = createClientUploadHandler({ - handler: async ({ apiRoute, collectionSlug, file, serverHandlerPath, serverURL }) => { + handler: async ({ apiRoute, collectionSlug, file, prefix, serverHandlerPath, serverURL }) => { const response = await fetch(`${serverURL}${apiRoute}${serverHandlerPath}`, { body: JSON.stringify({ collectionSlug, @@ -25,5 +25,7 @@ export const AzureClientUploadHandler = createClientUploadHandler({ }, method: 'PUT', }) + + return { prefix } }, }) diff --git a/packages/storage-azure/src/staticHandler.ts b/packages/storage-azure/src/staticHandler.ts index 0dcc888b7d..58ea821120 100644 --- a/packages/storage-azure/src/staticHandler.ts +++ b/packages/storage-azure/src/staticHandler.ts @@ -13,9 +13,9 @@ interface Args { } export const getHandler = ({ collection, getStorageClient }: Args): StaticHandler => { - return async (req, { params: { filename } }) => { + return async (req, { params: { clientUploadContext, filename } }) => { try { - const prefix = await getFilePrefix({ collection, filename, req }) + const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const blockBlobClient = getStorageClient().getBlockBlobClient( path.posix.join(prefix, filename), ) diff --git a/packages/storage-gcs/src/client/GcsClientUploadHandler.ts b/packages/storage-gcs/src/client/GcsClientUploadHandler.ts index 549c5a3c17..84b8a41320 100644 --- a/packages/storage-gcs/src/client/GcsClientUploadHandler.ts +++ b/packages/storage-gcs/src/client/GcsClientUploadHandler.ts @@ -2,7 +2,7 @@ import { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client' export const GcsClientUploadHandler = createClientUploadHandler({ - handler: async ({ apiRoute, collectionSlug, file, serverHandlerPath, serverURL }) => { + handler: async ({ apiRoute, collectionSlug, file, prefix, serverHandlerPath, serverURL }) => { const response = await fetch(`${serverURL}${apiRoute}${serverHandlerPath}`, { body: JSON.stringify({ collectionSlug, @@ -20,5 +20,9 @@ export const GcsClientUploadHandler = createClientUploadHandler({ headers: { 'Content-Length': file.size.toString(), 'Content-Type': file.type }, method: 'PUT', }) + + return { + prefix, + } }, }) diff --git a/packages/storage-gcs/src/staticHandler.ts b/packages/storage-gcs/src/staticHandler.ts index 0103c9d700..f6828fe834 100644 --- a/packages/storage-gcs/src/staticHandler.ts +++ b/packages/storage-gcs/src/staticHandler.ts @@ -12,9 +12,9 @@ interface Args { } export const getHandler = ({ bucket, collection, getStorageClient }: Args): StaticHandler => { - return async (req, { params: { filename } }) => { + return async (req, { params: { clientUploadContext, filename } }) => { try { - const prefix = await getFilePrefix({ collection, filename, req }) + const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const file = getStorageClient().bucket(bucket).file(path.posix.join(prefix, filename)) const [metadata] = await file.getMetadata() diff --git a/packages/storage-s3/src/client/S3ClientUploadHandler.ts b/packages/storage-s3/src/client/S3ClientUploadHandler.ts index 7f1748a89d..c4dc148aab 100644 --- a/packages/storage-s3/src/client/S3ClientUploadHandler.ts +++ b/packages/storage-s3/src/client/S3ClientUploadHandler.ts @@ -2,7 +2,7 @@ import { createClientUploadHandler } from '@payloadcms/plugin-cloud-storage/client' export const S3ClientUploadHandler = createClientUploadHandler({ - handler: async ({ apiRoute, collectionSlug, file, serverHandlerPath, serverURL }) => { + handler: async ({ apiRoute, collectionSlug, file, prefix, serverHandlerPath, serverURL }) => { const response = await fetch(`${serverURL}${apiRoute}${serverHandlerPath}`, { body: JSON.stringify({ collectionSlug, @@ -20,5 +20,7 @@ export const S3ClientUploadHandler = createClientUploadHandler({ headers: { 'Content-Length': file.size.toString(), 'Content-Type': file.type }, method: 'PUT', }) + + return { prefix } }, }) diff --git a/packages/storage-s3/src/staticHandler.ts b/packages/storage-s3/src/staticHandler.ts index 7b903e7b52..056ed7678d 100644 --- a/packages/storage-s3/src/staticHandler.ts +++ b/packages/storage-s3/src/staticHandler.ts @@ -35,9 +35,9 @@ const streamToBuffer = async (readableStream: any) => { } export const getHandler = ({ bucket, collection, getStorageClient }: Args): StaticHandler => { - return async (req, { params: { filename } }) => { + return async (req, { params: { clientUploadContext, filename } }) => { try { - const prefix = await getFilePrefix({ collection, filename, req }) + const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req }) const key = path.posix.join(prefix, filename)