fix(storage-uploadthing): files are duplicated to the storage via client uploads (#11518)
When uploading file via client side upload we invalidate it then on the server side with re-uploading. This works fine with most adapters since they just replace the old file under the same key. UploadThing works differently and generates a new key every time. Example of the issue: <img width="611" alt="image" src="https://github.com/user-attachments/assets/9c01b52a-d159-4f32-9f66-3b5fbadab7b4" /> Now, we clear the old file before doing re-upload.
This commit is contained in:
@@ -90,6 +90,10 @@ type PayloadRequestData = {
|
||||
data?: JsonObject
|
||||
/** The file on the request, same rules apply as the `data` property */
|
||||
file?: {
|
||||
/**
|
||||
* Context of the file when it was uploaded via client side.
|
||||
*/
|
||||
clientUploadContext?: unknown
|
||||
data: Buffer
|
||||
mimetype: string
|
||||
name: string
|
||||
|
||||
@@ -87,6 +87,7 @@ export const addDataAndFileToRequest: AddDataAndFileToRequest = async (req) => {
|
||||
|
||||
req.file = {
|
||||
name: filename,
|
||||
clientUploadContext,
|
||||
data: Buffer.from(await response.arrayBuffer()),
|
||||
mimetype: response.headers.get('Content-Type') || mimeType,
|
||||
size,
|
||||
|
||||
@@ -44,7 +44,13 @@ export const getBeforeChangeHook =
|
||||
}
|
||||
|
||||
const promises = files.map(async (file) => {
|
||||
await adapter.handleUpload({ collection, data, file, req })
|
||||
await adapter.handleUpload({
|
||||
clientUploadContext: file.clientUploadContext,
|
||||
collection,
|
||||
data,
|
||||
file,
|
||||
req,
|
||||
})
|
||||
})
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
|
||||
export interface File {
|
||||
buffer: Buffer
|
||||
clientUploadContext?: unknown
|
||||
filename: string
|
||||
filesize: number
|
||||
mimeType: string
|
||||
@@ -28,6 +29,7 @@ export type ClientUploadsConfig =
|
||||
| boolean
|
||||
|
||||
export type HandleUpload = (args: {
|
||||
clientUploadContext: unknown
|
||||
collection: CollectionConfig
|
||||
data: any
|
||||
file: File
|
||||
|
||||
@@ -16,6 +16,7 @@ export function getIncomingFiles({
|
||||
if (file && data.filename && data.mimeType) {
|
||||
const mainFile: File = {
|
||||
buffer: file.data,
|
||||
clientUploadContext: file.clientUploadContext,
|
||||
filename: data.filename,
|
||||
filesize: file.size,
|
||||
mimeType: data.mimeType,
|
||||
|
||||
@@ -12,8 +12,18 @@ type HandleUploadArgs = {
|
||||
}
|
||||
|
||||
export const getHandleUpload = ({ acl, utApi }: HandleUploadArgs): HandleUpload => {
|
||||
return async ({ data, file }) => {
|
||||
return async ({ clientUploadContext, data, file }) => {
|
||||
try {
|
||||
if (
|
||||
clientUploadContext &&
|
||||
typeof clientUploadContext === 'object' &&
|
||||
'key' in clientUploadContext &&
|
||||
typeof clientUploadContext.key === 'string'
|
||||
) {
|
||||
// Clear the old file
|
||||
await utApi.deleteFiles(clientUploadContext.key)
|
||||
}
|
||||
|
||||
const { buffer, filename, mimeType } = file
|
||||
|
||||
const blob = new Blob([buffer], { type: mimeType })
|
||||
|
||||
Reference in New Issue
Block a user