fix: correctly fetches externally stored files when passing uploadEdits (#4505)
This commit is contained in:
@@ -17,7 +17,7 @@ import { FileUploadError, MissingFile } from '../errors'
|
||||
import canResizeImage from './canResizeImage'
|
||||
import cropImage from './cropImage'
|
||||
import getFileByPath from './getFileByPath'
|
||||
import getFileByURL from './getFileByURL'
|
||||
import { getExternalFile } from './getExternalFile'
|
||||
import getImageSize from './getImageSize'
|
||||
import getSafeFileName from './getSafeFilename'
|
||||
import resizeAndTransformImageSizes from './imageResizer'
|
||||
@@ -72,9 +72,8 @@ export const generateFileData = async <T>({
|
||||
const response = await getFileByPath(filePath)
|
||||
file = response as UploadedFile
|
||||
overwriteExistingFiles = true
|
||||
} else {
|
||||
const response = await getFileByURL(url)
|
||||
file = response as UploadedFile
|
||||
} else if (filename && url) {
|
||||
file = (await getExternalFile({ req, data: data as FileData })) as UploadedFile
|
||||
overwriteExistingFiles = true
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
38
packages/payload/src/uploads/getExternalFile.ts
Normal file
38
packages/payload/src/uploads/getExternalFile.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { File, FileData } from './types'
|
||||
import { Request } from 'express'
|
||||
import { APIError } from '../errors'
|
||||
|
||||
type Args = {
|
||||
req: Request
|
||||
data: FileData
|
||||
}
|
||||
export const getExternalFile = async ({ req, data }: Args): Promise<File> => {
|
||||
const baseUrl = req.get('origin') || `${req.protocol}://${req.get('host')}`
|
||||
const { url, filename } = data
|
||||
|
||||
if (typeof url === 'string') {
|
||||
const fileURL = `${baseUrl}${url}`
|
||||
const { default: fetch } = (await import('node-fetch')) as any
|
||||
|
||||
const res = await fetch(fileURL, {
|
||||
credentials: 'include',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
...req.headers,
|
||||
},
|
||||
})
|
||||
|
||||
if (!res.ok) throw new APIError(`Failed to fetch file from ${fileURL}`, res.status)
|
||||
|
||||
const data = await res.buffer()
|
||||
|
||||
return {
|
||||
name: filename,
|
||||
data,
|
||||
mimetype: res.headers.get('content-type') || undefined,
|
||||
size: Number(res.headers.get('content-length')) || 0,
|
||||
}
|
||||
}
|
||||
|
||||
throw new APIError('Invalid file url', 400)
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import path from 'path'
|
||||
|
||||
import type { File } from './types'
|
||||
|
||||
const getFileByURL = async (url: string): Promise<File> => {
|
||||
if (typeof url === 'string') {
|
||||
const { default: fetch } = (await import('node-fetch')) as any
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'GET',
|
||||
})
|
||||
const data = await res.buffer()
|
||||
const name = path.basename(url)
|
||||
|
||||
return {
|
||||
name,
|
||||
data,
|
||||
mimetype: res.headers.get('content-type') || undefined,
|
||||
size: Number(res.headers.get('content-length')) || 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default getFileByURL
|
||||
@@ -20,4 +20,11 @@ GCS_ENDPOINT=http://localhost:4443
|
||||
GCS_PROJECT_ID=test
|
||||
GCS_BUCKET=payload-bucket
|
||||
|
||||
R2_ENDPOINT=https://cloudflare-generated-domain.r2.cloudflarestorage.com
|
||||
R2_REGION=auto
|
||||
R2_ACCESS_KEY_ID=access-key-id
|
||||
R2_SECRET_ACCESS_KEY=secret-access-key
|
||||
R2_BUCKET=payload-bucket
|
||||
R2_FORCE_PATH_STYLE=
|
||||
|
||||
PAYLOAD_DROP_DATABASE=true
|
||||
|
||||
@@ -51,6 +51,21 @@ if (process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER === 's3') {
|
||||
})
|
||||
}
|
||||
|
||||
if (process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER === 'r2') {
|
||||
adapter = s3Adapter({
|
||||
config: {
|
||||
endpoint: process.env.R2_ENDPOINT,
|
||||
forcePathStyle: process.env.R2_FORCE_PATH_STYLE === 'true',
|
||||
region: process.env.R2_REGION,
|
||||
credentials: {
|
||||
accessKeyId: process.env.R2_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
|
||||
},
|
||||
},
|
||||
bucket: process.env.R2_BUCKET,
|
||||
})
|
||||
}
|
||||
|
||||
if (process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER === 'gcs') {
|
||||
adapter = gcsAdapter({
|
||||
options: {
|
||||
|
||||
Reference in New Issue
Block a user