import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; export interface CloudStorageCredentials { enabled?: boolean; platform?: string; channel?: string; provider_name?: string; account_id?: string; access_key_id?: string; secret_access_key?: string; endpoint?: string; buckets: BucketItem[]; } export interface ClientStorageCredentials { enabled?: boolean; platform?: string; channel?: string; provider_name?: string; buckets: BucketItem[]; } export interface BucketItem { bucket: string; custom_domain?: string; prefix?: string; file_types?: string; // 允许上传的文件类型 file_size?: string; // 单个文件限制(字节) max_files?: string; // 存储桶最大文件数量 max_storage?: string; // 存储桶最大存储容量(字节) region?: string; public: boolean; } export interface FileObject { Key?: string; LastModified?: Date; ETag?: string; Size?: number; StorageClass?: string; } export function createS3Client( endpoint: string, accessKeyId: string, secretAccessKey: string, region: string = "auto", ) { return new S3Client({ region: region, endpoint: endpoint, credentials: { accessKeyId, secretAccessKey, }, }); } export async function uploadFile( file: Buffer, key: string, s3: S3Client, bucket: string, ) { const command = new PutObjectCommand({ Bucket: bucket, Key: key, Body: file, }); try { const response = await s3.send(command); return response; } catch (error) { console.error("Error uploading file:", error); throw error; } } export async function getSignedUrlForUpload( key: string, contentType: string, s3: S3Client, bucket: string, ): Promise { const command = new PutObjectCommand({ Bucket: bucket, Key: key, ContentType: contentType, }); try { const signedUrl = await getSignedUrl(s3, command, { expiresIn: 3600 }); return signedUrl; } catch (error) { console.error("Error generating signed URL:", error); throw error; } } export async function getSignedUrlForDownload( key: string, s3: S3Client, bucket: string, ): Promise { const command = new GetObjectCommand({ Bucket: bucket, Key: key, }); try { const signedUrl = await getSignedUrl(s3, command, { expiresIn: 3600 }); return signedUrl; } catch (error) { console.error("Error generating signed URL:", error); throw error; } } export async function listFiles( prefix: string = "", s3: S3Client, bucket: string, ): Promise { const command = new ListObjectsV2Command({ Bucket: bucket, Prefix: prefix, }); try { const response = await s3.send(command); return response.Contents || []; } catch (error) { console.error("Error listing files:", error); throw error; } } export async function getFileInfo(R2: S3Client, bucket: string, key: string) { try { const headCommand = new HeadObjectCommand({ Bucket: bucket, Key: key, }); const headResponse = await R2.send(headCommand); return { size: headResponse.ContentLength || 0, etag: headResponse.ETag || "", lastModified: headResponse.LastModified || new Date(), contentType: headResponse.ContentType || "", storageClass: headResponse.StorageClass || "", metadata: headResponse.Metadata || {}, }; } catch (error) { console.error("Error getting file info:", error); throw error; } } export async function deleteFile(key: string, s3: S3Client, bucket: string) { const command = new DeleteObjectCommand({ Bucket: bucket, Key: key, }); try { const response = await s3.send(command); return response; } catch (error) { console.error("Error deleting file:", error); throw error; } }