oex2003/evolution-api
0
1import { ConfigService, S3 } from '@config/env.config';2import { Logger } from '@config/logger.config';3import { BadRequestException } from '@exceptions';4import * as MinIo from 'minio';5import { join } from 'path';6import { Readable, Transform } from 'stream';7 8const logger = new Logger('S3 Service');9 10const BUCKET = new ConfigService().get<S3>('S3');11 12interface Metadata extends MinIo.ItemBucketMetadata {13 'Content-Type': string;14}15 16const minioClient = (() => {17 if (BUCKET?.ENABLE) {18 return new MinIo.Client({19 endPoint: BUCKET.ENDPOINT,20 port: BUCKET.PORT,21 useSSL: BUCKET.USE_SSL,22 accessKey: BUCKET.ACCESS_KEY,23 secretKey: BUCKET.SECRET_KEY,24 region: BUCKET.REGION,25 });26 }27})();28 29const bucketName = process.env.S3_BUCKET;30 31const bucketExists = async () => {32 if (minioClient) {33 try {34 const list = await minioClient.listBuckets();35 return list.find((bucket) => bucket.name === bucketName);36 } catch (error) {37 return false;38 }39 }40};41 42const setBucketPolicy = async () => {43 if (minioClient) {44 const policy = {45 Version: '2012-10-17',46 Statement: [47 {48 Effect: 'Allow',49 Principal: '*',50 Action: ['s3:GetObject'],51 Resource: [`arn:aws:s3:::${bucketName}/*`],52 },53 ],54 };55 await minioClient.setBucketPolicy(bucketName, JSON.stringify(policy));56 }57};58 59const createBucket = async () => {60 if (minioClient) {61 try {62 const exists = await bucketExists();63 if (!exists) {64 await minioClient.makeBucket(bucketName);65 }66 if (!BUCKET.SKIP_POLICY) {67 await setBucketPolicy();68 }69 logger.info(`S3 Bucket ${bucketName} - ON`);70 return true;71 } catch (error) {72 logger.error('S3 ERROR:');73 logger.error(error);74 return false;75 }76 }77};78 79createBucket();80 81const uploadFile = async (fileName: string, file: Buffer | Transform | Readable, size: number, metadata: Metadata) => {82 if (minioClient) {83 const objectName = join('evolution-api', fileName);84 try {85 metadata['custom-header-application'] = 'evolution-api';86 return await minioClient.putObject(bucketName, objectName, file, size, metadata);87 } catch (error) {88 logger.error(error);89 return error;90 }91 }92};93 94const getObjectUrl = async (fileName: string, expiry?: number) => {95 if (minioClient) {96 try {97 const objectName = join('evolution-api', fileName);98 if (expiry) {99 return await minioClient.presignedGetObject(bucketName, objectName, expiry);100 }101 return await minioClient.presignedGetObject(bucketName, objectName);102 } catch (error) {103 throw new BadRequestException(error?.message);104 }105 }106};107 108const uploadTempFile = async (109 folder: string,110 fileName: string,111 file: Buffer | Transform | Readable,112 size: number,113 metadata: Metadata,114) => {115 if (minioClient) {116 const objectName = join(folder, fileName);117 try {118 metadata['custom-header-application'] = 'evolution-api';119 return await minioClient.putObject(bucketName, objectName, file, size, metadata);120 } catch (error) {121 logger.error(error);122 return error;123 }124 }125};126 127const deleteFile = async (folder: string, fileName: string) => {128 if (minioClient) {129 const objectName = join(folder, fileName);130 try {131 return await minioClient.removeObject(bucketName, objectName);132 } catch (error) {133 logger.error(error);134 return error;135 }136 }137};138 139export { BUCKET, deleteFile, getObjectUrl, uploadFile, uploadTempFile };140 