fix(storage-s3, storage-azure, storage-gcs): client uploads when a collection has prefix configured (#11436)
### What? Fixes client uploads when storage collection config has the `prefix` property configured. Previously, it failed with "Object key was not found". ### Why? This is expected to work. ### How? The client upload handler now receives to its props `prefix`. Then it threads it to the server-side `staticHandler` through `clientUploadContext` and then to `getFilePrefix`, which checks for `clientUploadContext.prefix` and returns if there is. Previously, `staticHandler` tried to load the file without including prefix consideration. This changes only these adapters: * S3 * Azure * GCS With the Vercel Blob adapter, `prefix` works correctly.
This commit is contained in:
@@ -10,6 +10,7 @@ type ClientUploadHandlerProps<T extends Record<string, unknown>> = {
|
||||
collectionSlug: UploadCollectionSlug
|
||||
enabled?: boolean
|
||||
extra: T
|
||||
prefix?: string
|
||||
serverHandlerPath: string
|
||||
}
|
||||
|
||||
@@ -21,6 +22,7 @@ export const createClientUploadHandler = <T extends Record<string, unknown>>({
|
||||
collectionSlug: UploadCollectionSlug
|
||||
extra: T
|
||||
file: File
|
||||
prefix?: string
|
||||
serverHandlerPath: string
|
||||
serverURL: string
|
||||
updateFilename: (value: string) => void
|
||||
@@ -31,6 +33,7 @@ export const createClientUploadHandler = <T extends Record<string, unknown>>({
|
||||
collectionSlug,
|
||||
enabled,
|
||||
extra,
|
||||
prefix,
|
||||
serverHandlerPath,
|
||||
}: ClientUploadHandlerProps<T>) {
|
||||
const { setUploadHandler } = useUploadHandlers()
|
||||
@@ -51,6 +54,7 @@ export const createClientUploadHandler = <T extends Record<string, unknown>>({
|
||||
collectionSlug,
|
||||
extra,
|
||||
file,
|
||||
prefix,
|
||||
serverHandlerPath,
|
||||
serverURL,
|
||||
updateFilename,
|
||||
|
||||
@@ -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<string> {
|
||||
// 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({
|
||||
|
||||
@@ -63,11 +63,23 @@ export const initClientUploads = <ExtraProps extends Record<string, unknown>, 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,
|
||||
|
||||
@@ -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 }
|
||||
},
|
||||
})
|
||||
|
||||
@@ -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),
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 }
|
||||
},
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user