fix(apk): streaming chunked delivery para APK en route handler

This commit is contained in:
AI Bot 2026-08-31 12:16:55 -05:00
parent d6f57c94b9
commit 6ca73d559e

View File

@ -7,20 +7,46 @@ export const dynamic = 'force-dynamic';
export async function GET() { export async function GET() {
const possiblePaths = [ const possiblePaths = [
path.join(process.cwd(), 'public', 'DripZone.apk'), path.join(process.cwd(), 'public', 'DripZone.apk'),
path.join(process.cwd(), '..', 'public', 'DripZone.apk'),
'/app/public/DripZone.apk', '/app/public/DripZone.apk',
'/home/carlos/apps/dripzone-app/public/DripZone.apk', path.resolve('public/DripZone.apk'),
path.join(process.cwd(), 'DripZone.apk'), path.join(process.cwd(), 'DripZone.apk'),
]; ];
const apkPath = possiblePaths.find((p) => fs.existsSync(p)); let apkPath: string | undefined;
if (!apkPath) { for (const p of possiblePaths) {
return new NextResponse('APK no disponible en este momento', { status: 404 }); try {
if (fs.existsSync(p)) {
apkPath = p;
break;
}
} catch {}
} }
const stat = fs.statSync(apkPath); if (!apkPath) {
const fileBuffer = fs.readFileSync(apkPath); return new NextResponse(
JSON.stringify({ error: 'APK no disponible', searched: possiblePaths, cwd: process.cwd() }),
{ status: 404, headers: { 'Content-Type': 'application/json' } }
);
}
return new NextResponse(fileBuffer, { try {
const stat = fs.statSync(apkPath);
const nodeStream = fs.createReadStream(apkPath);
// Convert node stream to web ReadableStream for chunked delivery
const webStream = new ReadableStream({
start(controller) {
nodeStream.on('data', (chunk) => controller.enqueue(chunk));
nodeStream.on('end', () => controller.close());
nodeStream.on('error', (err) => controller.error(err));
},
cancel() {
nodeStream.destroy();
},
});
return new Response(webStream, {
status: 200, status: 200,
headers: { headers: {
'Content-Type': 'application/vnd.android.package-archive', 'Content-Type': 'application/vnd.android.package-archive',
@ -29,4 +55,7 @@ export async function GET() {
'Cache-Control': 'public, max-age=3600, must-revalidate', 'Cache-Control': 'public, max-age=3600, must-revalidate',
}, },
}); });
} catch (err: any) {
return new NextResponse(`Error reading APK: ${err?.message || err}`, { status: 500 });
}
} }