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
|
data?: JsonObject
|
||||||
/** The file on the request, same rules apply as the `data` property */
|
/** The file on the request, same rules apply as the `data` property */
|
||||||
file?: {
|
file?: {
|
||||||
|
/**
|
||||||
|
* Context of the file when it was uploaded via client side.
|
||||||
|
*/
|
||||||
|
clientUploadContext?: unknown
|
||||||
data: Buffer
|
data: Buffer
|
||||||
mimetype: string
|
mimetype: string
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export const addDataAndFileToRequest: AddDataAndFileToRequest = async (req) => {
|
|||||||
|
|
||||||
req.file = {
|
req.file = {
|
||||||
name: filename,
|
name: filename,
|
||||||
|
clientUploadContext,
|
||||||
data: Buffer.from(await response.arrayBuffer()),
|
data: Buffer.from(await response.arrayBuffer()),
|
||||||
mimetype: response.headers.get('Content-Type') || mimeType,
|
mimetype: response.headers.get('Content-Type') || mimeType,
|
||||||
size,
|
size,
|
||||||
|
|||||||
@@ -44,7 +44,13 @@ export const getBeforeChangeHook =
|
|||||||
}
|
}
|
||||||
|
|
||||||
const promises = files.map(async (file) => {
|
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)
|
await Promise.all(promises)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type {
|
|||||||
|
|
||||||
export interface File {
|
export interface File {
|
||||||
buffer: Buffer
|
buffer: Buffer
|
||||||
|
clientUploadContext?: unknown
|
||||||
filename: string
|
filename: string
|
||||||
filesize: number
|
filesize: number
|
||||||
mimeType: string
|
mimeType: string
|
||||||
@@ -28,6 +29,7 @@ export type ClientUploadsConfig =
|
|||||||
| boolean
|
| boolean
|
||||||
|
|
||||||
export type HandleUpload = (args: {
|
export type HandleUpload = (args: {
|
||||||
|
clientUploadContext: unknown
|
||||||
collection: CollectionConfig
|
collection: CollectionConfig
|
||||||
data: any
|
data: any
|
||||||
file: File
|
file: File
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export function getIncomingFiles({
|
|||||||
if (file && data.filename && data.mimeType) {
|
if (file && data.filename && data.mimeType) {
|
||||||
const mainFile: File = {
|
const mainFile: File = {
|
||||||
buffer: file.data,
|
buffer: file.data,
|
||||||
|
clientUploadContext: file.clientUploadContext,
|
||||||
filename: data.filename,
|
filename: data.filename,
|
||||||
filesize: file.size,
|
filesize: file.size,
|
||||||
mimeType: data.mimeType,
|
mimeType: data.mimeType,
|
||||||
|
|||||||
@@ -12,8 +12,18 @@ type HandleUploadArgs = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getHandleUpload = ({ acl, utApi }: HandleUploadArgs): HandleUpload => {
|
export const getHandleUpload = ({ acl, utApi }: HandleUploadArgs): HandleUpload => {
|
||||||
return async ({ data, file }) => {
|
return async ({ clientUploadContext, data, file }) => {
|
||||||
try {
|
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 { buffer, filename, mimeType } = file
|
||||||
|
|
||||||
const blob = new Blob([buffer], { type: mimeType })
|
const blob = new Blob([buffer], { type: mimeType })
|
||||||
|
|||||||
Reference in New Issue
Block a user