route.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { NextRequest, NextResponse } from "next/server";
  2. import { z } from "zod";
  3. import { tmdbFetch, filterAdultMovies } from "@/lib/tmdb/client";
  4. import { DISCOVER_CERT_PARAMS } from "@/lib/tmdb/certification";
  5. import type { TMDBSearchResponse } from "@/types/tmdb";
  6. const popularParamsSchema = z.object({
  7. page: z.coerce.number().int().min(1).max(500).optional().default(1),
  8. });
  9. export async function GET(request: NextRequest) {
  10. const rawParams = Object.fromEntries(request.nextUrl.searchParams);
  11. const parsed = popularParamsSchema.safeParse(rawParams);
  12. if (!parsed.success) {
  13. return NextResponse.json(
  14. { error: "Invalid parameters", details: parsed.error.flatten().fieldErrors },
  15. { status: 400 },
  16. );
  17. }
  18. const { page } = parsed.data;
  19. try {
  20. // Use /discover with sort_by=popularity.desc + cert filter so TMDB
  21. // pre-filters server-side; we still post-filter adult flags defensively.
  22. const data = await tmdbFetch<TMDBSearchResponse>("/discover/movie", {
  23. ...DISCOVER_CERT_PARAMS,
  24. sort_by: "popularity.desc",
  25. page: String(page),
  26. });
  27. return NextResponse.json(filterAdultMovies(data), {
  28. headers: { "Cache-Control": "public, s-maxage=300, stale-while-revalidate=60" },
  29. });
  30. } catch (error) {
  31. console.error("TMDB popular error:", error);
  32. return NextResponse.json({ error: "Failed to fetch popular movies" }, { status: 500 });
  33. }
  34. }