109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
import type { AttachmentStorageBackend, UserAttachmentStorageConfig } from "@/lib/boss-data";
|
||
import { createAliyunOssStorageProvider, validateAliyunOssConfig } from "@/lib/boss-storage-aliyun-oss";
|
||
import { storeServerFileAttachment } from "@/lib/boss-storage-server-file";
|
||
|
||
export interface StoreAttachmentParams {
|
||
account: string;
|
||
messageId: string;
|
||
attachmentId: string;
|
||
fileName: string;
|
||
mimeType: string;
|
||
buffer: Buffer;
|
||
}
|
||
|
||
export interface StoredAttachmentRecord {
|
||
storageBackend: AttachmentStorageBackend;
|
||
storagePath: string;
|
||
}
|
||
|
||
export interface AttachmentStorageProvider {
|
||
backend: AttachmentStorageBackend;
|
||
storeAttachment(params: StoreAttachmentParams): Promise<StoredAttachmentRecord>;
|
||
}
|
||
|
||
export interface SanitizedUserAttachmentStorageConfig {
|
||
account: string;
|
||
mode: UserAttachmentStorageConfig["mode"];
|
||
ossProvider?: UserAttachmentStorageConfig["ossProvider"];
|
||
aliyunOss?: {
|
||
enabled: boolean;
|
||
accessKeyId: string;
|
||
accessKeySecretConfigured: boolean;
|
||
bucket: string;
|
||
endpoint: string;
|
||
region: string;
|
||
prefix?: string;
|
||
};
|
||
updatedAt: string;
|
||
validatedAt?: string;
|
||
}
|
||
|
||
const serverFileProvider: AttachmentStorageProvider = {
|
||
backend: "server_file",
|
||
async storeAttachment(params) {
|
||
return storeServerFileAttachment(params);
|
||
},
|
||
};
|
||
|
||
export function getAttachmentStorageProvider(
|
||
config: UserAttachmentStorageConfig,
|
||
) {
|
||
if (config.mode === "server_file") {
|
||
return serverFileProvider;
|
||
}
|
||
|
||
if (config.mode === "oss" && config.ossProvider === "aliyun_oss" && config.aliyunOss) {
|
||
return createAliyunOssStorageProvider(config.aliyunOss);
|
||
}
|
||
|
||
throw new Error("ATTACHMENT_STORAGE_MODE_NOT_SUPPORTED");
|
||
}
|
||
|
||
export function sanitizeAttachmentStorageConfig(
|
||
config: UserAttachmentStorageConfig,
|
||
): SanitizedUserAttachmentStorageConfig {
|
||
return {
|
||
account: config.account,
|
||
mode: config.mode,
|
||
ossProvider: config.ossProvider,
|
||
aliyunOss: config.aliyunOss
|
||
? {
|
||
enabled: config.aliyunOss.enabled,
|
||
accessKeyId: config.aliyunOss.accessKeyId,
|
||
accessKeySecretConfigured: Boolean(config.aliyunOss.accessKeySecretEncrypted),
|
||
bucket: config.aliyunOss.bucket,
|
||
endpoint: config.aliyunOss.endpoint,
|
||
region: config.aliyunOss.region,
|
||
prefix: config.aliyunOss.prefix,
|
||
}
|
||
: undefined,
|
||
updatedAt: config.updatedAt,
|
||
validatedAt: config.validatedAt,
|
||
};
|
||
}
|
||
|
||
export function normalizeStorageError(error: unknown) {
|
||
const message = error instanceof Error ? error.message : "UNKNOWN_STORAGE_ERROR";
|
||
switch (message) {
|
||
case "ALIYUN_OSS_NOT_ENABLED":
|
||
return "阿里 OSS 尚未启用。";
|
||
case "ALIYUN_OSS_CONFIG_INCOMPLETE":
|
||
return "阿里 OSS 配置不完整,请补齐 AccessKey、Bucket、Endpoint 和 Region。";
|
||
case "ALIYUN_OSS_SECRET_REQUIRED":
|
||
return "请填写 AccessKey Secret。";
|
||
case "ALIYUN_OSS_PROVIDER_REQUIRED":
|
||
return "当前只支持阿里 OSS,请先选择阿里 OSS。";
|
||
case "INVALID_STORAGE_SECRET_FORMAT":
|
||
return "当前 OSS 密钥格式无效,请重新填写 AccessKey Secret。";
|
||
default:
|
||
return message;
|
||
}
|
||
}
|
||
|
||
export async function validateAttachmentStorageConfig(config: UserAttachmentStorageConfig) {
|
||
if (config.mode !== "oss" || config.ossProvider !== "aliyun_oss" || !config.aliyunOss) {
|
||
throw new Error("ALIYUN_OSS_NOT_ENABLED");
|
||
}
|
||
return validateAliyunOssConfig(config.aliyunOss);
|
||
}
|