feat: initial release v0.3.0
This commit is contained in:
161
scripts/test-full-image-flow.ts
Normal file
161
scripts/test-full-image-flow.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 模拟完整的图像生成和显示流程
|
||||
* 运行: npx tsx scripts/test-full-image-flow.ts
|
||||
*/
|
||||
import { config } from 'dotenv'
|
||||
config()
|
||||
|
||||
import { uploadObject, getStorageProvider } from '../src/lib/storage'
|
||||
import { extractStorageKeyFromLegacyValue, resolveMediaRefFromLegacyValue, getMediaObjectByPublicId } from '../src/lib/media/service'
|
||||
import { attachMediaFieldsToProject } from '../src/lib/media/attach'
|
||||
import { randomUUID } from 'crypto'
|
||||
|
||||
async function testFullImageFlow() {
|
||||
console.log('🧪 模拟完整图像生成和显示流程...\n')
|
||||
|
||||
const provider = getStorageProvider()
|
||||
console.log(`存储类型: ${provider.kind}\n`)
|
||||
|
||||
// 1. 模拟图像生成后的上传
|
||||
console.log('1️⃣ 模拟图像生成后上传:')
|
||||
const testKey = `images/location-${randomUUID()}.jpg`
|
||||
const testImageContent = Buffer.from('fake-generated-image-data')
|
||||
|
||||
const storedKey = await uploadObject(testImageContent, testKey)
|
||||
console.log(` ✅ 上传成功,返回 key: ${storedKey}`)
|
||||
|
||||
// 2. 模拟数据库存储(存储 key)
|
||||
console.log('\n2️⃣ 模拟数据库存储:')
|
||||
const mockDbLocation = {
|
||||
id: 'loc-test-123',
|
||||
name: '测试场景',
|
||||
images: [
|
||||
{
|
||||
id: 'img-1',
|
||||
imageUrl: storedKey, // 存储的是 key,不是完整 URL
|
||||
imageIndex: 0,
|
||||
}
|
||||
]
|
||||
}
|
||||
console.log(` 存储的 imageUrl: ${storedKey}`)
|
||||
|
||||
// 3. 测试 extractStorageKeyFromLegacyValue
|
||||
console.log('\n3️⃣ 测试 extractStorageKeyFromLegacyValue:')
|
||||
const extractedKey = extractStorageKeyFromLegacyValue(storedKey)
|
||||
console.log(` 输入: ${storedKey}`)
|
||||
console.log(` 输出: ${extractedKey}`)
|
||||
if (extractedKey) {
|
||||
console.log(` ✅ 成功提取 storageKey`)
|
||||
} else {
|
||||
console.log(` ❌ 未能提取 storageKey - 这是问题所在!`)
|
||||
}
|
||||
|
||||
// 4. 测试 resolveMediaRefFromLegacyValue(创建 MediaObject)
|
||||
console.log('\n4️⃣ 测试 resolveMediaRefFromLegacyValue:')
|
||||
try {
|
||||
const mediaRef = await resolveMediaRefFromLegacyValue(storedKey)
|
||||
if (mediaRef) {
|
||||
console.log(` ✅ MediaObject 创建/获取成功`)
|
||||
console.log(` id: ${mediaRef.id}`)
|
||||
console.log(` publicId: ${mediaRef.publicId}`)
|
||||
console.log(` url: ${mediaRef.url}`)
|
||||
console.log(` storageKey: ${mediaRef.storageKey}`)
|
||||
} else {
|
||||
console.log(` ❌ MediaRef 为 null`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ❌ 失败:`, error)
|
||||
}
|
||||
|
||||
// 5. 测试 attachMediaFieldsToProject(完整流程)
|
||||
console.log('\n5️⃣ 测试 attachMediaFieldsToProject(API 层转换):')
|
||||
try {
|
||||
const mockProject = {
|
||||
id: 'proj-test',
|
||||
locations: [mockDbLocation]
|
||||
}
|
||||
|
||||
const result = await attachMediaFieldsToProject(mockProject)
|
||||
const location = result.locations?.[0]
|
||||
const image = location?.images?.[0]
|
||||
|
||||
console.log(` 转换后的 imageUrl: ${image?.imageUrl}`)
|
||||
|
||||
if (image?.imageUrl?.startsWith('/m/')) {
|
||||
console.log(` ✅ 正确生成了 /m/ 格式的 URL`)
|
||||
|
||||
// 提取 publicId
|
||||
const publicId = image.imageUrl.replace('/m/', '').split('?')[0]
|
||||
console.log(` publicId: ${publicId}`)
|
||||
|
||||
// 验证 MediaObject 存在
|
||||
const media = await getMediaObjectByPublicId(publicId)
|
||||
if (media) {
|
||||
console.log(` ✅ MediaObject 存在,storageKey: ${media.storageKey}`)
|
||||
} else {
|
||||
console.log(` ❌ MediaObject 不存在!`)
|
||||
}
|
||||
} else if (image?.imageUrl?.startsWith('http')) {
|
||||
console.log(` ⚠️ 返回了完整 HTTP URL: ${image.imageUrl}`)
|
||||
} else if (!image?.imageUrl) {
|
||||
console.log(` ❌ imageUrl 为空!`)
|
||||
} else {
|
||||
console.log(` ⚠️ URL 格式: ${image.imageUrl}`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ❌ 失败:`, error)
|
||||
}
|
||||
|
||||
// 6. 测试访问 /m/ URL
|
||||
console.log('\n6️⃣ 测试访问 /m/ URL:')
|
||||
try {
|
||||
const mockProject = {
|
||||
id: 'proj-test',
|
||||
locations: [mockDbLocation]
|
||||
}
|
||||
|
||||
const result = await attachMediaFieldsToProject(mockProject)
|
||||
const imageUrl = result.locations?.[0]?.images?.[0]?.imageUrl
|
||||
|
||||
if (imageUrl?.startsWith('/m/')) {
|
||||
const fullUrl = `http://localhost:3000${imageUrl}`
|
||||
console.log(` 尝试访问: ${fullUrl}`)
|
||||
|
||||
try {
|
||||
const response = await fetch(fullUrl, { redirect: 'manual' })
|
||||
console.log(` 状态: ${response.status}`)
|
||||
|
||||
if (response.status === 200) {
|
||||
console.log(` ✅ /m/ 端点工作正常`)
|
||||
} else if (response.status === 307 || response.status === 302) {
|
||||
console.log(` ✅ /m/ 端点返回重定向(正常)`)
|
||||
console.log(` Location: ${response.headers.get('location')?.substring(0, 80)}...`)
|
||||
} else if (response.status === 404) {
|
||||
console.log(` ❌ MediaObject 未找到(404)`)
|
||||
} else {
|
||||
console.log(` ⚠️ 状态码: ${response.status}`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ⚠️ 请求失败(可能服务器未启动):`, error)
|
||||
}
|
||||
} else {
|
||||
console.log(` 跳过测试(URL 格式不正确)`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` 跳过测试:`, error)
|
||||
}
|
||||
|
||||
// 清理
|
||||
console.log('\n7️⃣ 清理测试数据:')
|
||||
try {
|
||||
const { deleteObject } = await import('../src/lib/storage')
|
||||
await deleteObject(storedKey)
|
||||
console.log(` ✅ 删除成功`)
|
||||
} catch (error) {
|
||||
console.log(` ⚠️ 删除失败:`, error)
|
||||
}
|
||||
|
||||
console.log('\n✨ 测试完成!')
|
||||
}
|
||||
|
||||
testFullImageFlow().catch(console.error)
|
||||
Reference in New Issue
Block a user