Merge pull request #1212 from payloadcms/fix/#940

Fix/#940
This commit is contained in:
James Mikrut
2022-10-06 14:24:51 -04:00
committed by GitHub
6 changed files with 98 additions and 36 deletions

View File

@@ -10,11 +10,12 @@ import { AfterChangeHook, BeforeOperationHook, BeforeValidateHook, Collection }
import { PayloadRequest } from '../../express/types';
import { Document } from '../../types';
import { fieldAffectsData } from '../../fields/config/types';
import uploadFile from '../../uploads/uploadFile';
import { uploadFiles } from '../../uploads/uploadFiles';
import { beforeChange } from '../../fields/hooks/beforeChange';
import { beforeValidate } from '../../fields/hooks/beforeValidate';
import { afterChange } from '../../fields/hooks/afterChange';
import { afterRead } from '../../fields/hooks/afterRead';
import { generateFileData } from '../../uploads/generateFileData';
export type Arguments = {
collection: Collection
@@ -91,10 +92,10 @@ async function create(incomingArgs: Arguments): Promise<Document> {
}
// /////////////////////////////////////
// Upload and resize potential files
// Generate data for all files and sizes
// /////////////////////////////////////
data = await uploadFile({
const { data: newFileData, files: filesToUpload } = await generateFileData({
config,
collection,
req,
@@ -103,6 +104,8 @@ async function create(incomingArgs: Arguments): Promise<Document> {
overwriteExistingFiles,
});
data = newFileData;
// /////////////////////////////////////
// beforeValidate - Fields
// /////////////////////////////////////
@@ -130,6 +133,14 @@ async function create(incomingArgs: Arguments): Promise<Document> {
})) || data;
}, Promise.resolve());
// /////////////////////////////////////
// Write files to local storage
// /////////////////////////////////////
if (!collectionConfig.upload.disableLocalStorage) {
await uploadFiles(payload, filesToUpload);
}
// /////////////////////////////////////
// beforeChange - Collection
// /////////////////////////////////////

View File

@@ -8,13 +8,14 @@ import { PayloadRequest } from '../../express/types';
import { hasWhereAccessResult, UserDocument } from '../../auth/types';
import { saveCollectionDraft } from '../../versions/drafts/saveCollectionDraft';
import { saveCollectionVersion } from '../../versions/saveCollectionVersion';
import uploadFile from '../../uploads/uploadFile';
import { uploadFiles } from '../../uploads/uploadFiles';
import cleanUpFailedVersion from '../../versions/cleanUpFailedVersion';
import { ensurePublishedCollectionVersion } from '../../versions/ensurePublishedCollectionVersion';
import { beforeChange } from '../../fields/hooks/beforeChange';
import { beforeValidate } from '../../fields/hooks/beforeValidate';
import { afterChange } from '../../fields/hooks/afterChange';
import { afterRead } from '../../fields/hooks/afterRead';
import { generateFileData } from '../../uploads/generateFileData';
export type Arguments = {
collection: Collection
@@ -125,10 +126,10 @@ async function update(incomingArgs: Arguments): Promise<Document> {
});
// /////////////////////////////////////
// Upload and resize potential files
// Generate data for all files and sizes
// /////////////////////////////////////
data = await uploadFile({
const { data: newFileData, files: filesToUpload } = await generateFileData({
config,
collection,
req,
@@ -137,6 +138,8 @@ async function update(incomingArgs: Arguments): Promise<Document> {
overwriteExistingFiles,
});
data = newFileData;
// /////////////////////////////////////
// beforeValidate - Fields
// /////////////////////////////////////
@@ -166,6 +169,14 @@ async function update(incomingArgs: Arguments): Promise<Document> {
})) || data;
}, Promise.resolve());
// /////////////////////////////////////
// Write files to local storage
// /////////////////////////////////////
if (!collectionConfig.upload.disableLocalStorage) {
await uploadFiles(payload, filesToUpload);
}
// /////////////////////////////////////
// beforeChange - Collection
// /////////////////////////////////////

View File

@@ -10,8 +10,7 @@ import { PayloadRequest } from '../express/types';
import getImageSize, { ProbedImageSize } from './getImageSize';
import getSafeFileName from './getSafeFilename';
import resizeAndSave from './imageResizer';
import saveBufferToFile from './saveBufferToFile';
import { FileData } from './types';
import { FileData, FileToSave } from './types';
import canResizeImage from './canResizeImage';
type Args = {
@@ -23,7 +22,12 @@ type Args = {
overwriteExistingFiles?: boolean
}
const uploadFile = async ({
type Result = Promise<{
data: Record<string, unknown>
files: FileToSave[]
}>
export const generateFileData = async ({
config,
collection: {
config: collectionConfig,
@@ -33,8 +37,9 @@ const uploadFile = async ({
data,
throwOnMissingFile,
overwriteExistingFiles,
}: Args): Promise<Record<string, unknown>> => {
}: Args): Result => {
let newData = data;
const filesToSave: FileToSave[] = [];
if (collectionConfig.upload) {
const fileData: Partial<FileData> = {};
@@ -88,9 +93,10 @@ const uploadFile = async ({
fsSafeName = await getSafeFileName(Model, staticPath, fsSafeName);
}
if (!disableLocalStorage) {
await saveBufferToFile(fileBuffer, `${staticPath}/${fsSafeName}`);
}
filesToSave.push({
path: `${staticPath}/${fsSafeName}`,
buffer: fileBuffer,
});
fileData.filename = fsSafeName || (!overwriteExistingFiles ? await getSafeFileName(Model, staticPath, file.name) : file.name);
fileData.filesize = fileSize || file.size;
@@ -98,7 +104,7 @@ const uploadFile = async ({
if (Array.isArray(imageSizes) && shouldResize) {
req.payloadUploadSizes = {};
fileData.sizes = await resizeAndSave({
const { sizeData, sizesToSave } = await resizeAndSave({
req,
file: file.data,
dimensions,
@@ -107,6 +113,9 @@ const uploadFile = async ({
savedFilename: fsSafeName || file.name,
mimeType: fileData.mimeType,
});
fileData.sizes = sizeData;
filesToSave.push(...sizesToSave);
}
} catch (err) {
console.error(err);
@@ -120,7 +129,8 @@ const uploadFile = async ({
}
}
return newData;
return {
data: newData,
files: filesToSave,
};
};
export default uploadFile;

View File

@@ -6,7 +6,7 @@ import { SanitizedCollectionConfig } from '../collections/config/types';
import { PayloadRequest } from '../express/types';
import fileExists from './fileExists';
import { ProbedImageSize } from './getImageSize';
import { FileSizes, ImageSize } from './types';
import { FileSizes, FileToSave, ImageSize } from './types';
type Args = {
req: PayloadRequest
@@ -25,6 +25,11 @@ type OutputImage = {
height: number
}
type Result = Promise<{
sizeData: FileSizes
sizesToSave: FileToSave[]
}>
function getOutputImage(sourceImage: string, size: ImageSize): OutputImage {
const extension = sourceImage.split('.').pop();
const name = sanitize(sourceImage.substring(0, sourceImage.lastIndexOf('.')) || sourceImage);
@@ -44,8 +49,9 @@ export default async function resizeAndSave({
staticPath,
config,
savedFilename,
}: Args): Promise<FileSizes> {
const { imageSizes, disableLocalStorage } = config.upload;
}: Args): Promise<Result> {
const { imageSizes } = config.upload;
const sizesToSave: FileToSave[] = [];
const sizes = imageSizes
.filter((desiredSize) => needsResize(desiredSize, dimensions))
@@ -72,9 +78,10 @@ export default async function resizeAndSave({
fs.unlinkSync(imagePath);
}
if (!disableLocalStorage) {
await resized.toFile(imagePath);
}
sizesToSave.push({
path: imagePath,
buffer: bufferObject.data,
});
return {
name: desiredSize.name,
@@ -88,19 +95,22 @@ export default async function resizeAndSave({
const savedSizes = await Promise.all(sizes);
return savedSizes.reduce(
(results, size) => ({
...results,
[size.name]: {
width: size.width,
height: size.height,
filename: size.filename,
mimeType: size.mimeType,
filesize: size.filesize,
},
}),
{},
);
return {
sizeData: savedSizes.reduce(
(results, size) => ({
...results,
[size.name]: {
width: size.width,
height: size.height,
filename: size.filename,
mimeType: size.mimeType,
filesize: size.filesize,
},
}),
{},
),
sizesToSave,
};
}
function createImageName(
outputImage: OutputImage,

View File

@@ -78,3 +78,8 @@ export type File = {
name: string
size: number
}
export type FileToSave = {
buffer: Buffer
path: string
}

View File

@@ -0,0 +1,15 @@
import { FileUploadError } from '../errors';
import saveBufferToFile from './saveBufferToFile';
import { FileToSave } from './types';
import { Payload } from '..';
export const uploadFiles = async (payload: Payload, files: FileToSave[]): Promise<void> => {
try {
await Promise.all(files.map(async ({ buffer, path }) => {
await saveBufferToFile(buffer, path);
}));
} catch (err) {
payload.logger.error(err);
throw new FileUploadError();
}
};