diff --git a/app/api/create-zip-v2/route.ts b/app/api/create-zip-v2/route.ts new file mode 100644 index 00000000..4119e494 --- /dev/null +++ b/app/api/create-zip-v2/route.ts @@ -0,0 +1,78 @@ +import { NextResponse } from 'next/server'; + +declare global { + var activeSandboxProvider: any; +} + +export async function POST() { + try { + if (!global.activeSandboxProvider) { + return NextResponse.json({ + success: false, + error: 'No active sandbox' + }, { status: 400 }); + } + + console.log('[create-zip-v2] Creating project zip...'); + + // Create zip file in sandbox using standard commands + const zipResult = await global.activeSandboxProvider.runCommand( + 'tar --exclude="node_modules" --exclude=".git" --exclude=".next" --exclude="dist" --exclude="build" --exclude="*.log" -czf /tmp/project.tar.gz .' + ); + console.log('[create-zip-v2] zipResult', zipResult); + + if (zipResult.exitCode !== 0) { + const error = typeof zipResult.stderr === 'function' + ? await zipResult.stderr() + : zipResult.stderr || ''; + throw new Error(`Failed to create zip: ${error}`); + } + + + const sizeResult = await global.activeSandboxProvider.runCommand( + 'ls -la /tmp/project.tar.gz | awk \'{print $5}\'' + ); + + const fileSize = typeof sizeResult.stdout === 'function' + ? await sizeResult.stdout() + : sizeResult.stdout || ''; + console.log(`[create-zip] Created project.zip (${fileSize.trim()} bytes)`); + + // Read the zip file and convert to base64 + const readResult = await global.activeSandboxProvider.runCommand( + 'base64 /tmp/project.tar.gz' + ); + console.log('[create-zip-v2] readResult', readResult); + + if (readResult.exitCode !== 0) { + const error = typeof readResult.stderr === 'function' + ? await readResult.stderr() + : readResult.stderr || ''; + throw new Error(`Failed to read zip file: ${error}`); + } + + const base64Content = typeof readResult.stdout === 'function' + ? (await readResult.stdout()).trim() + : (readResult.stdout || '').trim(); + + // Create a data URL for download + const dataUrl = `data:application/tar+gz;base64,${base64Content}`; + + return NextResponse.json({ + success: true, + dataUrl, + fileName: 'vercel-sandbox-project.tar.gz', + message: 'Zip file created successfully' + }); + + } catch (error) { + console.error('[create-zip-v2] Error:', error); + return NextResponse.json( + { + success: false, + error: (error as Error).message + }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/app/generation/page.tsx b/app/generation/page.tsx index 4e4237cd..6f49eeda 100644 --- a/app/generation/page.tsx +++ b/app/generation/page.tsx @@ -2160,7 +2160,7 @@ Tip: I automatically detect and install npm packages from your code imports (lik addChatMessage('Creating ZIP file of your Vite app...', 'system'); try { - const response = await fetch('/api/create-zip', { + const response = await fetch('/api/create-zip-v2', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); diff --git a/lib/sandbox/providers/vercel-provider.ts b/lib/sandbox/providers/vercel-provider.ts index 60de4a17..a8f86822 100644 --- a/lib/sandbox/providers/vercel-provider.ts +++ b/lib/sandbox/providers/vercel-provider.ts @@ -24,7 +24,7 @@ export class VercelProvider extends SandboxProvider { // Create Vercel sandbox const sandboxConfig: any = { - timeout: 300000, // 5 minutes in ms + timeout: 900000, // 15 minutes in ms runtime: 'node22', // Use node22 runtime for Vercel sandboxes ports: [5173] // Vite port };