feat: initial drafts and versions merge

This commit is contained in:
James
2022-02-06 12:13:52 -05:00
199 changed files with 6182 additions and 834 deletions

View File

@@ -0,0 +1,149 @@
import { Field } from '../fields/config/types';
import { Config } from '../config/types';
import { CollectionConfig } from '../collections/config/types';
import { mimeTypeValidator } from './mimeTypeValidator';
import { IncomingUploadType } from './types';
type Options = {
config: Config
collection: CollectionConfig
}
const getBaseUploadFields = ({ config, collection }: Options): Field[] => {
const uploadOptions: IncomingUploadType = typeof collection.upload === 'object' ? collection.upload : {};
const mimeType: Field = {
name: 'mimeType',
label: 'MIME Type',
type: 'text',
admin: {
readOnly: true,
disabled: true,
},
};
const url: Field = {
name: 'url',
label: 'URL',
type: 'text',
admin: {
readOnly: true,
disabled: true,
},
};
const width: Field = {
name: 'width',
label: 'Width',
type: 'number',
admin: {
readOnly: true,
disabled: true,
},
};
const height: Field = {
name: 'height',
label: 'Height',
type: 'number',
admin: {
readOnly: true,
disabled: true,
},
};
const filesize: Field = {
name: 'filesize',
label: 'File Size',
type: 'number',
admin: {
readOnly: true,
disabled: true,
},
};
const filename: Field = {
name: 'filename',
label: 'File Name',
type: 'text',
index: true,
unique: true,
admin: {
readOnly: true,
disabled: true,
},
};
let uploadFields: Field[] = [
{
...url,
hooks: {
afterRead: [
({ data }) => {
if (data?.filename) {
return `${config.serverURL}${uploadOptions.staticURL}/${data.filename}`;
}
return undefined;
},
],
},
},
filename,
mimeType,
filesize,
];
if (uploadOptions.mimeTypes) {
mimeType.validate = mimeTypeValidator(uploadOptions.mimeTypes);
}
if (uploadOptions.imageSizes) {
uploadFields = uploadFields.concat([
width,
height,
{
name: 'sizes',
label: 'Sizes',
type: 'group',
admin: {
disabled: true,
},
fields: uploadOptions.imageSizes.map((size) => ({
label: size.name,
name: size.name,
type: 'group',
admin: {
disabled: true,
},
fields: [
{
...url,
hooks: {
afterRead: [
({ data }) => {
const sizeFilename = data?.sizes?.[size.name]?.filename;
if (sizeFilename) {
return `${config.serverURL}${uploadOptions.staticURL}/${sizeFilename}`;
}
return undefined;
},
],
},
},
width,
height,
mimeType,
filesize,
filename,
],
})),
},
]);
}
return uploadFields;
};
export default getBaseUploadFields;

102
src/uploads/uploadFile.ts Normal file
View File

@@ -0,0 +1,102 @@
import mkdirp from 'mkdirp';
import path from 'path';
import { SanitizedConfig } from '../config/types';
import { Collection } from '../collections/config/types';
import { FileUploadError, MissingFile } from '../errors';
import { PayloadRequest } from '../express/types';
import { FileData } from './types';
import saveBufferToFile from './saveBufferToFile';
import getSafeFileName from './getSafeFilename';
import getImageSize from './getImageSize';
import resizeAndSave from './imageResizer';
import isImage from './isImage';
type Args = {
config: SanitizedConfig,
collection: Collection
throwOnMissingFile?: boolean
req: PayloadRequest
data: Record<string, unknown>
overwriteExistingFiles?: boolean
}
const uploadFile = async ({
config,
collection: {
config: collectionConfig,
Model,
},
req,
data,
throwOnMissingFile,
overwriteExistingFiles,
}: Args): Promise<Record<string, unknown>> => {
let newData = data;
if (collectionConfig.upload) {
const fileData: Partial<FileData> = {};
const { staticDir, imageSizes, disableLocalStorage } = collectionConfig.upload;
const { file } = req.files || {};
if (throwOnMissingFile && !file) {
throw new MissingFile();
}
let staticPath = staticDir;
if (staticDir.indexOf('/') !== 0) {
staticPath = path.resolve(config.paths.configDir, staticDir);
}
if (!disableLocalStorage) {
mkdirp.sync(staticPath);
}
if (file) {
const fsSafeName = !overwriteExistingFiles ? await getSafeFileName(Model, staticPath, file.name) : file.name;
try {
if (!disableLocalStorage) {
await saveBufferToFile(file.data, `${staticPath}/${fsSafeName}`);
}
fileData.filename = fsSafeName;
fileData.filesize = file.size;
fileData.mimeType = file.mimetype;
if (isImage(file.mimetype)) {
const dimensions = await getImageSize(file);
fileData.width = dimensions.width;
fileData.height = dimensions.height;
if (Array.isArray(imageSizes) && file.mimetype !== 'image/svg+xml') {
req.payloadUploadSizes = {};
fileData.sizes = await resizeAndSave({
req,
file: file.data,
dimensions,
staticPath,
config: collectionConfig,
savedFilename: fsSafeName,
mimeType: fileData.mimeType,
});
}
}
} catch (err) {
console.error(err);
throw new FileUploadError();
}
newData = {
...newData,
...fileData,
};
}
}
return newData;
};
export default uploadFile;