184 lines
3.9 KiB
TypeScript
184 lines
3.9 KiB
TypeScript
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<string> {
|
|
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<string> {
|
|
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<FileObject[]> {
|
|
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;
|
|
}
|
|
}
|