@@ -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
|
||||
// /////////////////////////////////////
|
||||
|
||||
@@ -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
|
||||
// /////////////////////////////////////
|
||||
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
|
||||
@@ -78,3 +78,8 @@ export type File = {
|
||||
name: string
|
||||
size: number
|
||||
}
|
||||
|
||||
export type FileToSave = {
|
||||
buffer: Buffer
|
||||
path: string
|
||||
}
|
||||
|
||||
15
src/uploads/uploadFiles.ts
Normal file
15
src/uploads/uploadFiles.ts
Normal 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();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user