mirror of
https://github.com/ZSCGR/CloudFlare-ImgBed.git
synced 2026-08-17 14:13:44 +08:00
134 lines
4.6 KiB
JavaScript
134 lines
4.6 KiB
JavaScript
/**
|
|
* Metadata 管理端视图工具
|
|
* 负责生成管理端可展示的 metadata,过滤敏感字段并按当前渠道配置补齐派生字段
|
|
*/
|
|
import { findConfiguredChannel, loadChannelConfig } from './channelConfig.js';
|
|
import { stripConfigDerivedMetadata, stripSensitiveMetadata } from './metadataSecurity.js';
|
|
import { buildWebDAVUrl } from '../storage/webdavAPI.js';
|
|
|
|
/* ========== 主要函数 ========== */
|
|
|
|
// 创建复用的视图上下文,避免批量序列化时重复读取上传配置
|
|
export async function createMetadataViewContext(db, env) {
|
|
return {
|
|
db,
|
|
env,
|
|
uploadConfig: await loadChannelConfig(db, env, 'metadata view'),
|
|
};
|
|
}
|
|
|
|
// 构建管理端可见 metadata,过滤敏感字段并补齐可展示链接
|
|
export async function buildFileMetadataForManagement(db, env, metadata = {}, viewContext = null) {
|
|
const context = viewContext || await createMetadataViewContext(db, env);
|
|
const view = stripConfigDerivedMetadata(stripSensitiveMetadata(metadata));
|
|
|
|
// 管理端展示字段从当前渠道配置实时补齐,不依赖旧 metadata 中保存的派生值
|
|
enrichS3Metadata(context, metadata, view);
|
|
enrichHuggingFaceMetadata(context, metadata, view);
|
|
enrichWebDAVMetadata(context, metadata, view);
|
|
|
|
return view;
|
|
}
|
|
|
|
// 将文件记录序列化为管理端列表接口使用的安全结构
|
|
export async function serializeFileRecordForManagement(db, env, file, viewContext = null) {
|
|
return {
|
|
name: file.id || file.name,
|
|
metadata: await buildFileMetadataForManagement(db, env, file.metadata, viewContext),
|
|
};
|
|
}
|
|
|
|
/* ========== 关键函数 ========== */
|
|
|
|
// 根据当前 S3 渠道配置补齐访问位置和 CDN URL
|
|
function enrichS3Metadata(context, sourceMetadata, view) {
|
|
if (sourceMetadata?.Channel !== 'S3') return;
|
|
|
|
try {
|
|
const channel = findConfiguredChannel(context.uploadConfig, 's3', sourceMetadata);
|
|
if (!channel) return;
|
|
|
|
const credentials = {
|
|
endpoint: channel.endpoint,
|
|
region: channel.region || 'auto',
|
|
bucketName: channel.bucketName,
|
|
pathStyle: channel.pathStyle || false,
|
|
cdnDomain: channel.cdnDomain || '',
|
|
key: sourceMetadata.S3FileKey,
|
|
};
|
|
|
|
if (!credentials.key) return;
|
|
|
|
if (credentials.endpoint && credentials.bucketName) {
|
|
view.S3Location = buildS3Location(credentials, credentials.key);
|
|
}
|
|
|
|
if (credentials.cdnDomain) {
|
|
view.S3CdnFileUrl = buildCdnFileUrl(credentials.cdnDomain, credentials.key);
|
|
}
|
|
} catch (error) {
|
|
console.warn('Failed to enrich S3 metadata:', error.message);
|
|
}
|
|
}
|
|
|
|
// 根据当前 HuggingFace 渠道配置补齐文件访问 URL
|
|
function enrichHuggingFaceMetadata(context, sourceMetadata, view) {
|
|
if (sourceMetadata?.Channel !== 'HuggingFace') return;
|
|
|
|
try {
|
|
const channel = findConfiguredChannel(context.uploadConfig, 'huggingface', sourceMetadata);
|
|
if (!channel) return;
|
|
|
|
if (channel.repo && sourceMetadata.HfFilePath) {
|
|
view.HfFileUrl = `https://huggingface.co/datasets/${channel.repo}/resolve/main/${sourceMetadata.HfFilePath}`;
|
|
}
|
|
} catch (error) {
|
|
console.warn('Failed to enrich HuggingFace metadata:', error.message);
|
|
}
|
|
}
|
|
|
|
// 根据当前 WebDAV 渠道配置补齐公开访问 URL
|
|
function enrichWebDAVMetadata(context, sourceMetadata, view) {
|
|
if (sourceMetadata?.Channel !== 'WebDAV') return;
|
|
|
|
try {
|
|
const channel = findConfiguredChannel(context.uploadConfig, 'webdav', sourceMetadata);
|
|
if (!channel) return;
|
|
|
|
if (channel.publicUrl && sourceMetadata.WebDAVFilePath) {
|
|
view.WebDAVPublicUrl = buildWebDAVUrl(channel.publicUrl, sourceMetadata.WebDAVFilePath);
|
|
}
|
|
} catch (error) {
|
|
console.warn('Failed to enrich WebDAV metadata:', error.message);
|
|
}
|
|
}
|
|
|
|
/* ========== 工具函数 ========== */
|
|
|
|
// 构建 S3 对象的源站访问地址
|
|
export function buildS3Location(credentials, key) {
|
|
const endpointHost = stripEndpointProtocol(credentials.endpoint);
|
|
if (!endpointHost || !credentials.bucketName || !key) return '';
|
|
|
|
// 同时支持 path-style 与 virtual-hosted-style 两种 S3 访问形式
|
|
if (credentials.pathStyle) {
|
|
return `https://${endpointHost}/${credentials.bucketName}/${key}`;
|
|
}
|
|
|
|
return `https://${credentials.bucketName}.${endpointHost}/${key}`;
|
|
}
|
|
|
|
// 构建渠道 CDN 域名下的文件访问地址
|
|
export function buildCdnFileUrl(cdnDomain, key) {
|
|
if (!cdnDomain || !key) return '';
|
|
return `${String(cdnDomain).replace(/\/+$/, '')}/${key}`;
|
|
}
|
|
|
|
// 去掉 endpoint 的协议和尾部斜杠,便于拼接 S3 地址
|
|
function stripEndpointProtocol(endpoint) {
|
|
return String(endpoint || '')
|
|
.trim()
|
|
.replace(/^https?:\/\//i, '')
|
|
.replace(/\/+$/, '');
|
|
}
|