mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 01:35:39 -04:00
- Add `openapi-fetch` dependency; generate `lib/tmdb/schema.d.ts` from TMDB's OpenAPI spec and delete `lib/tmdb/types.ts` - Rewrite `lib/tmdb/client.ts` to use the typed fetch client against the generated schema, exporting `TmdbMovieDetails`, `TmdbTvDetails`, `TmdbVideo`, and `TmdbGenre` directly - Fix null-safety across services (`credits`, `availability`, `metadata`, `person`, `webhooks`) and call sites (explore page, search route, explore actions) to handle optional fields produced by the stricter generated types - Update `metadata.ts` and `metadata.test.ts` to import shared types from `@/lib/tmdb/client` instead of the removed `types.ts` - Exclude `lib/tmdb/schema.d.ts` from Biome linting
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
"use server";
|
|
|
|
import { requireSession } from "@/lib/auth/session";
|
|
import { discover } from "@/lib/tmdb/client";
|
|
import { tmdbImageUrl } from "@/lib/tmdb/image";
|
|
|
|
export async function discoverByGenre(
|
|
mediaType: "movie" | "tv",
|
|
genreId: number,
|
|
) {
|
|
await requireSession();
|
|
const results = await discover(mediaType, {
|
|
sort_by: "popularity.desc",
|
|
"vote_count.gte": "50",
|
|
with_genres: String(genreId),
|
|
});
|
|
// Discover may return movie (title, release_date) or TV (name, first_air_date)
|
|
// fields depending on mediaType. The schema types them separately, so widen.
|
|
type DiscoverResult = NonNullable<typeof results.results>[number] & {
|
|
title?: string;
|
|
name?: string;
|
|
release_date?: string;
|
|
first_air_date?: string;
|
|
};
|
|
return ((results.results ?? []) as DiscoverResult[])
|
|
.filter((r) => r.poster_path)
|
|
.map((r) => ({
|
|
tmdbId: r.id,
|
|
type: mediaType,
|
|
title: r.title ?? r.name ?? "",
|
|
posterPath: tmdbImageUrl(r.poster_path ?? null, "posters"),
|
|
releaseDate: r.release_date ?? r.first_air_date ?? null,
|
|
voteAverage: r.vote_average,
|
|
}));
|
|
}
|