Files
twenty/server/src/core/file/services/file-upload.service.ts
Jérémy M 9df83c9a5a feat: better server lint (#2850)
* feat: add stylistic eslint plugin

* feat: add missing line return

* feat: secure line-break style

* feat: disallow break before else

* feat: line between class members

* feat: better new line lint rule
2023-12-06 12:19:00 +01:00

118 lines
2.5 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import sharp from 'sharp';
import { v4 as uuidV4 } from 'uuid';
import { FileFolder } from 'src/core/file/interfaces/file-folder.interface';
import { getCropSize } from 'src/utils/image';
import { settings } from 'src/constants/settings';
import { FileStorageService } from 'src/integrations/file-storage/file-storage.service';
@Injectable()
export class FileUploadService {
constructor(private readonly fileStorage: FileStorageService) {}
private async _uploadFile({
file,
filename,
mimeType,
fileFolder,
}: {
file: Buffer | Uint8Array | string;
filename: string;
mimeType: string | undefined;
fileFolder: FileFolder;
}) {
await this.fileStorage.write({
file,
name: filename,
mimeType,
folder: fileFolder,
});
}
async uploadFile({
file,
filename,
mimeType,
fileFolder,
}: {
file: Buffer | Uint8Array | string;
filename: string;
mimeType: string | undefined;
fileFolder: FileFolder;
}) {
const ext = filename.split('.')?.[1];
const id = uuidV4();
const name = `${id}${ext ? `.${ext}` : ''}`;
await this._uploadFile({
file,
filename: name,
mimeType,
fileFolder,
});
return {
id,
mimeType,
path: `${fileFolder}/${name}`,
};
}
async uploadImage({
file,
filename,
mimeType,
fileFolder,
}: {
file: Buffer | Uint8Array | string;
filename: string;
mimeType: string | undefined;
fileFolder: FileFolder;
}) {
const ext = filename.split('.')?.[1];
const id = uuidV4();
const name = `${id}${ext ? `.${ext}` : ''}`;
const cropSizes = settings.storage.imageCropSizes[fileFolder];
if (!cropSizes) {
throw new Error(`No crop sizes found for ${fileFolder}`);
}
const sizes = cropSizes.map((shortSize) => getCropSize(shortSize));
const images = await Promise.all(
sizes.map((size) =>
sharp(file).resize({
[size?.type || 'width']: size?.value ?? undefined,
}),
),
);
const paths: Array<string> = [];
await Promise.all(
images.map(async (image, index) => {
const buffer = await image.toBuffer();
paths.push(`${fileFolder}/${cropSizes[index]}/${name}`);
return this._uploadFile({
file: buffer,
filename: `${cropSizes[index]}/${name}`,
mimeType,
fileFolder,
});
}),
);
return {
id,
mimeType,
paths,
};
}
}