@@ -913,132 +913,144 @@ discoverRoutes.get<Record<string, unknown>, WatchlistResponse>(
913913) ;
914914
915915// TMDB list slider: return items from a TMDB list by id
916- discoverRoutes . get < { listId : string } > ( '/list/:listId' , async ( req , res , next ) => {
917- const listId = Number ( req . params . listId ) ;
918- if ( ! listId || Number . isNaN ( listId ) ) {
919- return next ( { status : 400 , message : 'Invalid list ID.' } ) ;
920- }
921-
922- // same helper as in /trending etc.
923- const tmdb = createTmdbWithRegionLanguage ( req . user ) ;
924- const language = ( req . query . language as string ) ?? req . locale ;
925- const page = req . query . page ? Number ( req . query . page ) || 1 : 1 ;
916+ discoverRoutes . get < { listId : string } > (
917+ '/list/:listId' ,
918+ async ( req , res , next ) => {
919+ const listId = Number ( req . params . listId ) ;
920+ if ( ! listId || Number . isNaN ( listId ) ) {
921+ return next ( { status : 400 , message : 'Invalid list ID.' } ) ;
922+ }
926923
927- try {
928- let data : { results : Array < any > } | null = null ;
924+ // same helper as in /trending etc.
925+ const tmdb = createTmdbWithRegionLanguage ( req . user ) ;
926+ const language = ( req . query . language as string ) ?? req . locale ;
927+ const page = req . query . page ? Number ( req . query . page ) || 1 : 1 ;
929928
930- // 1) v3: all items come without pagination
931929 try {
932- const v3 = await tmdb . getList ( { listId, language } ) ;
933- data = v3 ;
934- } catch {
935- data = null ;
936- }
937-
938- // 2) fallback to v4 if v3 is empty or failed
939- if ( ! data || ! Array . isArray ( data . results ) || data . results . length === 0 ) {
940- // use the existing Axios instance of the TMDB client (proxy/timeouts are preserved)
941- const axiosInstance : any = ( tmdb as any ) . axios ;
942- const v4Url = `https://api.themoviedb.org/4/list/${ listId } ` ;
930+ let data : { results : any [ ] } | null = null ;
943931
932+ // 1) v3: all items come without pagination
944933 try {
945- const resp = await axiosInstance . get ( v4Url , {
946- params : { page, language } ,
947- } ) ;
934+ const v3 = await tmdb . getList ( { listId, language } ) ;
935+ data = v3 ;
936+ } catch {
937+ data = null ;
938+ }
948939
949- const v4 = resp . data as {
950- page ?: number ;
951- total_pages ?: number ;
952- total_results ?: number ;
953- results ?: Array < { id : number ; media_type : string } > ;
954- } ;
940+ // 2) fallback to v4 if v3 is empty or failed
941+ if ( ! data || ! Array . isArray ( data . results ) || data . results . length === 0 ) {
942+ // use the existing Axios instance of the TMDB client (proxy/timeouts are preserved)
943+ const axiosInstance : any = ( tmdb as any ) . axios ;
944+ const v4Url = `https://api.themoviedb.org/4/list/${ listId } ` ;
945+
946+ try {
947+ const resp = await axiosInstance . get ( v4Url , {
948+ params : { page, language } ,
949+ } ) ;
950+
951+ const v4 = resp . data as {
952+ page ?: number ;
953+ total_pages ?: number ;
954+ total_results ?: number ;
955+ results ?: { id : number ; media_type : string } [ ] ;
956+ } ;
957+
958+ const media = await Media . getRelatedMedia (
959+ req . user ,
960+ ( v4 . results ?? [ ] ) . map ( ( r ) => r . id )
961+ ) ;
962+
963+ const mappedResults = ( v4 . results ?? [ ] ) . map ( ( r ) => {
964+ switch ( r . media_type ) {
965+ case 'movie' :
966+ return mapMovieResult (
967+ r as any ,
968+ media . find (
969+ ( m ) => m . tmdbId === r . id && m . mediaType === MediaType . MOVIE
970+ )
971+ ) ;
972+ case 'tv' :
973+ return mapTvResult (
974+ r as any ,
975+ media . find (
976+ ( m ) => m . tmdbId === r . id && m . mediaType === MediaType . TV
977+ )
978+ ) ;
979+ case 'person' :
980+ return mapPersonResult ( r as any ) ;
981+ default :
982+ return mapCollectionResult ( r as any ) ;
983+ }
984+ } ) ;
955985
986+ return res . status ( 200 ) . json ( {
987+ page : v4 . page ?? 1 ,
988+ totalPages : v4 . total_pages ?? 1 ,
989+ totalResults : mappedResults . length ,
990+ results : mappedResults ,
991+ } ) ;
992+ } catch {
993+ // if v4 also fails → continue to empty response below
994+ }
995+ }
996+
997+ // 3) return v3 data if available
998+ if ( data && Array . isArray ( data . results ) && data . results . length > 0 ) {
956999 const media = await Media . getRelatedMedia (
9571000 req . user ,
958- ( v4 . results ?? [ ] ) . map ( ( r ) => r . id )
1001+ data . results . map ( ( r ) => r . id )
9591002 ) ;
9601003
961- const mappedResults = ( v4 . results ?? [ ] ) . map ( ( r ) => {
962- switch ( r . media_type ) {
963- case 'movie' :
964- return mapMovieResult (
965- r as any ,
966- media . find ( ( m ) => m . tmdbId === r . id && m . mediaType === MediaType . MOVIE )
967- ) ;
968- case 'tv' :
969- return mapTvResult (
970- r as any ,
971- media . find ( ( m ) => m . tmdbId === r . id && m . mediaType === MediaType . TV )
972- ) ;
973- case 'person' :
974- return mapPersonResult ( r as any ) ;
975- default :
976- return mapCollectionResult ( r as any ) ;
977- }
978- } ) ;
1004+ const mappedResults = data . results . map ( ( result ) =>
1005+ isMovie ( result )
1006+ ? mapMovieResult (
1007+ result ,
1008+ media . find (
1009+ ( m ) =>
1010+ m . tmdbId === result . id && m . mediaType === MediaType . MOVIE
1011+ )
1012+ )
1013+ : isPerson ( result )
1014+ ? mapPersonResult ( result )
1015+ : isCollection ( result )
1016+ ? mapCollectionResult ( result )
1017+ : mapTvResult (
1018+ result ,
1019+ media . find (
1020+ ( m ) => m . tmdbId === result . id && m . mediaType === MediaType . TV
1021+ )
1022+ )
1023+ ) ;
9791024
9801025 return res . status ( 200 ) . json ( {
981- page : v4 . page ?? 1 ,
982- totalPages : v4 . total_pages ?? 1 ,
1026+ page : 1 ,
1027+ totalPages : 1 ,
9831028 totalResults : mappedResults . length ,
9841029 results : mappedResults ,
9851030 } ) ;
986- } catch {
987- // if v4 also fails → continue to empty response below
9881031 }
989- }
990-
991- // 3) return v3 data if available
992- if ( data && Array . isArray ( data . results ) && data . results . length > 0 ) {
993- const media = await Media . getRelatedMedia (
994- req . user ,
995- data . results . map ( ( r ) => r . id )
996- ) ;
997-
998- const mappedResults = data . results . map ( ( result ) =>
999- isMovie ( result )
1000- ? mapMovieResult (
1001- result ,
1002- media . find ( ( m ) => m . tmdbId === result . id && m . mediaType === MediaType . MOVIE )
1003- )
1004- : isPerson ( result )
1005- ? mapPersonResult ( result )
1006- : isCollection ( result )
1007- ? mapCollectionResult ( result )
1008- : mapTvResult (
1009- result ,
1010- media . find ( ( m ) => m . tmdbId === result . id && m . mediaType === MediaType . TV )
1011- )
1012- ) ;
10131032
1033+ // 4) both paths empty → return empty response
1034+ return res . status ( 200 ) . json ( {
1035+ page : 1 ,
1036+ totalPages : 1 ,
1037+ totalResults : 0 ,
1038+ results : [ ] ,
1039+ } ) ;
1040+ } catch ( err ) {
1041+ logger . debug ( 'TMDB list slider failed' , {
1042+ label : 'API' ,
1043+ errorMessage : ( err as Error ) . message ,
1044+ listId : req . params . listId ,
1045+ } ) ;
10141046 return res . status ( 200 ) . json ( {
10151047 page : 1 ,
10161048 totalPages : 1 ,
1017- totalResults : mappedResults . length ,
1018- results : mappedResults ,
1049+ totalResults : 0 ,
1050+ results : [ ] ,
10191051 } ) ;
10201052 }
1021-
1022- // 4) both paths empty → return empty response
1023- return res . status ( 200 ) . json ( {
1024- page : 1 ,
1025- totalPages : 1 ,
1026- totalResults : 0 ,
1027- results : [ ] ,
1028- } ) ;
1029- } catch ( err ) {
1030- logger . debug ( 'TMDB list slider failed' , {
1031- label : 'API' ,
1032- errorMessage : ( err as Error ) . message ,
1033- listId : req . params . listId ,
1034- } ) ;
1035- return res . status ( 200 ) . json ( {
1036- page : 1 ,
1037- totalPages : 1 ,
1038- totalResults : 0 ,
1039- results : [ ] ,
1040- } ) ;
10411053 }
1042- } ) ;
1054+ ) ;
10431055
10441056export default discoverRoutes ;
0 commit comments