Refactor backend folder structure (#4505)
* Refactor backend folder structure Co-authored-by: Charles Bochet <charles@twenty.com> * fix tests * fix * move yoga hooks --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -0,0 +1,98 @@
|
||||
import { Readable } from 'stream';
|
||||
|
||||
import {
|
||||
CreateBucketCommandInput,
|
||||
GetObjectCommand,
|
||||
HeadBucketCommandInput,
|
||||
NotFound,
|
||||
PutObjectCommand,
|
||||
S3,
|
||||
S3ClientConfig,
|
||||
} from '@aws-sdk/client-s3';
|
||||
|
||||
import { StorageDriver } from './interfaces/storage-driver.interface';
|
||||
|
||||
export interface S3DriverOptions extends S3ClientConfig {
|
||||
bucketName: string;
|
||||
endpoint?: string;
|
||||
region: string;
|
||||
}
|
||||
|
||||
export class S3Driver implements StorageDriver {
|
||||
private s3Client: S3;
|
||||
private bucketName: string;
|
||||
|
||||
constructor(options: S3DriverOptions) {
|
||||
const { bucketName, region, endpoint, ...s3Options } = options;
|
||||
|
||||
if (!bucketName || !region) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.s3Client = new S3({ ...s3Options, region, endpoint });
|
||||
this.bucketName = bucketName;
|
||||
}
|
||||
|
||||
public get client(): S3 {
|
||||
return this.s3Client;
|
||||
}
|
||||
|
||||
async write(params: {
|
||||
file: Buffer | Uint8Array | string;
|
||||
name: string;
|
||||
folder: string;
|
||||
mimeType: string | undefined;
|
||||
}): Promise<void> {
|
||||
const command = new PutObjectCommand({
|
||||
Key: `${params.folder}/${params.name}`,
|
||||
Body: params.file,
|
||||
ContentType: params.mimeType,
|
||||
Bucket: this.bucketName,
|
||||
});
|
||||
|
||||
await this.s3Client.send(command);
|
||||
}
|
||||
|
||||
async read(params: {
|
||||
folderPath: string;
|
||||
filename: string;
|
||||
}): Promise<Readable> {
|
||||
const command = new GetObjectCommand({
|
||||
Key: `${params.folderPath}/${params.filename}`,
|
||||
Bucket: this.bucketName,
|
||||
});
|
||||
const file = await this.s3Client.send(command);
|
||||
|
||||
if (!file || !file.Body || !(file.Body instanceof Readable)) {
|
||||
throw new Error('Unable to get file stream');
|
||||
}
|
||||
|
||||
return Readable.from(file.Body);
|
||||
}
|
||||
|
||||
async checkBucketExists(args: HeadBucketCommandInput) {
|
||||
try {
|
||||
await this.s3Client.headBucket(args);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error instanceof NotFound) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async createBucket(args: CreateBucketCommandInput) {
|
||||
const exist = await this.checkBucketExists({
|
||||
Bucket: args.Bucket,
|
||||
});
|
||||
|
||||
if (exist) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.s3Client.createBucket(args);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user