11import { NextRequest , NextResponse } from 'next/server' ;
22import { z } from 'zod' ;
33import { fetchTMDB } from '@/lib/tmdb' ;
4- import type { TMDBSearchResponse , TMDBConfigurationResponse } from '@/types/tmdb' ;
4+ import type { TMDBSearchResponse , TMDBMovie } from '@/types/tmdb' ;
55import type { APIResponse , MovieSearchResponse } from '@/types/api' ;
6+ import { enrichWithPosterUrl , getTMDBImageConfig } from '@/lib/tmdb-utls' ;
7+ import { ApiError } from '@/lib/apiError' ;
68
79const querySchema = z . object ( {
810 search : z . string ( ) . min ( 1 ) ,
@@ -12,47 +14,41 @@ const querySchema = z.object({
1214export async function GET (
1315 req : NextRequest
1416) : Promise < NextResponse < APIResponse < MovieSearchResponse > > > {
15- const url = new URL ( req . url ) ;
16- const query = Object . fromEntries ( url . searchParams . entries ( ) ) ;
17+ try {
18+ const url = new URL ( req . url ) ;
19+ const query = Object . fromEntries ( url . searchParams . entries ( ) ) ;
1720
18- const result = querySchema . safeParse ( query ) ;
21+ const result = querySchema . safeParse ( query ) ;
1922
20- if ( ! result . success ) {
21- return NextResponse . json ( { error : 'Invalid query' } , { status : 400 } ) ;
22- }
23+ if ( ! result . success ) {
24+ throw new ApiError ( 'Invalid query' , 400 ) ;
25+ }
2326
24- const { search, page } = result . data ;
27+ const { search, page } = result . data ;
2528
26- const revalidate = Number ( process . env . MOVIES_SEARCH_REVALIDATE ?? '300' ) ;
27- const configRevalidate = Number ( process . env . MOVIES_CONFIGURATION_REVALIDATE ?? '7200' ) ;
29+ const revalidate = Number ( process . env . MOVIES_SEARCH_REVALIDATE ?? '300' ) ;
2830
29- const movieRes = await fetchTMDB (
30- `/search/movie?query=${ encodeURIComponent ( search ) } &page=${ page } ` ,
31- revalidate
32- ) ;
31+ const moviesRes = await fetchTMDB (
32+ `/search/movie?query=${ encodeURIComponent ( search ) } &page=${ page } ` ,
33+ revalidate
34+ ) ;
3335
34- if ( ! movieRes . ok ) {
35- return NextResponse . json ( { error : 'unable to get movies' } , { status : movieRes . status } ) ;
36- }
36+ if ( ! moviesRes . ok ) {
37+ throw new ApiError ( 'unable to get movies' , moviesRes . status ) ;
38+ }
3739
38- const data : TMDBSearchResponse = await movieRes . json ( ) ;
40+ const data : TMDBSearchResponse = await moviesRes . json ( ) ;
3941
40- const configRes = await fetchTMDB ( '/configuration' , configRevalidate ) ;
42+ const { base , poster_sizes } = await getTMDBImageConfig ( ) ;
4143
42- if ( ! configRes . ok ) {
43- return NextResponse . json ( { error : 'unable to get movies' } , { status : 500 } ) ;
44- }
44+ const size = poster_sizes . includes ( 'w154' ) ? 'w154' : '' ;
4545
46- const config : TMDBConfigurationResponse = await configRes . json ( ) ;
47- const base = config . images . secure_base_url ;
48- const size = config . images . poster_sizes . includes ( 'w154' ) ? 'w154' : '' ;
46+ const enrichedResults = enrichWithPosterUrl < TMDBMovie > ( data . results , base , size ) ;
4947
50- const enrichedResults = data . results . map ( ( movie ) => ( {
51- ...movie ,
52- poster_url : {
53- default : movie . poster_path ? `${ base } ${ size } ${ movie . poster_path } ` : null ,
54- } ,
55- } ) ) ;
56-
57- return NextResponse . json ( { ...data , results : enrichedResults } , { status : 200 } ) ;
48+ return NextResponse . json ( { ...data , results : enrichedResults } , { status : 200 } ) ;
49+ } catch ( e : unknown ) {
50+ const error = e instanceof ApiError ? e . message : 'unable to get movies' ;
51+ const status = e instanceof ApiError ? e . status : 500 ;
52+ return NextResponse . json ( { error } , { status } ) ;
53+ }
5854}
0 commit comments