import { fetchWithRetry, pollStatus } from './apiUtils'; const MESHY_BASE_URL = 'https://api.meshy.ai/openapi/v1'; export interface MeshyTaskResponse { result: string; progress: number; status: 'PENDING' | 'IN_PROGRESS' | 'SUCCEEDED' | 'FAILED' | 'EXPIRED'; task_error?: { message: string }; model_urls?: { glb: string; usdz?: string }; } export async function createMeshyTask(apiKey: string, imageBase64DataUrl: string): Promise { const response = await fetchWithRetry(`${MESHY_BASE_URL}/image-to-3d`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ image_url: imageBase64DataUrl, enable_pbr: true, should_remesh: true }) }); const data = await response.json(); return data.result; // Task ID } export async function waitForMeshyTask(apiKey: string, taskId: string, onProgress?: (p: number) => void): Promise { return pollStatus(async () => { const response = await fetchWithRetry(`${MESHY_BASE_URL}/image-to-3d/${taskId}`, { headers: { 'Authorization': `Bearer ${apiKey}` }, maxRetries: 2, baseDelayMs: 500 }); const data: MeshyTaskResponse = await response.json(); if (data.status === 'SUCCEEDED' && data.model_urls?.glb) { return { status: 'success', data: data.model_urls.glb }; } if (data.status === 'FAILED' || data.status === 'EXPIRED') { console.error("Meshy task failed:", data.task_error); return { status: 'failed' }; } return { status: 'processing', progress: data.progress || 0 }; }, { intervalMs: 3000, maxAttempts: 100, // 5 minutes max wait onProgress }); }