perf: optimize file access promises (#12275)

Improves performance in local strategy uploads by reading the file and
metadata info synchronously. This change uses `promise.all` for three
separately awaited calls. This improves the perf by making all calls in
a non-blocking way.
This commit is contained in:
Dan Ribbens
2025-04-30 11:26:28 -07:00
committed by GitHub
parent 710fe0949b
commit 6133a1d183
2 changed files with 23 additions and 19 deletions

View File

@@ -10,7 +10,7 @@ import type { SanitizedConfig } from '../config/types.js'
import type { PayloadRequest } from '../types/index.js'
import type { FileData, FileToSave, ProbedImageSize, UploadEdits } from './types.js'
import { FileRetrievalError, FileUploadError, MissingFile } from '../errors/index.js'
import { FileRetrievalError, FileUploadError, Forbidden, MissingFile } from '../errors/index.js'
import { canResizeImage } from './canResizeImage.js'
import { cropImage } from './cropImage.js'
import { getExternalFile } from './getExternalFile.js'
@@ -85,6 +85,10 @@ export const generateFileData = async <T>({
if (!file && uploadEdits && incomingFileData) {
const { filename, url } = incomingFileData as FileData
if (filename && (filename.includes('../') || filename.includes('..\\'))) {
throw new Forbidden(req.t)
}
try {
if (url && url.startsWith('/') && !disableLocalStorage) {
const filePath = `${staticPath}/${filename}`

View File

@@ -5,28 +5,28 @@ import path from 'path'
import type { PayloadRequest } from '../types/index.js'
const mimeTypeEstimate = {
const mimeTypeEstimate: Record<string, string> = {
svg: 'image/svg+xml',
}
export const getFileByPath = async (filePath: string): Promise<PayloadRequest['file']> => {
if (typeof filePath === 'string') {
const data = await fs.readFile(filePath)
const mimetype = fileTypeFromFile(filePath)
const { size } = await fs.stat(filePath)
const name = path.basename(filePath)
const ext = path.extname(filePath).slice(1)
const mime = (await mimetype)?.mime || mimeTypeEstimate[ext]
return {
name,
data,
mimetype: mime,
size,
}
if (typeof filePath !== 'string') {
return undefined
}
return undefined
const name = path.basename(filePath)
const ext = path.extname(filePath).slice(1)
const [data, stat, type] = await Promise.all([
fs.readFile(filePath),
fs.stat(filePath),
fileTypeFromFile(filePath),
])
return {
name,
data,
mimetype: type?.mime || mimeTypeEstimate[ext],
size: stat.size,
}
}