import { NextRequest, NextResponse } from 'next/server'; import { db, marketplaceListings } from '@mcpengine/db'; import { eq, ilike, and, desc, count, or, sql } from 'drizzle-orm'; // ── GET /api/marketplace — public listing search ──────────────────────────── export async function GET(req: NextRequest) { try { const url = new URL(req.url); const query = url.searchParams.get('q') || ''; const category = url.searchParams.get('category') || ''; const official = url.searchParams.get('official'); const featured = url.searchParams.get('featured'); const page = Math.max(1, parseInt(url.searchParams.get('page') || '1', 10)); const limit = Math.min(50, Math.max(1, parseInt(url.searchParams.get('limit') || '24', 10))); const offset = (page - 1) * limit; // Build filter conditions — only published listings const conditions = [eq(marketplaceListings.status, 'published')]; if (category) { conditions.push(eq(marketplaceListings.category, category)); } if (official === 'true') { conditions.push(eq(marketplaceListings.isOfficial, true)); } if (featured === 'true') { conditions.push(eq(marketplaceListings.isFeatured, true)); } if (query) { conditions.push( or( ilike(marketplaceListings.name, `%${query}%`), ilike(marketplaceListings.description, `%${query}%`), ilike(marketplaceListings.slug, `%${query}%`), )!, ); } const where = and(...conditions); const [rows, totalResult] = await Promise.all([ db .select() .from(marketplaceListings) .where(where) .orderBy( desc(marketplaceListings.isFeatured), desc(marketplaceListings.forkCount), desc(marketplaceListings.createdAt), ) .limit(limit) .offset(offset), db .select({ count: count() }) .from(marketplaceListings) .where(where), ]); const total = totalResult[0]?.count ?? 0; // Collect distinct categories for faceting const categories = await db .selectDistinct({ category: marketplaceListings.category }) .from(marketplaceListings) .where(eq(marketplaceListings.status, 'published')); return NextResponse.json({ data: rows, meta: { page, limit, total, totalPages: Math.ceil(total / limit), categories: categories .map((c) => c.category) .filter(Boolean) .sort(), }, }); } catch (error) { console.error('[GET /api/marketplace]', error); return NextResponse.json( { error: 'Internal server error' }, { status: 500 }, ); } }