/** Permanently decommissioned storage. Historical records remain for reference. */ export const RETIRED_STORAGE_URL_PATTERN = '^https?://s3[.]1080p[.]hk([/:?#]|$)'; export const RETIRED_STORAGE_MESSAGE = '旧存储已停用,源文件已无法恢复,请重新上传。'; export function normalizeLegacyAliyunStorageUrl(value: string | null | undefined): string | null { if (!value) return null; try { let url = new URL(value, 'https://local.invalid'); if (url.pathname === '/api/image-proxy' || url.pathname === '/api/canvas/3d/model-proxy') { url = new URL(url.searchParams.get('url') || ''); } if (url.hostname !== 'demo-sparkai.oss-cn-shanghai.aliyuncs.com') return null; url.protocol = 'https:'; url.hash = ''; for (const name of ['Signature', 'OSSAccessKeyId', 'Expires', 'security-token']) url.searchParams.delete(name); url.searchParams.sort(); return url.toString(); } catch { return null; } } export function isLegacyAliyunStorageConfig(config: { bucket?: string | null; endpoint?: string | null; publicUrl?: string | null }): boolean { if (normalizeLegacyAliyunStorageUrl(config.publicUrl)) return true; try { return config.bucket === 'demo-sparkai' && new URL(config.endpoint || '').hostname.endsWith('.aliyuncs.com'); } catch { return false; } } export function isRetiredStorageUrl(value: string | null | undefined): boolean { if (!value) return false; try { const url = new URL(value, 'https://local.invalid'); if (url.hostname === 's3.1080p.hk') return true; if (url.pathname === '/api/image-proxy' || url.pathname === '/api/canvas/3d/model-proxy') { const source = url.searchParams.get('url'); return Boolean(source && new URL(source).hostname === 's3.1080p.hk'); } } catch { /* Relative local assets and non-URL values are not retired storage. */ } return false; }