w-funnel/src/app/api/images/[filename]/route.ts
dev.daminik00 5aea1c8a09 fix
2025-10-01 16:47:04 +02:00

116 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server';
import connectMongoDB from '@/lib/mongodb';
import { Image, type IImage } from '@/lib/models/Image';
import { IS_FRONTEND_ONLY_BUILD } from '@/lib/runtime/buildVariant';
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ filename: string }> }
) {
try {
// Проверяем что это полная сборка (с БД)
if (IS_FRONTEND_ONLY_BUILD) {
return NextResponse.json(
{ error: 'Image serving not available in frontend-only mode' },
{ status: 403 }
);
}
await connectMongoDB();
const { filename } = await params;
if (!filename) {
return NextResponse.json(
{ error: 'Filename is required' },
{ status: 400 }
);
}
const image = await Image.findOne({ filename }).lean() as IImage | null;
if (!image) {
return NextResponse.json(
{ error: 'Image not found' },
{ status: 404 }
);
}
// Возвращаем изображение с правильными заголовками
const buffer = image.data instanceof Buffer ? image.data : Buffer.from(image.data);
// Специальная обработка для SVG файлов
let contentType = image.mimetype;
if (filename.endsWith('.svg') && contentType === 'image/svg+xml') {
contentType = 'image/svg+xml; charset=utf-8';
}
return new NextResponse(buffer as unknown as BodyInit, {
status: 200,
headers: {
'Content-Type': contentType,
'Content-Length': buffer.length.toString(),
'Cache-Control': 'public, max-age=31536000, immutable',
'Content-Disposition': `inline; filename="${image.originalName}"`,
'Access-Control-Allow-Origin': '*',
// Дополнительные заголовки для SVG
'X-Content-Type-Options': 'nosniff',
},
});
} catch (error) {
console.error('Image serving error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ filename: string }> }
) {
try {
// Проверяем что это полная сборка (с БД)
if (IS_FRONTEND_ONLY_BUILD) {
return NextResponse.json(
{ error: 'Image deletion not available in frontend-only mode' },
{ status: 403 }
);
}
await connectMongoDB();
const { filename } = await params;
if (!filename) {
return NextResponse.json(
{ error: 'Filename is required' },
{ status: 400 }
);
}
const deletedImage = await Image.findOneAndDelete({ filename });
if (!deletedImage) {
return NextResponse.json(
{ error: 'Image not found' },
{ status: 404 }
);
}
return NextResponse.json({
message: 'Image deleted successfully',
filename: deletedImage.filename
});
} catch (error) {
console.error('Image deletion error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}