* 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>
99 lines
2.1 KiB
TypeScript
99 lines
2.1 KiB
TypeScript
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);
|
|
}
|
|
}
|