tmdb-kit 0.1.0-beta.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["#apiKey","#accessToken","#baseUrl","#fetch","#headers","#createUrl","#createHeaders","#resolveFetch","#transport","#transport","#transport","#transform","#transport","#transport","#transport","#transport","#transport","#transport"],"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/configuration.ts","../src/resources/genres.ts","../src/resources/images.ts","../src/resources/movies.ts","../src/resources/people.ts","../src/resources/search.ts","../src/resources/trending.ts","../src/resources/tv.ts","../src/client.ts","../src/search-guards.ts","../src/types.ts"],"sourcesContent":["import type { JsonValue } from './types'\n\n/** Raw TMDB error response body structure. */\nexport interface TMDBErrorResponseBody {\n success?: boolean\n status_code?: number\n status_message?: string\n}\n\n/** Options for constructing a {@link TMDBResponseError} or its subclasses. */\nexport interface TMDBResponseErrorOptions {\n body: JsonValue | undefined\n headers: Headers\n status: number\n statusText: string\n url: string\n}\n\n/** Base class for all SDK-originated errors. */\nexport class TMDBError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBError'\n }\n}\n\n/** Thrown before a request is sent or when fetch itself rejects. */\nexport class TMDBRequestError extends TMDBError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBRequestError'\n }\n}\n\n/** Thrown when TMDB returns a non-2xx response. */\nexport class TMDBResponseError extends TMDBError {\n readonly body: JsonValue | undefined\n readonly headers: Headers\n readonly requestId: string | null\n readonly status: number\n readonly statusCode: number | undefined\n readonly statusMessage: string | undefined\n readonly statusText: string\n readonly url: string\n\n constructor(message: string, options: TMDBResponseErrorOptions) {\n super(message)\n this.name = 'TMDBResponseError'\n this.body = options.body\n this.headers = options.headers\n this.requestId = options.headers.get('x-request-id')\n this.status = options.status\n this.statusText = options.statusText\n this.url = options.url\n\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n this.statusCode = body?.status_code\n this.statusMessage = body?.status_message\n }\n\n /** True when TMDB has asked the caller to back off (HTTP 429). */\n get isRateLimit(): boolean {\n return this.status === 429\n }\n\n /** True when the resource was not found (HTTP 404). */\n get isNotFound(): boolean {\n return this.status === 404\n }\n\n /** True when the request was rejected as unauthenticated (HTTP 401). */\n get isUnauthorized(): boolean {\n return this.status === 401\n }\n\n /** True when the request was rejected as forbidden (HTTP 403). */\n get isForbidden(): boolean {\n return this.status === 403\n }\n\n /** True when the upstream returned a 5xx server error. */\n get isServerError(): boolean {\n return this.status >= 500 && this.status < 600\n }\n}\n\nexport interface TMDBRateLimitErrorOptions extends TMDBResponseErrorOptions {\n /** Seconds to wait before retrying. Parsed from the `Retry-After` header. */\n retryAfter: number\n}\n\n/**\n * Thrown when TMDB returns HTTP 429.\n *\n * The SDK does NOT retry automatically — that decision is left to the\n * caller, since retry policies vary widely. Inspect `retryAfter` to\n * implement your own backoff.\n */\nexport class TMDBRateLimitError extends TMDBResponseError {\n readonly retryAfter: number\n\n constructor(message: string, options: TMDBRateLimitErrorOptions) {\n super(message, options)\n this.name = 'TMDBRateLimitError'\n this.retryAfter = options.retryAfter\n }\n}\n\n/**\n * Create the appropriate error instance for a non-2xx TMDB response.\n *\n * Returns a {@link TMDBRateLimitError} when the status is 429, otherwise\n * a generic {@link TMDBResponseError}. The error message is extracted from\n * the TMDB `status_message` field when available.\n */\nexport function createResponseError(\n options: TMDBResponseErrorOptions,\n): TMDBResponseError {\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n const message = body?.status_message ?? `${options.status} ${options.statusText}`.trim()\n\n if (options.status === 429) {\n return new TMDBRateLimitError(message, {\n ...options,\n retryAfter: parseRetryAfter(options.headers.get('retry-after')),\n })\n }\n\n return new TMDBResponseError(message, options)\n}\n\n/**\n * Parse the `Retry-After` header into seconds. Accepts both delta-seconds\n * (e.g. \"5\") and HTTP-date forms (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\").\n * Falls back to 1 second when the header is missing or unparseable.\n */\nexport function parseRetryAfter(value: string | null | undefined): number {\n if (value === null || value === undefined) {\n return 1\n }\n\n const trimmed = value.trim()\n if (trimmed === '') {\n return 1\n }\n\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return seconds\n }\n\n const date = Date.parse(trimmed)\n if (Number.isFinite(date)) {\n const deltaMs = date - Date.now()\n return Math.max(1, Math.ceil(deltaMs / 1000))\n }\n\n return 1\n}\n\n/** Check if a value has the shape of a TMDB error response body. */\nfunction isErrorResponseBody(value: unknown): value is TMDBErrorResponseBody {\n return typeof value === 'object' && value !== null\n}\n","import { TMDBRequestError } from './errors'\nimport type { ImageSize, RegionCode, LanguageCode, TrendingTimeWindow } from './types'\n\n/** Primitives allowed as query parameter values. */\nexport type QueryPrimitive = string | number | boolean\n\n/** A single query parameter value: primitive, array, or nullish. */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[] | null | undefined\n\n/** Key-value map of query parameters for API requests. */\nexport type QueryParams = Record<string, QueryValue>\n\n/** Default query parameters inherited from the client configuration. */\nexport interface QueryDefaults {\n language?: LanguageCode\n region?: RegionCode\n}\n\nexport const DEFAULT_API_BASE_URL = 'https://api.themoviedb.org/3'\nexport const DEFAULT_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p'\n\n/**\n * Append query parameters to a URL object.\n *\n * - `undefined` and `null` values are skipped.\n * - Arrays are joined with commas (TMDB convention).\n * - All values are converted to strings.\n */\nexport function appendQuery(url: URL, query: QueryParams): void {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','))\n continue\n }\n\n url.searchParams.set(key, String(value))\n }\n}\n\n/**\n * Merge a language query parameter with client defaults.\n *\n * If `query.language` is set it takes precedence; otherwise the client's\n * default language is used.\n */\nexport function withLanguage(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const language = typeof query.language === 'string' ? query.language : defaults.language\n\n return {\n ...query,\n language,\n }\n}\n\n/**\n * Merge language and region defaults for list endpoints.\n *\n * Combines {@link withLanguage} with region fallback from client defaults.\n */\nexport function withListDefaults(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const region = typeof query.region === 'string' ? query.region : defaults.region\n\n return {\n ...withLanguage(defaults, query),\n region,\n }\n}\n\n/**\n * Convert a string or string array to a comma-separated list.\n *\n * Returns `undefined` if the input is `undefined` (skips the parameter).\n * TMDB uses comma-separated values for multi-value query parameters.\n */\nexport function toCommaList(value: string | readonly string[] | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'string' ? value : value.join(',')\n}\n\n/**\n * Validate and convert a numeric ID to a string for use in URL paths.\n *\n * @throws {TMDBRequestError} If `value` is not a positive integer.\n */\nexport function toId(value: number, name: string): string {\n if (!Number.isInteger(value) || value <= 0) {\n throw new TMDBRequestError(`${name} must be a positive integer`)\n }\n\n return String(value)\n}\n\n/**\n * Validate and trim a search query string.\n *\n * @throws {TMDBRequestError} If the query is empty after trimming.\n */\nexport function toSearchQuery(value: string): string {\n const query = value.trim()\n\n if (query.length === 0) {\n throw new TMDBRequestError('search query must not be empty')\n }\n\n return query\n}\n\n/**\n * Validate a trending time window value.\n *\n * @throws {TMDBRequestError} If `value` is not `\"day\"` or `\"week\"`.\n */\nexport function toTimeWindow(value: TrendingTimeWindow): TrendingTimeWindow {\n if (value !== 'day' && value !== 'week') {\n throw new TMDBRequestError('timeWindow must be either \"day\" or \"week\"')\n }\n\n return value\n}\n\nexport interface BuildImageUrlOptions {\n baseUrl?: string\n /**\n * Transform the resolved TMDB image URL before returning it. Use this to\n * route requests through a CDN, image proxy, or to add signatures.\n */\n transform?: (url: string) => string\n}\n\n/**\n * Build a full TMDB image URL from the path returned by API payloads.\n * Returns null for nullish image paths so UI code can branch naturally.\n */\nexport function buildImageUrl(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: BuildImageUrlOptions = {},\n): string | null {\n if (path === undefined || path === null || path.trim() === '') {\n return null\n }\n\n const baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_IMAGE_BASE_URL)\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const url = `${baseUrl}/${size}${normalizedPath}`\n\n return options.transform ? options.transform(url) : url\n}\n\n/**\n * Strip trailing slashes from a base URL to ensure consistent path joining.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n","import { createResponseError, TMDBRequestError } from './errors'\nimport {\n appendQuery,\n DEFAULT_API_BASE_URL,\n DEFAULT_IMAGE_BASE_URL,\n normalizeBaseUrl,\n type QueryDefaults,\n type QueryParams,\n} from './query'\nimport type { ImageUrlTransform } from './resources/images'\nimport type { JsonValue, LanguageCode, RegionCode } from './types'\n\nexport type { ImageUrlTransform }\n\n/**\n * A minimal fetch-like function signature. Any runtime's native `fetch`\n * or a test double conforming to this shape can be used.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface TMDBAccessTokenAuth {\n /** TMDB API Read Access Token. Sent as an Authorization Bearer header. */\n accessToken: string\n apiKey?: never\n}\n\nexport interface TMDBApiKeyAuth {\n /** Legacy v3 API key. Sent as api_key query parameter. */\n apiKey: string\n accessToken?: never\n}\n\nexport type TMDBAuth = TMDBAccessTokenAuth | TMDBApiKeyAuth\n\n/** Internal defaults resolved during client construction. */\nexport interface TMDBClientDefaults extends QueryDefaults {\n imageBaseUrl: string\n}\n\nexport interface TMDBImagesOptions {\n /**\n * Default transform applied to every URL produced by the ImagesHelper.\n * Use this to route TMDB image requests through a CDN, image proxy, or\n * to add signed query parameters. Individual calls can still override it\n * via ImagesHelper.url(path, size, { transform }).\n */\n transform?: ImageUrlTransform\n}\n\nexport type TMDBClientOptions = TMDBAuth & {\n /** Defaults to https://api.themoviedb.org/3. Useful for tests or proxies. */\n baseUrl?: string\n /** Inject a fetch implementation for tests, custom runtimes, or instrumentation. */\n fetch?: FetchLike\n /** Default language for endpoints that accept a language query parameter. */\n defaultLanguage?: LanguageCode\n /** Default region for movie list/search endpoints that accept a region query parameter. */\n defaultRegion?: RegionCode\n /** Custom image host. Defaults to https://image.tmdb.org/t/p. */\n imageBaseUrl?: string\n /** Image-helper configuration: host overrides and URL transforms. */\n images?: TMDBImagesOptions\n /** Additional headers merged into every request before authentication is applied. */\n headers?: HeadersInit\n}\n\n/** Per-request overrides applied when making a single API call. */\nexport interface TMDBRequestOptions {\n headers?: HeadersInit\n query?: QueryParams\n signal?: AbortSignal\n}\n\n/**\n * Transport abstraction for making HTTP requests to the TMDB API.\n *\n * The built-in {@link TMDBHttpClient} implements this interface. You can\n * provide a custom implementation via {@link TMDBFactoryOptions.transport}\n * for testing, caching, or instrumentation.\n */\nexport interface TMDBTransport {\n readonly defaults: TMDBClientDefaults\n get<T>(path: string, options?: TMDBRequestOptions): Promise<T>\n}\n\n/**\n * Built-in HTTP transport that uses the Fetch API.\n *\n * Handles authentication (API key or access token), URL construction,\n * request headers, and response parsing. Use the factory function\n * {@link createTMDB} instead of instantiating this directly.\n */\nexport class TMDBHttpClient implements TMDBTransport {\n readonly defaults: TMDBClientDefaults\n readonly imageTransform: ImageUrlTransform | undefined\n\n readonly #apiKey: string | undefined\n readonly #accessToken: string | undefined\n readonly #baseUrl: string\n readonly #fetch: FetchLike | undefined\n readonly #headers: HeadersInit | undefined\n\n constructor(options: TMDBClientOptions) {\n const accessToken = normalizeSecret('accessToken' in options ? options.accessToken : undefined)\n const apiKey = normalizeSecret('apiKey' in options ? options.apiKey : undefined)\n\n if (Boolean(accessToken) === Boolean(apiKey)) {\n throw new TMDBRequestError('Provide exactly one of accessToken or apiKey')\n }\n\n this.#accessToken = accessToken\n this.#apiKey = apiKey\n this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_API_BASE_URL)\n this.#fetch = options.fetch\n this.#headers = options.headers\n this.defaults = {\n imageBaseUrl: normalizeBaseUrl(options.imageBaseUrl ?? DEFAULT_IMAGE_BASE_URL),\n language: options.defaultLanguage,\n region: options.defaultRegion,\n }\n this.imageTransform = options.images?.transform\n }\n\n async get<T>(path: string, options: TMDBRequestOptions = {}): Promise<T> {\n const url = this.#createUrl(path, options.query ?? {})\n const headers = this.#createHeaders(options.headers)\n const fetchImpl = this.#resolveFetch()\n\n let response: Response\n\n try {\n response = await fetchImpl(url, {\n headers,\n method: 'GET',\n signal: options.signal,\n })\n } catch (error) {\n throw new TMDBRequestError(`TMDB request failed: ${String(error)}`, { cause: error })\n }\n\n const body = await readJson(response)\n\n if (!response.ok) {\n throw createResponseError({\n body,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n url,\n })\n }\n\n return body as T\n }\n\n #resolveFetch(): FetchLike {\n if (this.#fetch !== undefined) {\n return this.#fetch\n }\n\n const globalFetch = globalThis.fetch\n\n if (typeof globalFetch !== 'function') {\n throw new TMDBRequestError('No fetch implementation found. Pass options.fetch in this runtime.')\n }\n\n return globalFetch.bind(globalThis)\n }\n\n #createHeaders(headersInit: HeadersInit | undefined): Headers {\n const headers = new Headers(this.#headers)\n const requestHeaders = new Headers(headersInit)\n\n headers.set('Accept', 'application/json')\n\n for (const [key, value] of requestHeaders) {\n headers.set(key, value)\n }\n\n if (this.#accessToken !== undefined) {\n headers.set('Authorization', `Bearer ${this.#accessToken}`)\n }\n\n return headers\n }\n\n #createUrl(path: string, query: QueryParams): string {\n const relativePath = path.replace(/^\\/+/, '')\n const url = new URL(relativePath, `${this.#baseUrl}/`)\n\n appendQuery(url, {\n ...query,\n api_key: this.#apiKey,\n })\n\n return url.toString()\n }\n}\n\n/**\n * Read and parse a JSON response body.\n *\n * Returns `undefined` for empty responses. If the body is not valid JSON,\n * the raw text string is returned as-is (TMDB occasionally returns plain\n * text for certain error conditions).\n */\nasync function readJson(response: Response): Promise<JsonValue | undefined> {\n const text = await response.text()\n\n if (text.length === 0) {\n return undefined\n }\n\n try {\n return JSON.parse(text) as JsonValue\n } catch {\n return text\n }\n}\n\n/**\n * Normalize a secret value by trimming whitespace and treating empty\n * strings as undefined (not provided).\n */\nfunction normalizeSecret(value: string | undefined): string | undefined {\n const secret = value?.trim()\n return secret === '' ? undefined : secret\n}\n","import type { TMDBTransport } from '../http'\nimport type { Configuration, Country, JobDepartment, Language, Timezone } from '../types'\n\n/**\n * Access TMDB configuration data (image sizes, countries, languages, etc.).\n *\n * Obtained via `client.configuration`.\n */\nexport class ConfigurationResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n details(): Promise<Configuration> {\n return this.#transport.get('/configuration')\n }\n\n countries(): Promise<Country[]> {\n return this.#transport.get('/configuration/countries')\n }\n\n jobs(): Promise<JobDepartment[]> {\n return this.#transport.get('/configuration/jobs')\n }\n\n languages(): Promise<Language[]> {\n return this.#transport.get('/configuration/languages')\n }\n\n primaryTranslations(): Promise<string[]> {\n return this.#transport.get('/configuration/primary_translations')\n }\n\n timezones(): Promise<Timezone[]> {\n return this.#transport.get('/configuration/timezones')\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { withLanguage } from '../query'\nimport type { GenresResponse, LanguageOptions } from '../types'\n\n/**\n * Access TMDB genre lists for movies and TV shows.\n *\n * Obtained via `client.genres`.\n */\nexport class GenresResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/movie/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/tv/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { buildImageUrl } from '../query'\nimport type { ImageSize } from '../types'\n\n/** Function that transforms a TMDB image URL (e.g. for CDN proxying). */\nexport type ImageUrlTransform = (url: string) => string\n\n/**\n * Helper for constructing TMDB image URLs from API path values.\n *\n * Obtained via `client.images`. Supports optional URL transforms for\n * routing image requests through a CDN or proxy.\n */\nexport class ImagesHelper {\n readonly #transport: TMDBTransport\n readonly #transform: ImageUrlTransform | undefined\n\n constructor(transport: TMDBTransport, transform?: ImageUrlTransform) {\n this.#transport = transport\n this.#transform = transform\n }\n\n url(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: { transform?: ImageUrlTransform } = {},\n ): string | null {\n return buildImageUrl(path, size, {\n baseUrl: this.#transport.defaults.imageBaseUrl,\n transform: options.transform ?? this.#transform,\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n ListOptions,\n MovieDetails,\n MovieDetailsOptions,\n MovieSummary,\n PagedResponse,\n TMDBObject,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB movie endpoints (popular, top-rated, details, credits, etc.).\n *\n * Obtained via `client.movies`.\n */\nexport class MoviesResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/popular', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n topRated(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/top_rated', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n nowPlaying(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/now_playing', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n upcoming(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/upcoming', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n movieId: number,\n options: MovieDetailsOptions = {},\n ): Promise<MovieDetails & TAppend> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(movieId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/recommendations`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n similar(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/similar`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n videos(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<VideosResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for movie list endpoints. */\nfunction movieListQuery(transport: TMDBTransport, options: ListOptions): QueryParams {\n return withListDefaults(transport.defaults, {\n language: options.language,\n page: options.page,\n region: options.region,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toId, withLanguage, type QueryParams } from '../query'\nimport type { LanguageOptions, ListOptions, PagedResponse, PersonDetails, PersonSummary } from '../types'\n\n/**\n * Access TMDB person (actor, director, etc.) endpoints.\n *\n * Obtained via `client.people`.\n */\nexport class PeopleResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<PersonSummary>> {\n return this.#transport.get('/person/popular', {\n query: peopleListQuery(this.#transport, options),\n })\n }\n\n details(personId: number, options: LanguageOptions = {}): Promise<PersonDetails> {\n return this.#transport.get(`/person/${toId(personId, 'personId')}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for person list endpoints. */\nfunction peopleListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toSearchQuery, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n MovieSearchOptions,\n MovieSearchResult,\n MultiSearchOptions,\n PagedResponse,\n PersonSearchResult,\n SearchMultiResult,\n TVSearchOptions,\n TVSearchResult,\n} from '../types'\n\n/**\n * Search TMDB for movies, TV shows, people, or all media types.\n *\n * Obtained via `client.search`.\n */\nexport class SearchResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(query: string, options: MovieSearchOptions = {}): Promise<PagedResponse<MovieSearchResult>> {\n return this.#transport.get('/search/movie', {\n query: movieSearchQuery(this.#transport, query, options),\n })\n }\n\n tv(query: string, options: TVSearchOptions = {}): Promise<PagedResponse<TVSearchResult>> {\n return this.#transport.get('/search/tv', {\n query: tvSearchQuery(this.#transport, query, options),\n })\n }\n\n people(query: string, options: MultiSearchOptions = {}): Promise<PagedResponse<PersonSearchResult>> {\n return this.#transport.get('/search/person', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n }\n\n async multi(\n query: string,\n options: MultiSearchOptions = {},\n ): Promise<PagedResponse<SearchMultiResult>> {\n const response = await this.#transport.get<PagedResponse<SearchMultiResult>>('/search/multi', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n\n const excluded = options.exclude\n if (excluded === undefined || excluded.length === 0) {\n return response\n }\n\n const excludedSet = new Set<string>(excluded)\n return {\n ...response,\n results: response.results.filter((result) => !excludedSet.has(result.media_type)),\n }\n }\n}\n\n/** Build query parameters for movie search. */\nfunction movieSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MovieSearchOptions,\n): QueryParams {\n return withListDefaults(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n primary_release_year: options.primaryReleaseYear,\n query: toSearchQuery(query),\n region: options.region,\n year: options.year,\n })\n}\n\n/** Build query parameters for TV search. */\nfunction tvSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: TVSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n first_air_date_year: options.firstAirDateYear,\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n year: options.year,\n })\n}\n\n/** Build query parameters for person and multi-search. */\nfunction commonSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MultiSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toTimeWindow, withLanguage } from '../query'\nimport type {\n LanguageOptions,\n MovieSummary,\n PagedResponse,\n PersonSummary,\n TrendingResult,\n TrendingTimeWindow,\n TVSummary,\n} from '../types'\n\n/**\n * Access TMDB trending content (movies, TV, people) for day/week windows.\n *\n * Obtained via `client.trending`.\n */\nexport class TrendingResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n all(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TrendingResult>> {\n return this.#transport.get(`/trending/all/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n movies(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<MovieSummary & { media_type?: 'movie' }>> {\n return this.#transport.get(`/trending/movie/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TVSummary & { media_type?: 'tv' }>> {\n return this.#transport.get(`/trending/tv/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n people(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<PersonSummary & { media_type?: 'person' }>> {\n return this.#transport.get(`/trending/person/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n LanguageOptions,\n ListOptions,\n PagedResponse,\n TMDBObject,\n TVDetails,\n TVDetailsOptions,\n TVSeasonDetails,\n TVSeasonDetailsOptions,\n TVSummary,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB TV show endpoints (popular, top-rated, details, seasons, etc.).\n *\n * Obtained via `client.tv`.\n */\nexport class TVResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/popular', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n topRated(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/top_rated', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n airingToday(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/airing_today', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n onTheAir(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/on_the_air', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n options: TVDetailsOptions = {},\n ): Promise<TVDetails & TAppend> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(seriesId: number, options: LanguageOptions = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(seriesId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/recommendations`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n similar(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/similar`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n videos(seriesId: number, options: LanguageOptions = {}): Promise<VideosResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n seasonDetails<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n seasonNumber: number,\n options: TVSeasonDetailsOptions = {},\n ): Promise<TVSeasonDetails & TAppend> {\n return this.#transport.get(\n `/tv/${toId(seriesId, 'seriesId')}/season/${toId(seasonNumber, 'seasonNumber')}`,\n {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n },\n )\n }\n}\n\n/** Build query parameters for TV list endpoints. */\nfunction tvListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import { TMDBHttpClient, type TMDBClientOptions, type TMDBRequestOptions, type TMDBTransport } from './http'\nimport { ConfigurationResource } from './resources/configuration'\nimport { GenresResource } from './resources/genres'\nimport { ImagesHelper } from './resources/images'\nimport { MoviesResource } from './resources/movies'\nimport { PeopleResource } from './resources/people'\nimport { SearchResource } from './resources/search'\nimport { TrendingResource } from './resources/trending'\nimport { TVResource } from './resources/tv'\n\n/**\n * Options accepted by {@link createTMDB} and the {@link TMDBClient} constructor.\n *\n * Extends {@link TMDBClientOptions} with an optional {@link TMDBTransport} so\n * callers can plug in a custom transport (typically for tests, caching, or\n * instrumentation) without having to mock `fetch` or the factory itself.\n */\nexport type TMDBFactoryOptions = TMDBClientOptions & {\n transport?: TMDBTransport\n}\n\n/**\n * Main SDK entry point.\n *\n * Resource properties are intentionally small and explicit. The SDK focuses on\n * common TMDB workflows first, while request<T>() keeps uncommon endpoints easy\n * to call without waiting for a generated surface area.\n */\nexport class TMDBClient {\n readonly configuration: ConfigurationResource\n readonly genres: GenresResource\n readonly images: ImagesHelper\n readonly movies: MoviesResource\n readonly people: PeopleResource\n readonly search: SearchResource\n readonly trending: TrendingResource\n readonly tv: TVResource\n\n readonly #transport: TMDBTransport\n\n constructor(options: TMDBFactoryOptions) {\n const { transport, images, ...httpOptions } = options\n // When the caller supplies a custom transport we still want to honor the\n // global images.transform option; otherwise read it back from the HTTP\n // client after it has been constructed.\n const fallbackTransform = images?.transform\n const builtInClient = transport === undefined ? new TMDBHttpClient({ ...httpOptions, images }) : undefined\n this.#transport = builtInClient ?? (transport as TMDBTransport)\n\n this.configuration = new ConfigurationResource(this.#transport)\n this.genres = new GenresResource(this.#transport)\n this.images = new ImagesHelper(\n this.#transport,\n builtInClient ? builtInClient.imageTransform : fallbackTransform,\n )\n this.movies = new MoviesResource(this.#transport)\n this.people = new PeopleResource(this.#transport)\n this.search = new SearchResource(this.#transport)\n this.trending = new TrendingResource(this.#transport)\n this.tv = new TVResource(this.#transport)\n }\n\n /**\n * Make a raw GET request to any TMDB endpoint.\n *\n * This is an escape hatch for endpoints not covered by the typed resource\n * helpers. The `path` should be relative to the API base URL (e.g.\n * `/movie/{id}/credits`). Response is parsed as JSON and cast to `T`.\n *\n * @param path - API path relative to the base URL (e.g. `/movie/123`)\n * @param options - Optional request-level overrides (headers, query, signal)\n * @returns Parsed JSON response typed as `T`\n */\n request<T>(path: string, options?: TMDBRequestOptions): Promise<T> {\n return this.#transport.get<T>(path, options)\n }\n}\n\n/**\n * Create a new {@link TMDBClient} instance.\n *\n * @example\n * ```ts\n * const tmdb = createTMDB({ accessToken: 'YOUR_TOKEN' })\n * const { results } = await tmdb.search.movies('Inception')\n * ```\n *\n * @param options - Authentication and configuration options\n * @returns A configured TMDBClient ready to make API calls\n */\nexport function createTMDB(options: TMDBFactoryOptions): TMDBClient {\n return new TMDBClient(options)\n}\n","import type {\n MovieMultiResult,\n MovieSearchResult,\n PersonMultiResult,\n PersonSearchResult,\n SearchMultiResult,\n TVMultiResult,\n TVSearchResult,\n} from './types'\n\n/**\n * Type guard that narrows a `search.multi()` result to a movie entry.\n *\n * The `media_type` field is required on every `/search/multi` payload by\n * TMDB, so this check is safe at runtime and produces a strictly typed\n * MovieSummary on the narrowed branch.\n */\nexport function isMovieSearchResult(\n result: SearchMultiResult,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a `search.multi()` result to a TV entry. */\nexport function isTVSearchResult(\n result: SearchMultiResult,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a `search.multi()` result to a person entry. */\nexport function isPersonSearchResult(\n result: SearchMultiResult,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/**\n * Convenience alias: `isMovieSearchResult` works on a `search.movies()`\n * result (which already has the narrow type but is also tagged with\n * `media_type?: 'movie'`), as well as on multi-search results.\n */\nexport function isMovie(result: MovieSearchResult | SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a search result to a TV entry. */\nexport function isTV(\n result: TVSearchResult | SearchMultiResult): result is TVMultiResult\nexport function isTV(result: SearchMultiResult): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a search result to a person entry. */\nexport function isPerson(\n result: PersonSearchResult | SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/** Internal helper: check if a value is an object with a matching `media_type` field. */\nfunction isObjectWithMediaType(\n value: unknown,\n mediaType: 'movie' | 'tv' | 'person',\n): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'media_type' in value &&\n (value as { media_type: unknown }).media_type === mediaType\n )\n}\n","/** Primitive JSON values returned by TMDB. */\nexport type JsonPrimitive = string | number | boolean | null\n\n/** JSON object/array tree returned by TMDB for fields this SDK does not model yet. */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[]\n\nexport interface JsonObject {\n [key: string]: JsonValue | undefined\n}\n\n/** Escape hatch for append_to_response payloads and future TMDB fields. */\nexport type TMDBObject = Record<string, unknown>\n\n/** Date string in TMDB format (typically `YYYY-MM-DD`). */\nexport type TMDBDateString = string\n\n/** ISO 639-1 language code (e.g. `\"en\"`, `\"zh\"`). */\nexport type LanguageCode = string\n\n/** ISO 3166-1 country/region code (e.g. `\"US\"`, `\"CN\"`). */\nexport type RegionCode = string\n\n/** Supported media types for multi-search results. */\nexport type MediaType = 'movie' | 'tv' | 'person'\n\n/** Time window for trending endpoints: `\"day\"` or `\"week\"`. */\nexport type TrendingTimeWindow = 'day' | 'week'\n\nexport interface PagedResponse<T> {\n page: number\n results: T[]\n total_pages: number\n total_results: number\n}\n\nexport interface Genre {\n id: number\n name: string\n}\n\nexport interface ProductionCompany {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface ProductionCountry {\n iso_3166_1: string\n name: string\n}\n\nexport interface SpokenLanguage {\n english_name: string\n iso_639_1: string\n name: string\n}\n\nexport interface CollectionSummary {\n id: number\n name: string\n poster_path: string | null\n backdrop_path: string | null\n}\n\nexport interface MovieSummary {\n adult: boolean\n backdrop_path: string | null\n genre_ids: number[]\n id: number\n original_language: string\n original_title: string\n overview: string\n popularity: number\n poster_path: string | null\n release_date: TMDBDateString\n title: string\n video: boolean\n vote_average: number\n vote_count: number\n}\n\nexport interface MovieDetails extends Omit<MovieSummary, 'genre_ids'> {\n belongs_to_collection: CollectionSummary | null\n budget: number\n genres: Genre[]\n homepage: string | null\n imdb_id: string | null\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n revenue: number\n runtime: number | null\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n}\n\nexport interface TVSummary {\n adult?: boolean\n backdrop_path: string | null\n first_air_date: TMDBDateString\n genre_ids: number[]\n id: number\n name: string\n origin_country: string[]\n original_language: string\n original_name: string\n overview: string\n popularity: number\n poster_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface CreatedBy {\n id: number\n credit_id: string\n name: string\n gender: number\n profile_path: string | null\n}\n\nexport interface Network {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface SeasonSummary {\n air_date: TMDBDateString | null\n episode_count: number\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport interface EpisodeGuestStar {\n adult: boolean\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface EpisodeSummary {\n air_date: TMDBDateString | null\n crew: CreditCrewMember[]\n episode_number: number\n episode_type: string\n guest_stars: EpisodeGuestStar[]\n id: number\n name: string\n overview: string\n production_code: string | null\n runtime: number | null\n season_number: number\n show_id: number\n still_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface TVSeasonDetails {\n _id: string\n air_date: TMDBDateString | null\n episodes: EpisodeSummary[]\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport type TVSeasonAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'translations'\n | 'videos'\n | (string & {})\n\nexport interface TVSeasonDetailsOptions extends LanguageOptions {\n appendToResponse?: TVSeasonAppendToResponse | readonly TVSeasonAppendToResponse[]\n}\n\nexport interface TVDetails extends Omit<TVSummary, 'genre_ids'> {\n created_by: CreatedBy[]\n episode_run_time: number[]\n genres: Genre[]\n homepage: string | null\n in_production: boolean\n languages: string[]\n last_air_date: TMDBDateString | null\n networks: Network[]\n number_of_episodes: number\n number_of_seasons: number\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n seasons: SeasonSummary[]\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n type: string\n}\n\nexport interface PersonKnownForMovie extends MovieSummary {\n media_type: 'movie'\n}\n\nexport interface PersonKnownForTV extends TVSummary {\n media_type: 'tv'\n}\n\nexport type PersonKnownFor = PersonKnownForMovie | PersonKnownForTV\n\nexport interface PersonSummary {\n adult: boolean\n gender: number\n id: number\n known_for: PersonKnownFor[]\n known_for_department: string\n name: string\n original_name?: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface PersonDetails extends Omit<PersonSummary, 'known_for'> {\n also_known_as: string[]\n biography: string\n birthday: TMDBDateString | null\n deathday: TMDBDateString | null\n homepage: string | null\n imdb_id: string | null\n place_of_birth: string | null\n}\n\nexport interface MovieSearchResult extends MovieSummary {\n media_type?: 'movie'\n}\n\nexport interface TVSearchResult extends TVSummary {\n media_type?: 'tv'\n}\n\nexport interface PersonSearchResult extends PersonSummary {\n media_type?: 'person'\n}\n\nexport type SearchMultiResult =\n | (MovieSummary & { media_type: 'movie' })\n | (TVSummary & { media_type: 'tv' })\n | (PersonSummary & { media_type: 'person' })\n\n/** A single multi-search result narrowed to a specific media type. */\nexport type MovieMultiResult = MovieSummary & { media_type: 'movie' }\nexport type TVMultiResult = TVSummary & { media_type: 'tv' }\nexport type PersonMultiResult = PersonSummary & { media_type: 'person' }\n\nexport type TrendingResult = SearchMultiResult\n\nexport interface CreditCastMember {\n adult?: boolean\n cast_id?: number\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditCrewMember {\n adult?: boolean\n credit_id: string\n department: string\n gender: number | null\n id: number\n job: string\n known_for_department: string\n name: string\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditsResponse {\n id: number\n cast: CreditCastMember[]\n crew: CreditCrewMember[]\n}\n\nexport interface Video {\n id: string\n iso_3166_1: string\n iso_639_1: string\n key: string\n name: string\n official: boolean\n published_at: string\n site: string\n size: number\n type: string\n}\n\nexport interface VideosResponse {\n id: number\n results: Video[]\n}\n\nexport interface ImageItem {\n aspect_ratio: number\n height: number\n iso_639_1: string | null\n file_path: string\n vote_average: number\n vote_count: number\n width: number\n}\n\nexport interface ImagesResponse {\n id: number\n backdrops: ImageItem[]\n logos?: ImageItem[]\n posters: ImageItem[]\n}\n\nexport interface ConfigurationImages {\n base_url: string\n secure_base_url: string\n backdrop_sizes: string[]\n logo_sizes: string[]\n poster_sizes: string[]\n profile_sizes: string[]\n still_sizes: string[]\n}\n\nexport interface Configuration {\n images: ConfigurationImages\n change_keys: string[]\n}\n\nexport interface Country {\n iso_3166_1: string\n english_name: string\n native_name: string\n}\n\nexport interface Language {\n iso_639_1: string\n english_name: string\n name: string\n}\n\nexport interface Timezone {\n iso_3166_1: string\n zones: string[]\n}\n\nexport interface JobDepartment {\n department: string\n jobs: string[]\n}\n\nexport interface GenresResponse {\n genres: Genre[]\n}\n\nexport type BackdropSize = 'w300' | 'w780' | 'w1280' | 'original' | (string & {})\nexport type LogoSize = 'w45' | 'w92' | 'w154' | 'w185' | 'w300' | 'w500' | 'original' | (string & {})\nexport type PosterSize = 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original' | (string & {})\nexport type ProfileSize = 'w45' | 'w185' | 'h632' | 'original' | (string & {})\nexport type StillSize = 'w92' | 'w185' | 'w300' | 'original' | (string & {})\nexport type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize\n\n/**\n * Public set of image sizes TMDB currently documents. The SDK does not\n * pin to a static copy of the TMDB docs — TMDB has added new sizes in\n * the past (e.g. `h632` for profile) without notice — but exposing the\n * canonical list lets callers:\n *\n * - iterate over the set to build a size picker\n * - validate user-supplied sizes with `isKnownBackdropSize(...)` etc.\n * - type a variable as a \"known\" size without giving up the\n * `(string & {})` escape hatch for forward-compatibility\n *\n * If TMDB publishes a new size, the SDK will still accept it at runtime\n * (every helper is `(string & {})` permissive), but you will need to\n * add the literal to these constants to get autocomplete on it.\n */\nexport const KNOWN_BACKDROP_SIZES = Object.freeze(['w300', 'w780', 'w1280', 'original'] as const)\nexport const KNOWN_LOGO_SIZES = Object.freeze([\n 'w45',\n 'w92',\n 'w154',\n 'w185',\n 'w300',\n 'w500',\n 'original',\n] as const)\nexport const KNOWN_POSTER_SIZES = Object.freeze([\n 'w92',\n 'w154',\n 'w185',\n 'w342',\n 'w500',\n 'w780',\n 'original',\n] as const)\nexport const KNOWN_PROFILE_SIZES = Object.freeze(['w45', 'w185', 'h632', 'original'] as const)\nexport const KNOWN_STILL_SIZES = Object.freeze(['w92', 'w185', 'w300', 'original'] as const)\n\n/** Union of every documented image size. */\nexport const KNOWN_IMAGE_SIZES = Object.freeze([\n ...KNOWN_BACKDROP_SIZES,\n ...KNOWN_LOGO_SIZES,\n ...KNOWN_POSTER_SIZES,\n ...KNOWN_PROFILE_SIZES,\n ...KNOWN_STILL_SIZES,\n] as const)\n\nexport type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number]\nexport type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number]\nexport type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number]\nexport type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number]\nexport type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number]\nexport type KnownImageSize =\n | KnownBackdropSize\n | KnownLogoSize\n | KnownPosterSize\n | KnownProfileSize\n | KnownStillSize\n\n/** O(1) membership check backed by a Set. */\nconst KNOWN_BACKDROP_SET: ReadonlySet<string> = new Set(KNOWN_BACKDROP_SIZES)\nconst KNOWN_LOGO_SET: ReadonlySet<string> = new Set(KNOWN_LOGO_SIZES)\nconst KNOWN_POSTER_SET: ReadonlySet<string> = new Set(KNOWN_POSTER_SIZES)\nconst KNOWN_PROFILE_SET: ReadonlySet<string> = new Set(KNOWN_PROFILE_SIZES)\nconst KNOWN_STILL_SET: ReadonlySet<string> = new Set(KNOWN_STILL_SIZES)\nconst KNOWN_IMAGE_SET: ReadonlySet<string> = new Set(KNOWN_IMAGE_SIZES)\n\nexport function isKnownBackdropSize(value: string): value is KnownBackdropSize {\n return KNOWN_BACKDROP_SET.has(value)\n}\n\nexport function isKnownLogoSize(value: string): value is KnownLogoSize {\n return KNOWN_LOGO_SET.has(value)\n}\n\nexport function isKnownPosterSize(value: string): value is KnownPosterSize {\n return KNOWN_POSTER_SET.has(value)\n}\n\nexport function isKnownProfileSize(value: string): value is KnownProfileSize {\n return KNOWN_PROFILE_SET.has(value)\n}\n\nexport function isKnownStillSize(value: string): value is KnownStillSize {\n return KNOWN_STILL_SET.has(value)\n}\n\n/** True if `value` is in any documented size set. */\nexport function isKnownImageSize(value: string): value is KnownImageSize {\n return KNOWN_IMAGE_SET.has(value)\n}\n\nexport type MovieAppendToResponse =\n | 'account_states'\n | 'alternative_titles'\n | 'changes'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'lists'\n | 'recommendations'\n | 'release_dates'\n | 'reviews'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport type TVAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'alternative_titles'\n | 'changes'\n | 'content_ratings'\n | 'credits'\n | 'episode_groups'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'recommendations'\n | 'reviews'\n | 'screened_theatrically'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport interface ListOptions {\n language?: LanguageCode\n page?: number\n region?: RegionCode\n}\n\nexport interface LanguageOptions {\n language?: LanguageCode\n}\n\nexport interface MovieDetailsOptions extends LanguageOptions {\n appendToResponse?: MovieAppendToResponse | readonly MovieAppendToResponse[]\n}\n\nexport interface TVDetailsOptions extends LanguageOptions {\n appendToResponse?: TVAppendToResponse | readonly TVAppendToResponse[]\n}\n\nexport interface MovieSearchOptions extends ListOptions {\n includeAdult?: boolean\n primaryReleaseYear?: string | number\n year?: string | number\n}\n\nexport interface TVSearchOptions extends Omit<ListOptions, 'region'> {\n firstAirDateYear?: string | number\n includeAdult?: boolean\n year?: string | number\n}\n\nexport interface MultiSearchOptions extends Omit<ListOptions, 'region'> {\n includeAdult?: boolean\n /**\n * Media types to exclude from a `search.multi()` response. Filtering is\n * performed client-side because the TMDB multi-search endpoint does not\n * support a server-side media_type filter.\n */\n exclude?: ReadonlyArray<MediaType>\n}\n\nexport interface ImageQueryOptions extends LanguageOptions {\n includeImageLanguage?: string | readonly string[]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["#apiKey","#accessToken","#baseUrl","#fetch","#headers","#createUrl","#createHeaders","#resolveFetch","#transport","#transport","#transport","#transform","#transport","#transport","#transport","#transport","#transport","#transport"],"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/configuration.ts","../src/resources/genres.ts","../src/resources/images.ts","../src/resources/movies.ts","../src/resources/people.ts","../src/resources/search.ts","../src/resources/trending.ts","../src/resources/tv.ts","../src/client.ts","../src/search-guards.ts","../src/types.ts"],"sourcesContent":["import type { JsonValue } from './types'\n\n/** Raw TMDB error response body structure. */\nexport interface TMDBErrorResponseBody {\n success?: boolean\n status_code?: number\n status_message?: string\n}\n\n/** Options for constructing a {@link TMDBResponseError} or its subclasses. */\nexport interface TMDBResponseErrorOptions {\n body: JsonValue | undefined\n headers: Headers\n status: number\n statusText: string\n url: string\n}\n\n/** Base class for all SDK-originated errors. */\nexport class TMDBError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBError'\n }\n}\n\n/** Thrown before a request is sent or when fetch itself rejects. */\nexport class TMDBRequestError extends TMDBError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBRequestError'\n }\n}\n\n/** Thrown when TMDB returns a non-2xx response. */\nexport class TMDBResponseError extends TMDBError {\n readonly body: JsonValue | undefined\n readonly headers: Headers\n readonly requestId: string | null\n readonly status: number\n readonly statusCode: number | undefined\n readonly statusMessage: string | undefined\n readonly statusText: string\n readonly url: string\n\n constructor(message: string, options: TMDBResponseErrorOptions) {\n super(message)\n this.name = 'TMDBResponseError'\n this.body = options.body\n this.headers = options.headers\n this.requestId = options.headers.get('x-request-id')\n this.status = options.status\n this.statusText = options.statusText\n this.url = options.url\n\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n this.statusCode = body?.status_code\n this.statusMessage = body?.status_message\n }\n\n /** True when TMDB has asked the caller to back off (HTTP 429). */\n get isRateLimit(): boolean {\n return this.status === 429\n }\n\n /** True when the resource was not found (HTTP 404). */\n get isNotFound(): boolean {\n return this.status === 404\n }\n\n /** True when the request was rejected as unauthenticated (HTTP 401). */\n get isUnauthorized(): boolean {\n return this.status === 401\n }\n\n /** True when the request was rejected as forbidden (HTTP 403). */\n get isForbidden(): boolean {\n return this.status === 403\n }\n\n /** True when the upstream returned a 5xx server error. */\n get isServerError(): boolean {\n return this.status >= 500 && this.status < 600\n }\n}\n\nexport interface TMDBRateLimitErrorOptions extends TMDBResponseErrorOptions {\n /** Seconds to wait before retrying. Parsed from the `Retry-After` header. */\n retryAfter: number\n}\n\n/**\n * Thrown when TMDB returns HTTP 429.\n *\n * The SDK does NOT retry automatically — that decision is left to the\n * caller, since retry policies vary widely. Inspect `retryAfter` to\n * implement your own backoff.\n */\nexport class TMDBRateLimitError extends TMDBResponseError {\n readonly retryAfter: number\n\n constructor(message: string, options: TMDBRateLimitErrorOptions) {\n super(message, options)\n this.name = 'TMDBRateLimitError'\n this.retryAfter = options.retryAfter\n }\n}\n\n/**\n * Create the appropriate error instance for a non-2xx TMDB response.\n *\n * Returns a {@link TMDBRateLimitError} when the status is 429, otherwise\n * a generic {@link TMDBResponseError}. The error message is extracted from\n * the TMDB `status_message` field when available.\n */\nexport function createResponseError(\n options: TMDBResponseErrorOptions,\n): TMDBResponseError {\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n const message = body?.status_message ?? `${options.status} ${options.statusText}`.trim()\n\n if (options.status === 429) {\n return new TMDBRateLimitError(message, {\n ...options,\n retryAfter: parseRetryAfter(options.headers.get('retry-after')),\n })\n }\n\n return new TMDBResponseError(message, options)\n}\n\n/**\n * Parse the `Retry-After` header into seconds. Accepts both delta-seconds\n * (e.g. \"5\") and HTTP-date forms (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\").\n * Falls back to 1 second when the header is missing or unparseable.\n */\nexport function parseRetryAfter(value: string | null | undefined): number {\n if (value === null || value === undefined) {\n return 1\n }\n\n const trimmed = value.trim()\n if (trimmed === '') {\n return 1\n }\n\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return seconds\n }\n\n const date = Date.parse(trimmed)\n if (Number.isFinite(date)) {\n const deltaMs = date - Date.now()\n return Math.max(1, Math.ceil(deltaMs / 1000))\n }\n\n return 1\n}\n\n/** Check if a value has the shape of a TMDB error response body. */\nfunction isErrorResponseBody(value: unknown): value is TMDBErrorResponseBody {\n return typeof value === 'object' && value !== null\n}\n","import { TMDBRequestError } from './errors'\nimport type { ImageSize, RegionCode, LanguageCode, TrendingTimeWindow } from './types'\n\n/** Primitives allowed as query parameter values. */\nexport type QueryPrimitive = string | number | boolean\n\n/** A single query parameter value: primitive, array, or nullish. */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[] | null | undefined\n\n/** Key-value map of query parameters for API requests. */\nexport type QueryParams = Record<string, QueryValue>\n\n/** Default query parameters inherited from the client configuration. */\nexport interface QueryDefaults {\n language?: LanguageCode\n region?: RegionCode\n}\n\nexport const DEFAULT_API_BASE_URL = 'https://api.themoviedb.org/3'\nexport const DEFAULT_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p'\n\n/**\n * Append query parameters to a URL object.\n *\n * - `undefined` and `null` values are skipped.\n * - Arrays are joined with commas (TMDB convention).\n * - All values are converted to strings.\n */\nexport function appendQuery(url: URL, query: QueryParams): void {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','))\n continue\n }\n\n url.searchParams.set(key, String(value))\n }\n}\n\n/**\n * Merge a language query parameter with client defaults.\n *\n * If `query.language` is set it takes precedence; otherwise the client's\n * default language is used.\n */\nexport function withLanguage(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const language = typeof query.language === 'string' ? query.language : defaults.language\n\n return {\n ...query,\n language,\n }\n}\n\n/**\n * Merge language and region defaults for list endpoints.\n *\n * Combines {@link withLanguage} with region fallback from client defaults.\n */\nexport function withListDefaults(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const region = typeof query.region === 'string' ? query.region : defaults.region\n\n return {\n ...withLanguage(defaults, query),\n region,\n }\n}\n\n/**\n * Convert a string or string array to a comma-separated list.\n *\n * Returns `undefined` if the input is `undefined` (skips the parameter).\n * TMDB uses comma-separated values for multi-value query parameters.\n */\nexport function toCommaList(value: string | readonly string[] | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'string' ? value : value.join(',')\n}\n\n/**\n * Validate and convert a numeric ID to a string for use in URL paths.\n *\n * @throws {TMDBRequestError} If `value` is not a positive integer.\n */\nexport function toId(value: number, name: string): string {\n if (!Number.isInteger(value) || value <= 0) {\n throw new TMDBRequestError(`${name} must be a positive integer`)\n }\n\n return String(value)\n}\n\n/**\n * Validate and trim a search query string.\n *\n * @throws {TMDBRequestError} If the query is empty after trimming.\n */\nexport function toSearchQuery(value: string): string {\n const query = value.trim()\n\n if (query.length === 0) {\n throw new TMDBRequestError('search query must not be empty')\n }\n\n return query\n}\n\n/**\n * Validate a trending time window value.\n *\n * @throws {TMDBRequestError} If `value` is not `\"day\"` or `\"week\"`.\n */\nexport function toTimeWindow(value: TrendingTimeWindow): TrendingTimeWindow {\n if (value !== 'day' && value !== 'week') {\n throw new TMDBRequestError('timeWindow must be either \"day\" or \"week\"')\n }\n\n return value\n}\n\nexport interface BuildImageUrlOptions {\n baseUrl?: string\n /**\n * Transform the resolved TMDB image URL before returning it. Use this to\n * route requests through a CDN, image proxy, or to add signatures.\n */\n transform?: (url: string) => string\n}\n\n/**\n * Build a full TMDB image URL from the path returned by API payloads.\n * Returns null for nullish image paths so UI code can branch naturally.\n */\nexport function buildImageUrl(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: BuildImageUrlOptions = {},\n): string | null {\n if (path === undefined || path === null || path.trim() === '') {\n return null\n }\n\n const baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_IMAGE_BASE_URL)\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const url = `${baseUrl}/${size}${normalizedPath}`\n\n return options.transform ? options.transform(url) : url\n}\n\n/**\n * Strip trailing slashes from a base URL to ensure consistent path joining.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n","import { createResponseError, TMDBRequestError } from './errors'\nimport {\n appendQuery,\n DEFAULT_API_BASE_URL,\n DEFAULT_IMAGE_BASE_URL,\n normalizeBaseUrl,\n type QueryDefaults,\n type QueryParams,\n} from './query'\nimport type { ImageUrlTransform } from './resources/images'\nimport type { JsonValue, LanguageCode, RegionCode } from './types'\n\nexport type { ImageUrlTransform }\n\n/**\n * A minimal fetch-like function signature. Any runtime's native `fetch`\n * or a test double conforming to this shape can be used.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface TMDBAccessTokenAuth {\n /** TMDB API Read Access Token. Sent as an Authorization Bearer header. */\n accessToken: string\n apiKey?: never\n}\n\nexport interface TMDBApiKeyAuth {\n /** Legacy v3 API key. Sent as api_key query parameter. */\n apiKey: string\n accessToken?: never\n}\n\nexport type TMDBAuth = TMDBAccessTokenAuth | TMDBApiKeyAuth\n\n/** Internal defaults resolved during client construction. */\nexport interface TMDBClientDefaults extends QueryDefaults {\n imageBaseUrl: string\n}\n\nexport interface TMDBImagesOptions {\n /**\n * Default transform applied to every URL produced by the ImagesHelper.\n * Use this to route TMDB image requests through a CDN, image proxy, or\n * to add signed query parameters. Individual calls can still override it\n * via ImagesHelper.url(path, size, { transform }).\n */\n transform?: ImageUrlTransform\n}\n\nexport type TMDBClientOptions = TMDBAuth & {\n /** Defaults to https://api.themoviedb.org/3. Useful for tests or proxies. */\n baseUrl?: string\n /** Inject a fetch implementation for tests, custom runtimes, or instrumentation. */\n fetch?: FetchLike\n /** Default language for endpoints that accept a language query parameter. */\n defaultLanguage?: LanguageCode\n /** Default region for movie list/search endpoints that accept a region query parameter. */\n defaultRegion?: RegionCode\n /** Custom image host. Defaults to https://image.tmdb.org/t/p. */\n imageBaseUrl?: string\n /** Image-helper configuration: host overrides and URL transforms. */\n images?: TMDBImagesOptions\n /** Additional headers merged into every request before authentication is applied. */\n headers?: HeadersInit\n}\n\n/** Per-request overrides applied when making a single API call. */\nexport interface TMDBRequestOptions {\n headers?: HeadersInit\n query?: QueryParams\n signal?: AbortSignal\n}\n\n/**\n * Transport abstraction for making HTTP requests to the TMDB API.\n *\n * The built-in {@link TMDBHttpClient} implements this interface. You can\n * provide a custom implementation via {@link TMDBFactoryOptions.transport}\n * for testing, caching, or instrumentation.\n */\nexport interface TMDBTransport {\n readonly defaults: TMDBClientDefaults\n get<T>(path: string, options?: TMDBRequestOptions): Promise<T>\n}\n\n/**\n * Built-in HTTP transport that uses the Fetch API.\n *\n * Handles authentication (API key or access token), URL construction,\n * request headers, and response parsing. Use the factory function\n * {@link createTMDB} instead of instantiating this directly.\n */\nexport class TMDBHttpClient implements TMDBTransport {\n readonly defaults: TMDBClientDefaults\n readonly imageTransform: ImageUrlTransform | undefined\n\n readonly #apiKey: string | undefined\n readonly #accessToken: string | undefined\n readonly #baseUrl: string\n readonly #fetch: FetchLike | undefined\n readonly #headers: HeadersInit | undefined\n\n constructor(options: TMDBClientOptions) {\n const accessToken = normalizeSecret('accessToken' in options ? options.accessToken : undefined)\n const apiKey = normalizeSecret('apiKey' in options ? options.apiKey : undefined)\n\n if (Boolean(accessToken) === Boolean(apiKey)) {\n throw new TMDBRequestError('Provide exactly one of accessToken or apiKey')\n }\n\n this.#accessToken = accessToken\n this.#apiKey = apiKey\n this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_API_BASE_URL)\n this.#fetch = options.fetch\n this.#headers = options.headers\n this.defaults = {\n imageBaseUrl: normalizeBaseUrl(options.imageBaseUrl ?? DEFAULT_IMAGE_BASE_URL),\n language: options.defaultLanguage,\n region: options.defaultRegion,\n }\n this.imageTransform = options.images?.transform\n }\n\n async get<T>(path: string, options: TMDBRequestOptions = {}): Promise<T> {\n const url = this.#createUrl(path, options.query ?? {})\n const headers = this.#createHeaders(options.headers)\n const fetchImpl = this.#resolveFetch()\n\n let response: Response\n\n try {\n response = await fetchImpl(url, {\n headers,\n method: 'GET',\n signal: options.signal,\n })\n } catch (error) {\n throw new TMDBRequestError(`TMDB request failed: ${String(error)}`, { cause: error })\n }\n\n const body = await readJson(response)\n\n if (!response.ok) {\n throw createResponseError({\n body,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n url,\n })\n }\n\n return body as T\n }\n\n #resolveFetch(): FetchLike {\n if (this.#fetch !== undefined) {\n return this.#fetch\n }\n\n const globalFetch = globalThis.fetch\n\n if (typeof globalFetch !== 'function') {\n throw new TMDBRequestError('No fetch implementation found. Pass options.fetch in this runtime.')\n }\n\n return globalFetch.bind(globalThis)\n }\n\n #createHeaders(headersInit: HeadersInit | undefined): Headers {\n const headers = new Headers(this.#headers)\n const requestHeaders = new Headers(headersInit)\n\n headers.set('Accept', 'application/json')\n\n for (const [key, value] of requestHeaders) {\n headers.set(key, value)\n }\n\n if (this.#accessToken !== undefined) {\n headers.set('Authorization', `Bearer ${this.#accessToken}`)\n }\n\n return headers\n }\n\n #createUrl(path: string, query: QueryParams): string {\n const relativePath = path.replace(/^\\/+/, '')\n const url = new URL(relativePath, `${this.#baseUrl}/`)\n\n appendQuery(url, {\n ...query,\n api_key: this.#apiKey,\n })\n\n return url.toString()\n }\n}\n\n/**\n * Read and parse a JSON response body.\n *\n * Returns `undefined` for empty responses. If the body is not valid JSON,\n * the raw text string is returned as-is (TMDB occasionally returns plain\n * text for certain error conditions).\n */\nasync function readJson(response: Response): Promise<JsonValue | undefined> {\n const text = await response.text()\n\n if (text.length === 0) {\n return undefined\n }\n\n try {\n return JSON.parse(text) as JsonValue\n } catch {\n return text\n }\n}\n\n/**\n * Normalize a secret value by trimming whitespace and treating empty\n * strings as undefined (not provided).\n */\nfunction normalizeSecret(value: string | undefined): string | undefined {\n const secret = value?.trim()\n return secret === '' ? undefined : secret\n}\n","import type { TMDBTransport } from '../http'\nimport type { Configuration, Country, JobDepartment, Language, Timezone } from '../types'\n\n/**\n * Access TMDB configuration data (image sizes, countries, languages, etc.).\n *\n * Obtained via `client.configuration`.\n */\nexport class ConfigurationResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n details(): Promise<Configuration> {\n return this.#transport.get('/configuration')\n }\n\n countries(): Promise<Country[]> {\n return this.#transport.get('/configuration/countries')\n }\n\n jobs(): Promise<JobDepartment[]> {\n return this.#transport.get('/configuration/jobs')\n }\n\n languages(): Promise<Language[]> {\n return this.#transport.get('/configuration/languages')\n }\n\n primaryTranslations(): Promise<string[]> {\n return this.#transport.get('/configuration/primary_translations')\n }\n\n timezones(): Promise<Timezone[]> {\n return this.#transport.get('/configuration/timezones')\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { withLanguage } from '../query'\nimport type { GenresResponse, LanguageOptions } from '../types'\n\n/**\n * Access TMDB genre lists for movies and TV shows.\n *\n * Obtained via `client.genres`.\n */\nexport class GenresResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/movie/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/tv/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { buildImageUrl } from '../query'\nimport type { ImageSize } from '../types'\n\n/** Function that transforms a TMDB image URL (e.g. for CDN proxying). */\nexport type ImageUrlTransform = (url: string) => string\n\n/**\n * Helper for constructing TMDB image URLs from API path values.\n *\n * Obtained via `client.images`. Supports optional URL transforms for\n * routing image requests through a CDN or proxy.\n */\nexport class ImagesHelper {\n readonly #transport: TMDBTransport\n readonly #transform: ImageUrlTransform | undefined\n\n constructor(transport: TMDBTransport, transform?: ImageUrlTransform) {\n this.#transport = transport\n this.#transform = transform\n }\n\n url(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: { transform?: ImageUrlTransform } = {},\n ): string | null {\n return buildImageUrl(path, size, {\n baseUrl: this.#transport.defaults.imageBaseUrl,\n transform: options.transform ?? this.#transform,\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n ListOptions,\n MovieDetails,\n MovieDetailsOptions,\n MovieSummary,\n PagedResponse,\n TMDBObject,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB movie endpoints (popular, top-rated, details, credits, etc.).\n *\n * Obtained via `client.movies`.\n */\nexport class MoviesResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/popular', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n topRated(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/top_rated', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n nowPlaying(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/now_playing', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n upcoming(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/upcoming', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n movieId: number,\n options: MovieDetailsOptions = {},\n ): Promise<MovieDetails & TAppend> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(movieId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/recommendations`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n similar(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/similar`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n videos(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<VideosResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for movie list endpoints. */\nfunction movieListQuery(transport: TMDBTransport, options: ListOptions): QueryParams {\n return withListDefaults(transport.defaults, {\n language: options.language,\n page: options.page,\n region: options.region,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toId, withLanguage, type QueryParams } from '../query'\nimport type { LanguageOptions, ListOptions, PagedResponse, PersonDetails, PersonSummary } from '../types'\n\n/**\n * Access TMDB person (actor, director, etc.) endpoints.\n *\n * Obtained via `client.people`.\n */\nexport class PeopleResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<PersonSummary>> {\n return this.#transport.get('/person/popular', {\n query: peopleListQuery(this.#transport, options),\n })\n }\n\n details(personId: number, options: LanguageOptions = {}): Promise<PersonDetails> {\n return this.#transport.get(`/person/${toId(personId, 'personId')}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for person list endpoints. */\nfunction peopleListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toSearchQuery, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n MovieSearchOptions,\n MovieSearchResult,\n MultiSearchOptions,\n PagedResponse,\n PersonSearchResult,\n SearchMultiResult,\n TVSearchOptions,\n TVSearchResult,\n} from '../types'\n\n/**\n * Search TMDB for movies, TV shows, people, or all media types.\n *\n * Obtained via `client.search`.\n */\nexport class SearchResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(query: string, options: MovieSearchOptions = {}): Promise<PagedResponse<MovieSearchResult>> {\n return this.#transport.get('/search/movie', {\n query: movieSearchQuery(this.#transport, query, options),\n })\n }\n\n tv(query: string, options: TVSearchOptions = {}): Promise<PagedResponse<TVSearchResult>> {\n return this.#transport.get('/search/tv', {\n query: tvSearchQuery(this.#transport, query, options),\n })\n }\n\n people(query: string, options: MultiSearchOptions = {}): Promise<PagedResponse<PersonSearchResult>> {\n return this.#transport.get('/search/person', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n }\n\n async multi(\n query: string,\n options: MultiSearchOptions = {},\n ): Promise<PagedResponse<SearchMultiResult>> {\n const response = await this.#transport.get<PagedResponse<SearchMultiResult>>('/search/multi', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n\n const excluded = options.exclude\n if (excluded === undefined || excluded.length === 0) {\n return response\n }\n\n const excludedSet = new Set<string>(excluded)\n return {\n ...response,\n results: response.results.filter((result) => !excludedSet.has(result.media_type)),\n }\n }\n}\n\n/** Build query parameters for movie search. */\nfunction movieSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MovieSearchOptions,\n): QueryParams {\n return withListDefaults(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n primary_release_year: options.primaryReleaseYear,\n query: toSearchQuery(query),\n region: options.region,\n year: options.year,\n })\n}\n\n/** Build query parameters for TV search. */\nfunction tvSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: TVSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n first_air_date_year: options.firstAirDateYear,\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n year: options.year,\n })\n}\n\n/** Build query parameters for person and multi-search. */\nfunction commonSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MultiSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toTimeWindow, withLanguage } from '../query'\nimport type {\n LanguageOptions,\n MovieSummary,\n PagedResponse,\n PersonSummary,\n TrendingResult,\n TrendingTimeWindow,\n TVSummary,\n} from '../types'\n\n/**\n * Access TMDB trending content (movies, TV, people) for day/week windows.\n *\n * Obtained via `client.trending`.\n */\nexport class TrendingResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n all(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TrendingResult>> {\n return this.#transport.get(`/trending/all/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n movies(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<MovieSummary & { media_type?: 'movie' }>> {\n return this.#transport.get(`/trending/movie/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TVSummary & { media_type?: 'tv' }>> {\n return this.#transport.get(`/trending/tv/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n people(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<PersonSummary & { media_type?: 'person' }>> {\n return this.#transport.get(`/trending/person/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n LanguageOptions,\n ListOptions,\n PagedResponse,\n TMDBObject,\n TVDetails,\n TVDetailsOptions,\n TVSeasonDetails,\n TVSeasonDetailsOptions,\n TVSummary,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB TV show endpoints (popular, top-rated, details, seasons, etc.).\n *\n * Obtained via `client.tv`.\n */\nexport class TVResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/popular', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n topRated(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/top_rated', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n airingToday(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/airing_today', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n onTheAir(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/on_the_air', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n options: TVDetailsOptions = {},\n ): Promise<TVDetails & TAppend> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(seriesId: number, options: LanguageOptions = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(seriesId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/recommendations`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n similar(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/similar`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n videos(seriesId: number, options: LanguageOptions = {}): Promise<VideosResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n seasonDetails<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n seasonNumber: number,\n options: TVSeasonDetailsOptions = {},\n ): Promise<TVSeasonDetails & TAppend> {\n return this.#transport.get(\n `/tv/${toId(seriesId, 'seriesId')}/season/${toId(seasonNumber, 'seasonNumber')}`,\n {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n },\n )\n }\n}\n\n/** Build query parameters for TV list endpoints. */\nfunction tvListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import { TMDBHttpClient, type TMDBClientOptions, type TMDBRequestOptions, type TMDBTransport } from './http'\nimport { ConfigurationResource } from './resources/configuration'\nimport { GenresResource } from './resources/genres'\nimport { ImagesHelper } from './resources/images'\nimport { MoviesResource } from './resources/movies'\nimport { PeopleResource } from './resources/people'\nimport { SearchResource } from './resources/search'\nimport { TrendingResource } from './resources/trending'\nimport { TVResource } from './resources/tv'\n\n/**\n * Options accepted by {@link createTMDB} and the {@link TMDBClient} constructor.\n *\n * Extends {@link TMDBClientOptions} with an optional {@link TMDBTransport} so\n * callers can plug in a custom transport (typically for tests, caching, or\n * instrumentation) without having to mock `fetch` or the factory itself.\n */\nexport type TMDBFactoryOptions = TMDBClientOptions & {\n transport?: TMDBTransport\n}\n\n/**\n * Main SDK entry point.\n *\n * Resource properties are intentionally small and explicit. The SDK focuses on\n * common TMDB workflows first, while request<T>() keeps uncommon endpoints easy\n * to call without waiting for a generated surface area.\n */\nexport class TMDBClient {\n readonly configuration: ConfigurationResource\n readonly genres: GenresResource\n readonly images: ImagesHelper\n readonly movies: MoviesResource\n readonly people: PeopleResource\n readonly search: SearchResource\n readonly trending: TrendingResource\n readonly tv: TVResource\n\n readonly #transport: TMDBTransport\n\n constructor(options: TMDBFactoryOptions) {\n const { transport, images, ...httpOptions } = options\n // When the caller supplies a custom transport we still want to honor the\n // global images.transform option; otherwise read it back from the HTTP\n // client after it has been constructed.\n const fallbackTransform = images?.transform\n const builtInClient = transport === undefined ? new TMDBHttpClient({ ...httpOptions, images }) : undefined\n this.#transport = builtInClient ?? (transport as TMDBTransport)\n\n this.configuration = new ConfigurationResource(this.#transport)\n this.genres = new GenresResource(this.#transport)\n this.images = new ImagesHelper(\n this.#transport,\n builtInClient ? builtInClient.imageTransform : fallbackTransform,\n )\n this.movies = new MoviesResource(this.#transport)\n this.people = new PeopleResource(this.#transport)\n this.search = new SearchResource(this.#transport)\n this.trending = new TrendingResource(this.#transport)\n this.tv = new TVResource(this.#transport)\n }\n\n /**\n * Make a raw GET request to any TMDB endpoint.\n *\n * This is an escape hatch for endpoints not covered by the typed resource\n * helpers. The `path` should be relative to the API base URL (e.g.\n * `/movie/{id}/credits`). Response is parsed as JSON and cast to `T`.\n *\n * @param path - API path relative to the base URL (e.g. `/movie/123`)\n * @param options - Optional request-level overrides (headers, query, signal)\n * @returns Parsed JSON response typed as `T`\n */\n request<T>(path: string, options?: TMDBRequestOptions): Promise<T> {\n return this.#transport.get<T>(path, options)\n }\n}\n\n/**\n * Create a new {@link TMDBClient} instance.\n *\n * @example\n * ```ts\n * const tmdb = createTMDB({ accessToken: 'YOUR_TOKEN' })\n * const { results } = await tmdb.search.movies('Inception')\n * ```\n *\n * @param options - Authentication and configuration options\n * @returns A configured TMDBClient ready to make API calls\n */\nexport function createTMDB(options: TMDBFactoryOptions): TMDBClient {\n return new TMDBClient(options)\n}\n","import type {\n MovieMultiResult,\n MovieSearchResult,\n PersonMultiResult,\n PersonSearchResult,\n SearchMultiResult,\n TVMultiResult,\n TVSearchResult,\n} from './types'\n\n/**\n * Type guard that narrows a `search.multi()` result to a movie entry.\n *\n * The `media_type` field is required on every `/search/multi` payload by\n * TMDB, so this check is safe at runtime and produces a strictly typed\n * MovieSummary on the narrowed branch.\n */\nexport function isMovieSearchResult(\n result: SearchMultiResult,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a `search.multi()` result to a TV entry. */\nexport function isTVSearchResult(\n result: SearchMultiResult,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a `search.multi()` result to a person entry. */\nexport function isPersonSearchResult(\n result: SearchMultiResult,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/**\n * Convenience alias: `isMovieSearchResult` works on a `search.movies()`\n * result (which already has the narrow type but is also tagged with\n * `media_type?: 'movie'`), as well as on multi-search results.\n */\nexport function isMovie(result: MovieSearchResult | SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a search result to a TV entry. */\nexport function isTV(\n result: TVSearchResult | SearchMultiResult): result is TVMultiResult\nexport function isTV(result: SearchMultiResult): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a search result to a person entry. */\nexport function isPerson(\n result: PersonSearchResult | SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/** Internal helper: check if a value is an object with a matching `media_type` field. */\nfunction isObjectWithMediaType(\n value: unknown,\n mediaType: 'movie' | 'tv' | 'person',\n): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'media_type' in value &&\n (value as { media_type: unknown }).media_type === mediaType\n )\n}\n","/** Primitive JSON values returned by TMDB. */\nexport type JsonPrimitive = string | number | boolean | null\n\n/** JSON object/array tree returned by TMDB for fields this SDK does not model yet. */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[]\n\nexport interface JsonObject {\n [key: string]: JsonValue | undefined\n}\n\n/** Escape hatch for append_to_response payloads and future TMDB fields. */\nexport type TMDBObject = Record<string, unknown>\n\n/** Date string in TMDB format (typically `YYYY-MM-DD`). */\nexport type TMDBDateString = string\n\n/** ISO 639-1 language code (e.g. `\"en\"`, `\"zh\"`). */\nexport type LanguageCode = string\n\n/** ISO 3166-1 country/region code (e.g. `\"US\"`, `\"CN\"`). */\nexport type RegionCode = string\n\n/** Supported media types for multi-search results. */\nexport type MediaType = 'movie' | 'tv' | 'person'\n\n/** Time window for trending endpoints: `\"day\"` or `\"week\"`. */\nexport type TrendingTimeWindow = 'day' | 'week'\n\nexport interface PagedResponse<T> {\n page: number\n results: T[]\n total_pages: number\n total_results: number\n}\n\nexport interface Genre {\n id: number\n name: string\n}\n\nexport interface ProductionCompany {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface ProductionCountry {\n iso_3166_1: string\n name: string\n}\n\nexport interface SpokenLanguage {\n english_name: string\n iso_639_1: string\n name: string\n}\n\nexport interface CollectionSummary {\n id: number\n name: string\n poster_path: string | null\n backdrop_path: string | null\n}\n\nexport interface MovieSummary {\n adult: boolean\n backdrop_path: string | null\n genre_ids: number[]\n id: number\n original_language: string\n original_title: string\n overview: string\n popularity: number\n poster_path: string | null\n release_date: TMDBDateString\n title: string\n video: boolean\n vote_average: number\n vote_count: number\n}\n\nexport interface MovieDetails extends Omit<MovieSummary, 'genre_ids'> {\n belongs_to_collection: CollectionSummary | null\n budget: number\n genres: Genre[]\n homepage: string | null\n imdb_id: string | null\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n revenue: number\n runtime: number | null\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n}\n\nexport interface TVSummary {\n adult?: boolean\n backdrop_path: string | null\n first_air_date: TMDBDateString\n genre_ids: number[]\n id: number\n name: string\n origin_country: string[]\n original_language: string\n original_name: string\n overview: string\n popularity: number\n poster_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface CreatedBy {\n id: number\n credit_id: string\n name: string\n gender: number\n profile_path: string | null\n}\n\nexport interface Network {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface SeasonSummary {\n air_date: TMDBDateString | null\n episode_count: number\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport interface EpisodeGuestStar {\n adult: boolean\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface EpisodeSummary {\n air_date: TMDBDateString | null\n crew: CreditCrewMember[]\n episode_number: number\n episode_type: string\n guest_stars: EpisodeGuestStar[]\n id: number\n name: string\n overview: string\n production_code: string | null\n runtime: number | null\n season_number: number\n show_id: number\n still_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface TVSeasonDetails {\n _id: string\n air_date: TMDBDateString | null\n episodes: EpisodeSummary[]\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport type TVSeasonAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'translations'\n | 'videos'\n | (string & {})\n\nexport interface TVSeasonDetailsOptions extends LanguageOptions {\n appendToResponse?: TVSeasonAppendToResponse | readonly TVSeasonAppendToResponse[]\n}\n\nexport interface TVDetails extends Omit<TVSummary, 'genre_ids'> {\n created_by: CreatedBy[]\n episode_run_time: number[]\n genres: Genre[]\n homepage: string | null\n in_production: boolean\n languages: string[]\n last_air_date: TMDBDateString | null\n networks: Network[]\n number_of_episodes: number\n number_of_seasons: number\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n seasons: SeasonSummary[]\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n type: string\n}\n\nexport interface PersonKnownForMovie extends MovieSummary {\n media_type: 'movie'\n}\n\nexport interface PersonKnownForTV extends TVSummary {\n media_type: 'tv'\n}\n\nexport type PersonKnownFor = PersonKnownForMovie | PersonKnownForTV\n\nexport interface PersonSummary {\n adult: boolean\n gender: number\n id: number\n known_for: PersonKnownFor[]\n known_for_department: string\n name: string\n original_name?: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface PersonDetails extends Omit<PersonSummary, 'known_for'> {\n also_known_as: string[]\n biography: string\n birthday: TMDBDateString | null\n deathday: TMDBDateString | null\n homepage: string | null\n imdb_id: string | null\n place_of_birth: string | null\n}\n\nexport interface MovieSearchResult extends MovieSummary {\n media_type?: 'movie'\n}\n\nexport interface TVSearchResult extends TVSummary {\n media_type?: 'tv'\n}\n\nexport interface PersonSearchResult extends PersonSummary {\n media_type?: 'person'\n}\n\nexport type SearchMultiResult =\n | (MovieSummary & { media_type: 'movie' })\n | (TVSummary & { media_type: 'tv' })\n | (PersonSummary & { media_type: 'person' })\n\n/** A single multi-search result narrowed to a specific media type. */\nexport type MovieMultiResult = MovieSummary & { media_type: 'movie' }\nexport type TVMultiResult = TVSummary & { media_type: 'tv' }\nexport type PersonMultiResult = PersonSummary & { media_type: 'person' }\n\nexport type TrendingResult = SearchMultiResult\n\nexport interface CreditCastMember {\n adult?: boolean\n cast_id?: number\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditCrewMember {\n adult?: boolean\n credit_id: string\n department: string\n gender: number | null\n id: number\n job: string\n known_for_department: string\n name: string\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditsResponse {\n id: number\n cast: CreditCastMember[]\n crew: CreditCrewMember[]\n}\n\nexport interface Video {\n id: string\n iso_3166_1: string\n iso_639_1: string\n key: string\n name: string\n official: boolean\n published_at: string\n site: string\n size: number\n type: string\n}\n\nexport interface VideosResponse {\n id: number\n results: Video[]\n}\n\nexport interface ImageItem {\n aspect_ratio: number\n height: number\n iso_639_1: string | null\n file_path: string\n vote_average: number\n vote_count: number\n width: number\n}\n\nexport interface ImagesResponse {\n id: number\n backdrops: ImageItem[]\n logos?: ImageItem[]\n posters: ImageItem[]\n}\n\nexport interface ConfigurationImages {\n base_url: string\n secure_base_url: string\n backdrop_sizes: string[]\n logo_sizes: string[]\n poster_sizes: string[]\n profile_sizes: string[]\n still_sizes: string[]\n}\n\nexport interface Configuration {\n images: ConfigurationImages\n change_keys: string[]\n}\n\nexport interface Country {\n iso_3166_1: string\n english_name: string\n native_name: string\n}\n\nexport interface Language {\n iso_639_1: string\n english_name: string\n name: string\n}\n\nexport interface Timezone {\n iso_3166_1: string\n zones: string[]\n}\n\nexport interface JobDepartment {\n department: string\n jobs: string[]\n}\n\nexport interface GenresResponse {\n genres: Genre[]\n}\n\nexport type BackdropSize = 'w300' | 'w780' | 'w1280' | 'original' | (string & {})\nexport type LogoSize = 'w45' | 'w92' | 'w154' | 'w185' | 'w300' | 'w500' | 'original' | (string & {})\nexport type PosterSize = 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original' | (string & {})\nexport type ProfileSize = 'w45' | 'w185' | 'h632' | 'original' | (string & {})\nexport type StillSize = 'w92' | 'w185' | 'w300' | 'original' | (string & {})\nexport type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize\n\n/**\n * Public set of image sizes TMDB currently documents. The SDK does not\n * pin to a static copy of the TMDB docs — TMDB has added new sizes in\n * the past (e.g. `h632` for profile) without notice — but exposing the\n * canonical list lets callers:\n *\n * - iterate over the set to build a size picker\n * - validate user-supplied sizes with `isKnownBackdropSize(...)` etc.\n * - type a variable as a \"known\" size without giving up the\n * `(string & {})` escape hatch for forward-compatibility\n *\n * If TMDB publishes a new size, the SDK will still accept it at runtime\n * (every helper is `(string & {})` permissive), but you will need to\n * add the literal to these constants to get autocomplete on it.\n */\nexport const KNOWN_BACKDROP_SIZES: readonly ['w300', 'w780', 'w1280', 'original'] = Object.freeze(['w300', 'w780', 'w1280', 'original'] as const)\nexport const KNOWN_LOGO_SIZES: readonly ['w45', 'w92', 'w154', 'w185', 'w300', 'w500', 'original'] = Object.freeze([\n 'w45',\n 'w92',\n 'w154',\n 'w185',\n 'w300',\n 'w500',\n 'original',\n] as const)\nexport const KNOWN_POSTER_SIZES: readonly ['w92', 'w154', 'w185', 'w342', 'w500', 'w780', 'original'] = Object.freeze([\n 'w92',\n 'w154',\n 'w185',\n 'w342',\n 'w500',\n 'w780',\n 'original',\n] as const)\nexport const KNOWN_PROFILE_SIZES: readonly ['w45', 'w185', 'h632', 'original'] = Object.freeze(['w45', 'w185', 'h632', 'original'] as const)\nexport const KNOWN_STILL_SIZES: readonly ['w92', 'w185', 'w300', 'original'] = Object.freeze(['w92', 'w185', 'w300', 'original'] as const)\n\nexport type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number]\nexport type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number]\nexport type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number]\nexport type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number]\nexport type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number]\nexport type KnownImageSize =\n | KnownBackdropSize\n | KnownLogoSize\n | KnownPosterSize\n | KnownProfileSize\n | KnownStillSize\n\n/** Union of every documented image size. */\nexport const KNOWN_IMAGE_SIZES: readonly KnownImageSize[] = Object.freeze([\n ...KNOWN_BACKDROP_SIZES,\n ...KNOWN_LOGO_SIZES,\n ...KNOWN_POSTER_SIZES,\n ...KNOWN_PROFILE_SIZES,\n ...KNOWN_STILL_SIZES,\n] as const)\n\n/** O(1) membership check backed by a Set. */\nconst KNOWN_BACKDROP_SET: ReadonlySet<string> = new Set(KNOWN_BACKDROP_SIZES)\nconst KNOWN_LOGO_SET: ReadonlySet<string> = new Set(KNOWN_LOGO_SIZES)\nconst KNOWN_POSTER_SET: ReadonlySet<string> = new Set(KNOWN_POSTER_SIZES)\nconst KNOWN_PROFILE_SET: ReadonlySet<string> = new Set(KNOWN_PROFILE_SIZES)\nconst KNOWN_STILL_SET: ReadonlySet<string> = new Set(KNOWN_STILL_SIZES)\nconst KNOWN_IMAGE_SET: ReadonlySet<string> = new Set(KNOWN_IMAGE_SIZES)\n\nexport function isKnownBackdropSize(value: string): value is KnownBackdropSize {\n return KNOWN_BACKDROP_SET.has(value)\n}\n\nexport function isKnownLogoSize(value: string): value is KnownLogoSize {\n return KNOWN_LOGO_SET.has(value)\n}\n\nexport function isKnownPosterSize(value: string): value is KnownPosterSize {\n return KNOWN_POSTER_SET.has(value)\n}\n\nexport function isKnownProfileSize(value: string): value is KnownProfileSize {\n return KNOWN_PROFILE_SET.has(value)\n}\n\nexport function isKnownStillSize(value: string): value is KnownStillSize {\n return KNOWN_STILL_SET.has(value)\n}\n\n/** True if `value` is in any documented size set. */\nexport function isKnownImageSize(value: string): value is KnownImageSize {\n return KNOWN_IMAGE_SET.has(value)\n}\n\nexport type MovieAppendToResponse =\n | 'account_states'\n | 'alternative_titles'\n | 'changes'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'lists'\n | 'recommendations'\n | 'release_dates'\n | 'reviews'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport type TVAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'alternative_titles'\n | 'changes'\n | 'content_ratings'\n | 'credits'\n | 'episode_groups'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'recommendations'\n | 'reviews'\n | 'screened_theatrically'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport interface ListOptions {\n language?: LanguageCode\n page?: number\n region?: RegionCode\n}\n\nexport interface LanguageOptions {\n language?: LanguageCode\n}\n\nexport interface MovieDetailsOptions extends LanguageOptions {\n appendToResponse?: MovieAppendToResponse | readonly MovieAppendToResponse[]\n}\n\nexport interface TVDetailsOptions extends LanguageOptions {\n appendToResponse?: TVAppendToResponse | readonly TVAppendToResponse[]\n}\n\nexport interface MovieSearchOptions extends ListOptions {\n includeAdult?: boolean\n primaryReleaseYear?: string | number\n year?: string | number\n}\n\nexport interface TVSearchOptions extends Omit<ListOptions, 'region'> {\n firstAirDateYear?: string | number\n includeAdult?: boolean\n year?: string | number\n}\n\nexport interface MultiSearchOptions extends Omit<ListOptions, 'region'> {\n includeAdult?: boolean\n /**\n * Media types to exclude from a `search.multi()` response. Filtering is\n * performed client-side because the TMDB multi-search endpoint does not\n * support a server-side media_type filter.\n */\n exclude?: ReadonlyArray<MediaType>\n}\n\nexport interface ImageQueryOptions extends LanguageOptions {\n includeImageLanguage?: string | readonly string[]\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -354,19 +354,19 @@ type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize;
|
|
|
354
354
|
* (every helper is `(string & {})` permissive), but you will need to
|
|
355
355
|
* add the literal to these constants to get autocomplete on it.
|
|
356
356
|
*/
|
|
357
|
-
declare const KNOWN_BACKDROP_SIZES: readonly [
|
|
358
|
-
declare const KNOWN_LOGO_SIZES: readonly [
|
|
359
|
-
declare const KNOWN_POSTER_SIZES: readonly [
|
|
360
|
-
declare const KNOWN_PROFILE_SIZES: readonly [
|
|
361
|
-
declare const KNOWN_STILL_SIZES: readonly [
|
|
362
|
-
/** Union of every documented image size. */
|
|
363
|
-
declare const KNOWN_IMAGE_SIZES: readonly ["w300", "w780", "w1280", "original", "w45", "w92", "w154", "w185", "w300", "w500", "original", "w92", "w154", "w185", "w342", "w500", "w780", "original", "w45", "w185", "h632", "original", "w92", "w185", "w300", "original"];
|
|
357
|
+
declare const KNOWN_BACKDROP_SIZES: readonly ['w300', 'w780', 'w1280', 'original'];
|
|
358
|
+
declare const KNOWN_LOGO_SIZES: readonly ['w45', 'w92', 'w154', 'w185', 'w300', 'w500', 'original'];
|
|
359
|
+
declare const KNOWN_POSTER_SIZES: readonly ['w92', 'w154', 'w185', 'w342', 'w500', 'w780', 'original'];
|
|
360
|
+
declare const KNOWN_PROFILE_SIZES: readonly ['w45', 'w185', 'h632', 'original'];
|
|
361
|
+
declare const KNOWN_STILL_SIZES: readonly ['w92', 'w185', 'w300', 'original'];
|
|
364
362
|
type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number];
|
|
365
363
|
type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number];
|
|
366
364
|
type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number];
|
|
367
365
|
type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number];
|
|
368
366
|
type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number];
|
|
369
367
|
type KnownImageSize = KnownBackdropSize | KnownLogoSize | KnownPosterSize | KnownProfileSize | KnownStillSize;
|
|
368
|
+
/** Union of every documented image size. */
|
|
369
|
+
declare const KNOWN_IMAGE_SIZES: readonly KnownImageSize[];
|
|
370
370
|
declare function isKnownBackdropSize(value: string): value is KnownBackdropSize;
|
|
371
371
|
declare function isKnownLogoSize(value: string): value is KnownLogoSize;
|
|
372
372
|
declare function isKnownPosterSize(value: string): value is KnownPosterSize;
|
package/dist/index.d.ts
CHANGED
|
@@ -354,19 +354,19 @@ type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize;
|
|
|
354
354
|
* (every helper is `(string & {})` permissive), but you will need to
|
|
355
355
|
* add the literal to these constants to get autocomplete on it.
|
|
356
356
|
*/
|
|
357
|
-
declare const KNOWN_BACKDROP_SIZES: readonly [
|
|
358
|
-
declare const KNOWN_LOGO_SIZES: readonly [
|
|
359
|
-
declare const KNOWN_POSTER_SIZES: readonly [
|
|
360
|
-
declare const KNOWN_PROFILE_SIZES: readonly [
|
|
361
|
-
declare const KNOWN_STILL_SIZES: readonly [
|
|
362
|
-
/** Union of every documented image size. */
|
|
363
|
-
declare const KNOWN_IMAGE_SIZES: readonly ["w300", "w780", "w1280", "original", "w45", "w92", "w154", "w185", "w300", "w500", "original", "w92", "w154", "w185", "w342", "w500", "w780", "original", "w45", "w185", "h632", "original", "w92", "w185", "w300", "original"];
|
|
357
|
+
declare const KNOWN_BACKDROP_SIZES: readonly ['w300', 'w780', 'w1280', 'original'];
|
|
358
|
+
declare const KNOWN_LOGO_SIZES: readonly ['w45', 'w92', 'w154', 'w185', 'w300', 'w500', 'original'];
|
|
359
|
+
declare const KNOWN_POSTER_SIZES: readonly ['w92', 'w154', 'w185', 'w342', 'w500', 'w780', 'original'];
|
|
360
|
+
declare const KNOWN_PROFILE_SIZES: readonly ['w45', 'w185', 'h632', 'original'];
|
|
361
|
+
declare const KNOWN_STILL_SIZES: readonly ['w92', 'w185', 'w300', 'original'];
|
|
364
362
|
type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number];
|
|
365
363
|
type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number];
|
|
366
364
|
type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number];
|
|
367
365
|
type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number];
|
|
368
366
|
type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number];
|
|
369
367
|
type KnownImageSize = KnownBackdropSize | KnownLogoSize | KnownPosterSize | KnownProfileSize | KnownStillSize;
|
|
368
|
+
/** Union of every documented image size. */
|
|
369
|
+
declare const KNOWN_IMAGE_SIZES: readonly KnownImageSize[];
|
|
370
370
|
declare function isKnownBackdropSize(value: string): value is KnownBackdropSize;
|
|
371
371
|
declare function isKnownLogoSize(value: string): value is KnownLogoSize;
|
|
372
372
|
declare function isKnownPosterSize(value: string): value is KnownPosterSize;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#apiKey","#accessToken","#baseUrl","#fetch","#headers","#createUrl","#createHeaders","#resolveFetch","#transport","#transport","#transport","#transform","#transport","#transport","#transport","#transport","#transport","#transport"],"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/configuration.ts","../src/resources/genres.ts","../src/resources/images.ts","../src/resources/movies.ts","../src/resources/people.ts","../src/resources/search.ts","../src/resources/trending.ts","../src/resources/tv.ts","../src/client.ts","../src/search-guards.ts","../src/types.ts"],"sourcesContent":["import type { JsonValue } from './types'\n\n/** Raw TMDB error response body structure. */\nexport interface TMDBErrorResponseBody {\n success?: boolean\n status_code?: number\n status_message?: string\n}\n\n/** Options for constructing a {@link TMDBResponseError} or its subclasses. */\nexport interface TMDBResponseErrorOptions {\n body: JsonValue | undefined\n headers: Headers\n status: number\n statusText: string\n url: string\n}\n\n/** Base class for all SDK-originated errors. */\nexport class TMDBError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBError'\n }\n}\n\n/** Thrown before a request is sent or when fetch itself rejects. */\nexport class TMDBRequestError extends TMDBError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBRequestError'\n }\n}\n\n/** Thrown when TMDB returns a non-2xx response. */\nexport class TMDBResponseError extends TMDBError {\n readonly body: JsonValue | undefined\n readonly headers: Headers\n readonly requestId: string | null\n readonly status: number\n readonly statusCode: number | undefined\n readonly statusMessage: string | undefined\n readonly statusText: string\n readonly url: string\n\n constructor(message: string, options: TMDBResponseErrorOptions) {\n super(message)\n this.name = 'TMDBResponseError'\n this.body = options.body\n this.headers = options.headers\n this.requestId = options.headers.get('x-request-id')\n this.status = options.status\n this.statusText = options.statusText\n this.url = options.url\n\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n this.statusCode = body?.status_code\n this.statusMessage = body?.status_message\n }\n\n /** True when TMDB has asked the caller to back off (HTTP 429). */\n get isRateLimit(): boolean {\n return this.status === 429\n }\n\n /** True when the resource was not found (HTTP 404). */\n get isNotFound(): boolean {\n return this.status === 404\n }\n\n /** True when the request was rejected as unauthenticated (HTTP 401). */\n get isUnauthorized(): boolean {\n return this.status === 401\n }\n\n /** True when the request was rejected as forbidden (HTTP 403). */\n get isForbidden(): boolean {\n return this.status === 403\n }\n\n /** True when the upstream returned a 5xx server error. */\n get isServerError(): boolean {\n return this.status >= 500 && this.status < 600\n }\n}\n\nexport interface TMDBRateLimitErrorOptions extends TMDBResponseErrorOptions {\n /** Seconds to wait before retrying. Parsed from the `Retry-After` header. */\n retryAfter: number\n}\n\n/**\n * Thrown when TMDB returns HTTP 429.\n *\n * The SDK does NOT retry automatically — that decision is left to the\n * caller, since retry policies vary widely. Inspect `retryAfter` to\n * implement your own backoff.\n */\nexport class TMDBRateLimitError extends TMDBResponseError {\n readonly retryAfter: number\n\n constructor(message: string, options: TMDBRateLimitErrorOptions) {\n super(message, options)\n this.name = 'TMDBRateLimitError'\n this.retryAfter = options.retryAfter\n }\n}\n\n/**\n * Create the appropriate error instance for a non-2xx TMDB response.\n *\n * Returns a {@link TMDBRateLimitError} when the status is 429, otherwise\n * a generic {@link TMDBResponseError}. The error message is extracted from\n * the TMDB `status_message` field when available.\n */\nexport function createResponseError(\n options: TMDBResponseErrorOptions,\n): TMDBResponseError {\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n const message = body?.status_message ?? `${options.status} ${options.statusText}`.trim()\n\n if (options.status === 429) {\n return new TMDBRateLimitError(message, {\n ...options,\n retryAfter: parseRetryAfter(options.headers.get('retry-after')),\n })\n }\n\n return new TMDBResponseError(message, options)\n}\n\n/**\n * Parse the `Retry-After` header into seconds. Accepts both delta-seconds\n * (e.g. \"5\") and HTTP-date forms (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\").\n * Falls back to 1 second when the header is missing or unparseable.\n */\nexport function parseRetryAfter(value: string | null | undefined): number {\n if (value === null || value === undefined) {\n return 1\n }\n\n const trimmed = value.trim()\n if (trimmed === '') {\n return 1\n }\n\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return seconds\n }\n\n const date = Date.parse(trimmed)\n if (Number.isFinite(date)) {\n const deltaMs = date - Date.now()\n return Math.max(1, Math.ceil(deltaMs / 1000))\n }\n\n return 1\n}\n\n/** Check if a value has the shape of a TMDB error response body. */\nfunction isErrorResponseBody(value: unknown): value is TMDBErrorResponseBody {\n return typeof value === 'object' && value !== null\n}\n","import { TMDBRequestError } from './errors'\nimport type { ImageSize, RegionCode, LanguageCode, TrendingTimeWindow } from './types'\n\n/** Primitives allowed as query parameter values. */\nexport type QueryPrimitive = string | number | boolean\n\n/** A single query parameter value: primitive, array, or nullish. */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[] | null | undefined\n\n/** Key-value map of query parameters for API requests. */\nexport type QueryParams = Record<string, QueryValue>\n\n/** Default query parameters inherited from the client configuration. */\nexport interface QueryDefaults {\n language?: LanguageCode\n region?: RegionCode\n}\n\nexport const DEFAULT_API_BASE_URL = 'https://api.themoviedb.org/3'\nexport const DEFAULT_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p'\n\n/**\n * Append query parameters to a URL object.\n *\n * - `undefined` and `null` values are skipped.\n * - Arrays are joined with commas (TMDB convention).\n * - All values are converted to strings.\n */\nexport function appendQuery(url: URL, query: QueryParams): void {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','))\n continue\n }\n\n url.searchParams.set(key, String(value))\n }\n}\n\n/**\n * Merge a language query parameter with client defaults.\n *\n * If `query.language` is set it takes precedence; otherwise the client's\n * default language is used.\n */\nexport function withLanguage(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const language = typeof query.language === 'string' ? query.language : defaults.language\n\n return {\n ...query,\n language,\n }\n}\n\n/**\n * Merge language and region defaults for list endpoints.\n *\n * Combines {@link withLanguage} with region fallback from client defaults.\n */\nexport function withListDefaults(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const region = typeof query.region === 'string' ? query.region : defaults.region\n\n return {\n ...withLanguage(defaults, query),\n region,\n }\n}\n\n/**\n * Convert a string or string array to a comma-separated list.\n *\n * Returns `undefined` if the input is `undefined` (skips the parameter).\n * TMDB uses comma-separated values for multi-value query parameters.\n */\nexport function toCommaList(value: string | readonly string[] | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'string' ? value : value.join(',')\n}\n\n/**\n * Validate and convert a numeric ID to a string for use in URL paths.\n *\n * @throws {TMDBRequestError} If `value` is not a positive integer.\n */\nexport function toId(value: number, name: string): string {\n if (!Number.isInteger(value) || value <= 0) {\n throw new TMDBRequestError(`${name} must be a positive integer`)\n }\n\n return String(value)\n}\n\n/**\n * Validate and trim a search query string.\n *\n * @throws {TMDBRequestError} If the query is empty after trimming.\n */\nexport function toSearchQuery(value: string): string {\n const query = value.trim()\n\n if (query.length === 0) {\n throw new TMDBRequestError('search query must not be empty')\n }\n\n return query\n}\n\n/**\n * Validate a trending time window value.\n *\n * @throws {TMDBRequestError} If `value` is not `\"day\"` or `\"week\"`.\n */\nexport function toTimeWindow(value: TrendingTimeWindow): TrendingTimeWindow {\n if (value !== 'day' && value !== 'week') {\n throw new TMDBRequestError('timeWindow must be either \"day\" or \"week\"')\n }\n\n return value\n}\n\nexport interface BuildImageUrlOptions {\n baseUrl?: string\n /**\n * Transform the resolved TMDB image URL before returning it. Use this to\n * route requests through a CDN, image proxy, or to add signatures.\n */\n transform?: (url: string) => string\n}\n\n/**\n * Build a full TMDB image URL from the path returned by API payloads.\n * Returns null for nullish image paths so UI code can branch naturally.\n */\nexport function buildImageUrl(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: BuildImageUrlOptions = {},\n): string | null {\n if (path === undefined || path === null || path.trim() === '') {\n return null\n }\n\n const baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_IMAGE_BASE_URL)\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const url = `${baseUrl}/${size}${normalizedPath}`\n\n return options.transform ? options.transform(url) : url\n}\n\n/**\n * Strip trailing slashes from a base URL to ensure consistent path joining.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n","import { createResponseError, TMDBRequestError } from './errors'\nimport {\n appendQuery,\n DEFAULT_API_BASE_URL,\n DEFAULT_IMAGE_BASE_URL,\n normalizeBaseUrl,\n type QueryDefaults,\n type QueryParams,\n} from './query'\nimport type { ImageUrlTransform } from './resources/images'\nimport type { JsonValue, LanguageCode, RegionCode } from './types'\n\nexport type { ImageUrlTransform }\n\n/**\n * A minimal fetch-like function signature. Any runtime's native `fetch`\n * or a test double conforming to this shape can be used.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface TMDBAccessTokenAuth {\n /** TMDB API Read Access Token. Sent as an Authorization Bearer header. */\n accessToken: string\n apiKey?: never\n}\n\nexport interface TMDBApiKeyAuth {\n /** Legacy v3 API key. Sent as api_key query parameter. */\n apiKey: string\n accessToken?: never\n}\n\nexport type TMDBAuth = TMDBAccessTokenAuth | TMDBApiKeyAuth\n\n/** Internal defaults resolved during client construction. */\nexport interface TMDBClientDefaults extends QueryDefaults {\n imageBaseUrl: string\n}\n\nexport interface TMDBImagesOptions {\n /**\n * Default transform applied to every URL produced by the ImagesHelper.\n * Use this to route TMDB image requests through a CDN, image proxy, or\n * to add signed query parameters. Individual calls can still override it\n * via ImagesHelper.url(path, size, { transform }).\n */\n transform?: ImageUrlTransform\n}\n\nexport type TMDBClientOptions = TMDBAuth & {\n /** Defaults to https://api.themoviedb.org/3. Useful for tests or proxies. */\n baseUrl?: string\n /** Inject a fetch implementation for tests, custom runtimes, or instrumentation. */\n fetch?: FetchLike\n /** Default language for endpoints that accept a language query parameter. */\n defaultLanguage?: LanguageCode\n /** Default region for movie list/search endpoints that accept a region query parameter. */\n defaultRegion?: RegionCode\n /** Custom image host. Defaults to https://image.tmdb.org/t/p. */\n imageBaseUrl?: string\n /** Image-helper configuration: host overrides and URL transforms. */\n images?: TMDBImagesOptions\n /** Additional headers merged into every request before authentication is applied. */\n headers?: HeadersInit\n}\n\n/** Per-request overrides applied when making a single API call. */\nexport interface TMDBRequestOptions {\n headers?: HeadersInit\n query?: QueryParams\n signal?: AbortSignal\n}\n\n/**\n * Transport abstraction for making HTTP requests to the TMDB API.\n *\n * The built-in {@link TMDBHttpClient} implements this interface. You can\n * provide a custom implementation via {@link TMDBFactoryOptions.transport}\n * for testing, caching, or instrumentation.\n */\nexport interface TMDBTransport {\n readonly defaults: TMDBClientDefaults\n get<T>(path: string, options?: TMDBRequestOptions): Promise<T>\n}\n\n/**\n * Built-in HTTP transport that uses the Fetch API.\n *\n * Handles authentication (API key or access token), URL construction,\n * request headers, and response parsing. Use the factory function\n * {@link createTMDB} instead of instantiating this directly.\n */\nexport class TMDBHttpClient implements TMDBTransport {\n readonly defaults: TMDBClientDefaults\n readonly imageTransform: ImageUrlTransform | undefined\n\n readonly #apiKey: string | undefined\n readonly #accessToken: string | undefined\n readonly #baseUrl: string\n readonly #fetch: FetchLike | undefined\n readonly #headers: HeadersInit | undefined\n\n constructor(options: TMDBClientOptions) {\n const accessToken = normalizeSecret('accessToken' in options ? options.accessToken : undefined)\n const apiKey = normalizeSecret('apiKey' in options ? options.apiKey : undefined)\n\n if (Boolean(accessToken) === Boolean(apiKey)) {\n throw new TMDBRequestError('Provide exactly one of accessToken or apiKey')\n }\n\n this.#accessToken = accessToken\n this.#apiKey = apiKey\n this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_API_BASE_URL)\n this.#fetch = options.fetch\n this.#headers = options.headers\n this.defaults = {\n imageBaseUrl: normalizeBaseUrl(options.imageBaseUrl ?? DEFAULT_IMAGE_BASE_URL),\n language: options.defaultLanguage,\n region: options.defaultRegion,\n }\n this.imageTransform = options.images?.transform\n }\n\n async get<T>(path: string, options: TMDBRequestOptions = {}): Promise<T> {\n const url = this.#createUrl(path, options.query ?? {})\n const headers = this.#createHeaders(options.headers)\n const fetchImpl = this.#resolveFetch()\n\n let response: Response\n\n try {\n response = await fetchImpl(url, {\n headers,\n method: 'GET',\n signal: options.signal,\n })\n } catch (error) {\n throw new TMDBRequestError(`TMDB request failed: ${String(error)}`, { cause: error })\n }\n\n const body = await readJson(response)\n\n if (!response.ok) {\n throw createResponseError({\n body,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n url,\n })\n }\n\n return body as T\n }\n\n #resolveFetch(): FetchLike {\n if (this.#fetch !== undefined) {\n return this.#fetch\n }\n\n const globalFetch = globalThis.fetch\n\n if (typeof globalFetch !== 'function') {\n throw new TMDBRequestError('No fetch implementation found. Pass options.fetch in this runtime.')\n }\n\n return globalFetch.bind(globalThis)\n }\n\n #createHeaders(headersInit: HeadersInit | undefined): Headers {\n const headers = new Headers(this.#headers)\n const requestHeaders = new Headers(headersInit)\n\n headers.set('Accept', 'application/json')\n\n for (const [key, value] of requestHeaders) {\n headers.set(key, value)\n }\n\n if (this.#accessToken !== undefined) {\n headers.set('Authorization', `Bearer ${this.#accessToken}`)\n }\n\n return headers\n }\n\n #createUrl(path: string, query: QueryParams): string {\n const relativePath = path.replace(/^\\/+/, '')\n const url = new URL(relativePath, `${this.#baseUrl}/`)\n\n appendQuery(url, {\n ...query,\n api_key: this.#apiKey,\n })\n\n return url.toString()\n }\n}\n\n/**\n * Read and parse a JSON response body.\n *\n * Returns `undefined` for empty responses. If the body is not valid JSON,\n * the raw text string is returned as-is (TMDB occasionally returns plain\n * text for certain error conditions).\n */\nasync function readJson(response: Response): Promise<JsonValue | undefined> {\n const text = await response.text()\n\n if (text.length === 0) {\n return undefined\n }\n\n try {\n return JSON.parse(text) as JsonValue\n } catch {\n return text\n }\n}\n\n/**\n * Normalize a secret value by trimming whitespace and treating empty\n * strings as undefined (not provided).\n */\nfunction normalizeSecret(value: string | undefined): string | undefined {\n const secret = value?.trim()\n return secret === '' ? undefined : secret\n}\n","import type { TMDBTransport } from '../http'\nimport type { Configuration, Country, JobDepartment, Language, Timezone } from '../types'\n\n/**\n * Access TMDB configuration data (image sizes, countries, languages, etc.).\n *\n * Obtained via `client.configuration`.\n */\nexport class ConfigurationResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n details(): Promise<Configuration> {\n return this.#transport.get('/configuration')\n }\n\n countries(): Promise<Country[]> {\n return this.#transport.get('/configuration/countries')\n }\n\n jobs(): Promise<JobDepartment[]> {\n return this.#transport.get('/configuration/jobs')\n }\n\n languages(): Promise<Language[]> {\n return this.#transport.get('/configuration/languages')\n }\n\n primaryTranslations(): Promise<string[]> {\n return this.#transport.get('/configuration/primary_translations')\n }\n\n timezones(): Promise<Timezone[]> {\n return this.#transport.get('/configuration/timezones')\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { withLanguage } from '../query'\nimport type { GenresResponse, LanguageOptions } from '../types'\n\n/**\n * Access TMDB genre lists for movies and TV shows.\n *\n * Obtained via `client.genres`.\n */\nexport class GenresResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/movie/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/tv/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { buildImageUrl } from '../query'\nimport type { ImageSize } from '../types'\n\n/** Function that transforms a TMDB image URL (e.g. for CDN proxying). */\nexport type ImageUrlTransform = (url: string) => string\n\n/**\n * Helper for constructing TMDB image URLs from API path values.\n *\n * Obtained via `client.images`. Supports optional URL transforms for\n * routing image requests through a CDN or proxy.\n */\nexport class ImagesHelper {\n readonly #transport: TMDBTransport\n readonly #transform: ImageUrlTransform | undefined\n\n constructor(transport: TMDBTransport, transform?: ImageUrlTransform) {\n this.#transport = transport\n this.#transform = transform\n }\n\n url(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: { transform?: ImageUrlTransform } = {},\n ): string | null {\n return buildImageUrl(path, size, {\n baseUrl: this.#transport.defaults.imageBaseUrl,\n transform: options.transform ?? this.#transform,\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n ListOptions,\n MovieDetails,\n MovieDetailsOptions,\n MovieSummary,\n PagedResponse,\n TMDBObject,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB movie endpoints (popular, top-rated, details, credits, etc.).\n *\n * Obtained via `client.movies`.\n */\nexport class MoviesResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/popular', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n topRated(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/top_rated', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n nowPlaying(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/now_playing', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n upcoming(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/upcoming', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n movieId: number,\n options: MovieDetailsOptions = {},\n ): Promise<MovieDetails & TAppend> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(movieId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/recommendations`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n similar(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/similar`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n videos(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<VideosResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for movie list endpoints. */\nfunction movieListQuery(transport: TMDBTransport, options: ListOptions): QueryParams {\n return withListDefaults(transport.defaults, {\n language: options.language,\n page: options.page,\n region: options.region,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toId, withLanguage, type QueryParams } from '../query'\nimport type { LanguageOptions, ListOptions, PagedResponse, PersonDetails, PersonSummary } from '../types'\n\n/**\n * Access TMDB person (actor, director, etc.) endpoints.\n *\n * Obtained via `client.people`.\n */\nexport class PeopleResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<PersonSummary>> {\n return this.#transport.get('/person/popular', {\n query: peopleListQuery(this.#transport, options),\n })\n }\n\n details(personId: number, options: LanguageOptions = {}): Promise<PersonDetails> {\n return this.#transport.get(`/person/${toId(personId, 'personId')}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for person list endpoints. */\nfunction peopleListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toSearchQuery, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n MovieSearchOptions,\n MovieSearchResult,\n MultiSearchOptions,\n PagedResponse,\n PersonSearchResult,\n SearchMultiResult,\n TVSearchOptions,\n TVSearchResult,\n} from '../types'\n\n/**\n * Search TMDB for movies, TV shows, people, or all media types.\n *\n * Obtained via `client.search`.\n */\nexport class SearchResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(query: string, options: MovieSearchOptions = {}): Promise<PagedResponse<MovieSearchResult>> {\n return this.#transport.get('/search/movie', {\n query: movieSearchQuery(this.#transport, query, options),\n })\n }\n\n tv(query: string, options: TVSearchOptions = {}): Promise<PagedResponse<TVSearchResult>> {\n return this.#transport.get('/search/tv', {\n query: tvSearchQuery(this.#transport, query, options),\n })\n }\n\n people(query: string, options: MultiSearchOptions = {}): Promise<PagedResponse<PersonSearchResult>> {\n return this.#transport.get('/search/person', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n }\n\n async multi(\n query: string,\n options: MultiSearchOptions = {},\n ): Promise<PagedResponse<SearchMultiResult>> {\n const response = await this.#transport.get<PagedResponse<SearchMultiResult>>('/search/multi', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n\n const excluded = options.exclude\n if (excluded === undefined || excluded.length === 0) {\n return response\n }\n\n const excludedSet = new Set<string>(excluded)\n return {\n ...response,\n results: response.results.filter((result) => !excludedSet.has(result.media_type)),\n }\n }\n}\n\n/** Build query parameters for movie search. */\nfunction movieSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MovieSearchOptions,\n): QueryParams {\n return withListDefaults(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n primary_release_year: options.primaryReleaseYear,\n query: toSearchQuery(query),\n region: options.region,\n year: options.year,\n })\n}\n\n/** Build query parameters for TV search. */\nfunction tvSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: TVSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n first_air_date_year: options.firstAirDateYear,\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n year: options.year,\n })\n}\n\n/** Build query parameters for person and multi-search. */\nfunction commonSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MultiSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toTimeWindow, withLanguage } from '../query'\nimport type {\n LanguageOptions,\n MovieSummary,\n PagedResponse,\n PersonSummary,\n TrendingResult,\n TrendingTimeWindow,\n TVSummary,\n} from '../types'\n\n/**\n * Access TMDB trending content (movies, TV, people) for day/week windows.\n *\n * Obtained via `client.trending`.\n */\nexport class TrendingResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n all(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TrendingResult>> {\n return this.#transport.get(`/trending/all/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n movies(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<MovieSummary & { media_type?: 'movie' }>> {\n return this.#transport.get(`/trending/movie/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TVSummary & { media_type?: 'tv' }>> {\n return this.#transport.get(`/trending/tv/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n people(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<PersonSummary & { media_type?: 'person' }>> {\n return this.#transport.get(`/trending/person/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n LanguageOptions,\n ListOptions,\n PagedResponse,\n TMDBObject,\n TVDetails,\n TVDetailsOptions,\n TVSeasonDetails,\n TVSeasonDetailsOptions,\n TVSummary,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB TV show endpoints (popular, top-rated, details, seasons, etc.).\n *\n * Obtained via `client.tv`.\n */\nexport class TVResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/popular', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n topRated(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/top_rated', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n airingToday(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/airing_today', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n onTheAir(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/on_the_air', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n options: TVDetailsOptions = {},\n ): Promise<TVDetails & TAppend> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(seriesId: number, options: LanguageOptions = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(seriesId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/recommendations`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n similar(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/similar`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n videos(seriesId: number, options: LanguageOptions = {}): Promise<VideosResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n seasonDetails<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n seasonNumber: number,\n options: TVSeasonDetailsOptions = {},\n ): Promise<TVSeasonDetails & TAppend> {\n return this.#transport.get(\n `/tv/${toId(seriesId, 'seriesId')}/season/${toId(seasonNumber, 'seasonNumber')}`,\n {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n },\n )\n }\n}\n\n/** Build query parameters for TV list endpoints. */\nfunction tvListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import { TMDBHttpClient, type TMDBClientOptions, type TMDBRequestOptions, type TMDBTransport } from './http'\nimport { ConfigurationResource } from './resources/configuration'\nimport { GenresResource } from './resources/genres'\nimport { ImagesHelper } from './resources/images'\nimport { MoviesResource } from './resources/movies'\nimport { PeopleResource } from './resources/people'\nimport { SearchResource } from './resources/search'\nimport { TrendingResource } from './resources/trending'\nimport { TVResource } from './resources/tv'\n\n/**\n * Options accepted by {@link createTMDB} and the {@link TMDBClient} constructor.\n *\n * Extends {@link TMDBClientOptions} with an optional {@link TMDBTransport} so\n * callers can plug in a custom transport (typically for tests, caching, or\n * instrumentation) without having to mock `fetch` or the factory itself.\n */\nexport type TMDBFactoryOptions = TMDBClientOptions & {\n transport?: TMDBTransport\n}\n\n/**\n * Main SDK entry point.\n *\n * Resource properties are intentionally small and explicit. The SDK focuses on\n * common TMDB workflows first, while request<T>() keeps uncommon endpoints easy\n * to call without waiting for a generated surface area.\n */\nexport class TMDBClient {\n readonly configuration: ConfigurationResource\n readonly genres: GenresResource\n readonly images: ImagesHelper\n readonly movies: MoviesResource\n readonly people: PeopleResource\n readonly search: SearchResource\n readonly trending: TrendingResource\n readonly tv: TVResource\n\n readonly #transport: TMDBTransport\n\n constructor(options: TMDBFactoryOptions) {\n const { transport, images, ...httpOptions } = options\n // When the caller supplies a custom transport we still want to honor the\n // global images.transform option; otherwise read it back from the HTTP\n // client after it has been constructed.\n const fallbackTransform = images?.transform\n const builtInClient = transport === undefined ? new TMDBHttpClient({ ...httpOptions, images }) : undefined\n this.#transport = builtInClient ?? (transport as TMDBTransport)\n\n this.configuration = new ConfigurationResource(this.#transport)\n this.genres = new GenresResource(this.#transport)\n this.images = new ImagesHelper(\n this.#transport,\n builtInClient ? builtInClient.imageTransform : fallbackTransform,\n )\n this.movies = new MoviesResource(this.#transport)\n this.people = new PeopleResource(this.#transport)\n this.search = new SearchResource(this.#transport)\n this.trending = new TrendingResource(this.#transport)\n this.tv = new TVResource(this.#transport)\n }\n\n /**\n * Make a raw GET request to any TMDB endpoint.\n *\n * This is an escape hatch for endpoints not covered by the typed resource\n * helpers. The `path` should be relative to the API base URL (e.g.\n * `/movie/{id}/credits`). Response is parsed as JSON and cast to `T`.\n *\n * @param path - API path relative to the base URL (e.g. `/movie/123`)\n * @param options - Optional request-level overrides (headers, query, signal)\n * @returns Parsed JSON response typed as `T`\n */\n request<T>(path: string, options?: TMDBRequestOptions): Promise<T> {\n return this.#transport.get<T>(path, options)\n }\n}\n\n/**\n * Create a new {@link TMDBClient} instance.\n *\n * @example\n * ```ts\n * const tmdb = createTMDB({ accessToken: 'YOUR_TOKEN' })\n * const { results } = await tmdb.search.movies('Inception')\n * ```\n *\n * @param options - Authentication and configuration options\n * @returns A configured TMDBClient ready to make API calls\n */\nexport function createTMDB(options: TMDBFactoryOptions): TMDBClient {\n return new TMDBClient(options)\n}\n","import type {\n MovieMultiResult,\n MovieSearchResult,\n PersonMultiResult,\n PersonSearchResult,\n SearchMultiResult,\n TVMultiResult,\n TVSearchResult,\n} from './types'\n\n/**\n * Type guard that narrows a `search.multi()` result to a movie entry.\n *\n * The `media_type` field is required on every `/search/multi` payload by\n * TMDB, so this check is safe at runtime and produces a strictly typed\n * MovieSummary on the narrowed branch.\n */\nexport function isMovieSearchResult(\n result: SearchMultiResult,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a `search.multi()` result to a TV entry. */\nexport function isTVSearchResult(\n result: SearchMultiResult,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a `search.multi()` result to a person entry. */\nexport function isPersonSearchResult(\n result: SearchMultiResult,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/**\n * Convenience alias: `isMovieSearchResult` works on a `search.movies()`\n * result (which already has the narrow type but is also tagged with\n * `media_type?: 'movie'`), as well as on multi-search results.\n */\nexport function isMovie(result: MovieSearchResult | SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a search result to a TV entry. */\nexport function isTV(\n result: TVSearchResult | SearchMultiResult): result is TVMultiResult\nexport function isTV(result: SearchMultiResult): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a search result to a person entry. */\nexport function isPerson(\n result: PersonSearchResult | SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/** Internal helper: check if a value is an object with a matching `media_type` field. */\nfunction isObjectWithMediaType(\n value: unknown,\n mediaType: 'movie' | 'tv' | 'person',\n): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'media_type' in value &&\n (value as { media_type: unknown }).media_type === mediaType\n )\n}\n","/** Primitive JSON values returned by TMDB. */\nexport type JsonPrimitive = string | number | boolean | null\n\n/** JSON object/array tree returned by TMDB for fields this SDK does not model yet. */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[]\n\nexport interface JsonObject {\n [key: string]: JsonValue | undefined\n}\n\n/** Escape hatch for append_to_response payloads and future TMDB fields. */\nexport type TMDBObject = Record<string, unknown>\n\n/** Date string in TMDB format (typically `YYYY-MM-DD`). */\nexport type TMDBDateString = string\n\n/** ISO 639-1 language code (e.g. `\"en\"`, `\"zh\"`). */\nexport type LanguageCode = string\n\n/** ISO 3166-1 country/region code (e.g. `\"US\"`, `\"CN\"`). */\nexport type RegionCode = string\n\n/** Supported media types for multi-search results. */\nexport type MediaType = 'movie' | 'tv' | 'person'\n\n/** Time window for trending endpoints: `\"day\"` or `\"week\"`. */\nexport type TrendingTimeWindow = 'day' | 'week'\n\nexport interface PagedResponse<T> {\n page: number\n results: T[]\n total_pages: number\n total_results: number\n}\n\nexport interface Genre {\n id: number\n name: string\n}\n\nexport interface ProductionCompany {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface ProductionCountry {\n iso_3166_1: string\n name: string\n}\n\nexport interface SpokenLanguage {\n english_name: string\n iso_639_1: string\n name: string\n}\n\nexport interface CollectionSummary {\n id: number\n name: string\n poster_path: string | null\n backdrop_path: string | null\n}\n\nexport interface MovieSummary {\n adult: boolean\n backdrop_path: string | null\n genre_ids: number[]\n id: number\n original_language: string\n original_title: string\n overview: string\n popularity: number\n poster_path: string | null\n release_date: TMDBDateString\n title: string\n video: boolean\n vote_average: number\n vote_count: number\n}\n\nexport interface MovieDetails extends Omit<MovieSummary, 'genre_ids'> {\n belongs_to_collection: CollectionSummary | null\n budget: number\n genres: Genre[]\n homepage: string | null\n imdb_id: string | null\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n revenue: number\n runtime: number | null\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n}\n\nexport interface TVSummary {\n adult?: boolean\n backdrop_path: string | null\n first_air_date: TMDBDateString\n genre_ids: number[]\n id: number\n name: string\n origin_country: string[]\n original_language: string\n original_name: string\n overview: string\n popularity: number\n poster_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface CreatedBy {\n id: number\n credit_id: string\n name: string\n gender: number\n profile_path: string | null\n}\n\nexport interface Network {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface SeasonSummary {\n air_date: TMDBDateString | null\n episode_count: number\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport interface EpisodeGuestStar {\n adult: boolean\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface EpisodeSummary {\n air_date: TMDBDateString | null\n crew: CreditCrewMember[]\n episode_number: number\n episode_type: string\n guest_stars: EpisodeGuestStar[]\n id: number\n name: string\n overview: string\n production_code: string | null\n runtime: number | null\n season_number: number\n show_id: number\n still_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface TVSeasonDetails {\n _id: string\n air_date: TMDBDateString | null\n episodes: EpisodeSummary[]\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport type TVSeasonAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'translations'\n | 'videos'\n | (string & {})\n\nexport interface TVSeasonDetailsOptions extends LanguageOptions {\n appendToResponse?: TVSeasonAppendToResponse | readonly TVSeasonAppendToResponse[]\n}\n\nexport interface TVDetails extends Omit<TVSummary, 'genre_ids'> {\n created_by: CreatedBy[]\n episode_run_time: number[]\n genres: Genre[]\n homepage: string | null\n in_production: boolean\n languages: string[]\n last_air_date: TMDBDateString | null\n networks: Network[]\n number_of_episodes: number\n number_of_seasons: number\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n seasons: SeasonSummary[]\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n type: string\n}\n\nexport interface PersonKnownForMovie extends MovieSummary {\n media_type: 'movie'\n}\n\nexport interface PersonKnownForTV extends TVSummary {\n media_type: 'tv'\n}\n\nexport type PersonKnownFor = PersonKnownForMovie | PersonKnownForTV\n\nexport interface PersonSummary {\n adult: boolean\n gender: number\n id: number\n known_for: PersonKnownFor[]\n known_for_department: string\n name: string\n original_name?: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface PersonDetails extends Omit<PersonSummary, 'known_for'> {\n also_known_as: string[]\n biography: string\n birthday: TMDBDateString | null\n deathday: TMDBDateString | null\n homepage: string | null\n imdb_id: string | null\n place_of_birth: string | null\n}\n\nexport interface MovieSearchResult extends MovieSummary {\n media_type?: 'movie'\n}\n\nexport interface TVSearchResult extends TVSummary {\n media_type?: 'tv'\n}\n\nexport interface PersonSearchResult extends PersonSummary {\n media_type?: 'person'\n}\n\nexport type SearchMultiResult =\n | (MovieSummary & { media_type: 'movie' })\n | (TVSummary & { media_type: 'tv' })\n | (PersonSummary & { media_type: 'person' })\n\n/** A single multi-search result narrowed to a specific media type. */\nexport type MovieMultiResult = MovieSummary & { media_type: 'movie' }\nexport type TVMultiResult = TVSummary & { media_type: 'tv' }\nexport type PersonMultiResult = PersonSummary & { media_type: 'person' }\n\nexport type TrendingResult = SearchMultiResult\n\nexport interface CreditCastMember {\n adult?: boolean\n cast_id?: number\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditCrewMember {\n adult?: boolean\n credit_id: string\n department: string\n gender: number | null\n id: number\n job: string\n known_for_department: string\n name: string\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditsResponse {\n id: number\n cast: CreditCastMember[]\n crew: CreditCrewMember[]\n}\n\nexport interface Video {\n id: string\n iso_3166_1: string\n iso_639_1: string\n key: string\n name: string\n official: boolean\n published_at: string\n site: string\n size: number\n type: string\n}\n\nexport interface VideosResponse {\n id: number\n results: Video[]\n}\n\nexport interface ImageItem {\n aspect_ratio: number\n height: number\n iso_639_1: string | null\n file_path: string\n vote_average: number\n vote_count: number\n width: number\n}\n\nexport interface ImagesResponse {\n id: number\n backdrops: ImageItem[]\n logos?: ImageItem[]\n posters: ImageItem[]\n}\n\nexport interface ConfigurationImages {\n base_url: string\n secure_base_url: string\n backdrop_sizes: string[]\n logo_sizes: string[]\n poster_sizes: string[]\n profile_sizes: string[]\n still_sizes: string[]\n}\n\nexport interface Configuration {\n images: ConfigurationImages\n change_keys: string[]\n}\n\nexport interface Country {\n iso_3166_1: string\n english_name: string\n native_name: string\n}\n\nexport interface Language {\n iso_639_1: string\n english_name: string\n name: string\n}\n\nexport interface Timezone {\n iso_3166_1: string\n zones: string[]\n}\n\nexport interface JobDepartment {\n department: string\n jobs: string[]\n}\n\nexport interface GenresResponse {\n genres: Genre[]\n}\n\nexport type BackdropSize = 'w300' | 'w780' | 'w1280' | 'original' | (string & {})\nexport type LogoSize = 'w45' | 'w92' | 'w154' | 'w185' | 'w300' | 'w500' | 'original' | (string & {})\nexport type PosterSize = 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original' | (string & {})\nexport type ProfileSize = 'w45' | 'w185' | 'h632' | 'original' | (string & {})\nexport type StillSize = 'w92' | 'w185' | 'w300' | 'original' | (string & {})\nexport type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize\n\n/**\n * Public set of image sizes TMDB currently documents. The SDK does not\n * pin to a static copy of the TMDB docs — TMDB has added new sizes in\n * the past (e.g. `h632` for profile) without notice — but exposing the\n * canonical list lets callers:\n *\n * - iterate over the set to build a size picker\n * - validate user-supplied sizes with `isKnownBackdropSize(...)` etc.\n * - type a variable as a \"known\" size without giving up the\n * `(string & {})` escape hatch for forward-compatibility\n *\n * If TMDB publishes a new size, the SDK will still accept it at runtime\n * (every helper is `(string & {})` permissive), but you will need to\n * add the literal to these constants to get autocomplete on it.\n */\nexport const KNOWN_BACKDROP_SIZES = Object.freeze(['w300', 'w780', 'w1280', 'original'] as const)\nexport const KNOWN_LOGO_SIZES = Object.freeze([\n 'w45',\n 'w92',\n 'w154',\n 'w185',\n 'w300',\n 'w500',\n 'original',\n] as const)\nexport const KNOWN_POSTER_SIZES = Object.freeze([\n 'w92',\n 'w154',\n 'w185',\n 'w342',\n 'w500',\n 'w780',\n 'original',\n] as const)\nexport const KNOWN_PROFILE_SIZES = Object.freeze(['w45', 'w185', 'h632', 'original'] as const)\nexport const KNOWN_STILL_SIZES = Object.freeze(['w92', 'w185', 'w300', 'original'] as const)\n\n/** Union of every documented image size. */\nexport const KNOWN_IMAGE_SIZES = Object.freeze([\n ...KNOWN_BACKDROP_SIZES,\n ...KNOWN_LOGO_SIZES,\n ...KNOWN_POSTER_SIZES,\n ...KNOWN_PROFILE_SIZES,\n ...KNOWN_STILL_SIZES,\n] as const)\n\nexport type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number]\nexport type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number]\nexport type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number]\nexport type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number]\nexport type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number]\nexport type KnownImageSize =\n | KnownBackdropSize\n | KnownLogoSize\n | KnownPosterSize\n | KnownProfileSize\n | KnownStillSize\n\n/** O(1) membership check backed by a Set. */\nconst KNOWN_BACKDROP_SET: ReadonlySet<string> = new Set(KNOWN_BACKDROP_SIZES)\nconst KNOWN_LOGO_SET: ReadonlySet<string> = new Set(KNOWN_LOGO_SIZES)\nconst KNOWN_POSTER_SET: ReadonlySet<string> = new Set(KNOWN_POSTER_SIZES)\nconst KNOWN_PROFILE_SET: ReadonlySet<string> = new Set(KNOWN_PROFILE_SIZES)\nconst KNOWN_STILL_SET: ReadonlySet<string> = new Set(KNOWN_STILL_SIZES)\nconst KNOWN_IMAGE_SET: ReadonlySet<string> = new Set(KNOWN_IMAGE_SIZES)\n\nexport function isKnownBackdropSize(value: string): value is KnownBackdropSize {\n return KNOWN_BACKDROP_SET.has(value)\n}\n\nexport function isKnownLogoSize(value: string): value is KnownLogoSize {\n return KNOWN_LOGO_SET.has(value)\n}\n\nexport function isKnownPosterSize(value: string): value is KnownPosterSize {\n return KNOWN_POSTER_SET.has(value)\n}\n\nexport function isKnownProfileSize(value: string): value is KnownProfileSize {\n return KNOWN_PROFILE_SET.has(value)\n}\n\nexport function isKnownStillSize(value: string): value is KnownStillSize {\n return KNOWN_STILL_SET.has(value)\n}\n\n/** True if `value` is in any documented size set. */\nexport function isKnownImageSize(value: string): value is KnownImageSize {\n return KNOWN_IMAGE_SET.has(value)\n}\n\nexport type MovieAppendToResponse =\n | 'account_states'\n | 'alternative_titles'\n | 'changes'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'lists'\n | 'recommendations'\n | 'release_dates'\n | 'reviews'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport type TVAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'alternative_titles'\n | 'changes'\n | 'content_ratings'\n | 'credits'\n | 'episode_groups'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'recommendations'\n | 'reviews'\n | 'screened_theatrically'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport interface ListOptions {\n language?: LanguageCode\n page?: number\n region?: RegionCode\n}\n\nexport interface LanguageOptions {\n language?: LanguageCode\n}\n\nexport interface MovieDetailsOptions extends LanguageOptions {\n appendToResponse?: MovieAppendToResponse | readonly MovieAppendToResponse[]\n}\n\nexport interface TVDetailsOptions extends LanguageOptions {\n appendToResponse?: TVAppendToResponse | readonly TVAppendToResponse[]\n}\n\nexport interface MovieSearchOptions extends ListOptions {\n includeAdult?: boolean\n primaryReleaseYear?: string | number\n year?: string | number\n}\n\nexport interface TVSearchOptions extends Omit<ListOptions, 'region'> {\n firstAirDateYear?: string | number\n includeAdult?: boolean\n year?: string | number\n}\n\nexport interface MultiSearchOptions extends Omit<ListOptions, 'region'> {\n includeAdult?: boolean\n /**\n * Media types to exclude from a `search.multi()` response. Filtering is\n * performed client-side because the TMDB multi-search endpoint does not\n * support a server-side media_type filter.\n */\n exclude?: ReadonlyArray<MediaType>\n}\n\nexport interface ImageQueryOptions extends LanguageOptions {\n includeImageLanguage?: string | readonly string[]\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#apiKey","#accessToken","#baseUrl","#fetch","#headers","#createUrl","#createHeaders","#resolveFetch","#transport","#transport","#transport","#transform","#transport","#transport","#transport","#transport","#transport","#transport"],"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/configuration.ts","../src/resources/genres.ts","../src/resources/images.ts","../src/resources/movies.ts","../src/resources/people.ts","../src/resources/search.ts","../src/resources/trending.ts","../src/resources/tv.ts","../src/client.ts","../src/search-guards.ts","../src/types.ts"],"sourcesContent":["import type { JsonValue } from './types'\n\n/** Raw TMDB error response body structure. */\nexport interface TMDBErrorResponseBody {\n success?: boolean\n status_code?: number\n status_message?: string\n}\n\n/** Options for constructing a {@link TMDBResponseError} or its subclasses. */\nexport interface TMDBResponseErrorOptions {\n body: JsonValue | undefined\n headers: Headers\n status: number\n statusText: string\n url: string\n}\n\n/** Base class for all SDK-originated errors. */\nexport class TMDBError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBError'\n }\n}\n\n/** Thrown before a request is sent or when fetch itself rejects. */\nexport class TMDBRequestError extends TMDBError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = 'TMDBRequestError'\n }\n}\n\n/** Thrown when TMDB returns a non-2xx response. */\nexport class TMDBResponseError extends TMDBError {\n readonly body: JsonValue | undefined\n readonly headers: Headers\n readonly requestId: string | null\n readonly status: number\n readonly statusCode: number | undefined\n readonly statusMessage: string | undefined\n readonly statusText: string\n readonly url: string\n\n constructor(message: string, options: TMDBResponseErrorOptions) {\n super(message)\n this.name = 'TMDBResponseError'\n this.body = options.body\n this.headers = options.headers\n this.requestId = options.headers.get('x-request-id')\n this.status = options.status\n this.statusText = options.statusText\n this.url = options.url\n\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n this.statusCode = body?.status_code\n this.statusMessage = body?.status_message\n }\n\n /** True when TMDB has asked the caller to back off (HTTP 429). */\n get isRateLimit(): boolean {\n return this.status === 429\n }\n\n /** True when the resource was not found (HTTP 404). */\n get isNotFound(): boolean {\n return this.status === 404\n }\n\n /** True when the request was rejected as unauthenticated (HTTP 401). */\n get isUnauthorized(): boolean {\n return this.status === 401\n }\n\n /** True when the request was rejected as forbidden (HTTP 403). */\n get isForbidden(): boolean {\n return this.status === 403\n }\n\n /** True when the upstream returned a 5xx server error. */\n get isServerError(): boolean {\n return this.status >= 500 && this.status < 600\n }\n}\n\nexport interface TMDBRateLimitErrorOptions extends TMDBResponseErrorOptions {\n /** Seconds to wait before retrying. Parsed from the `Retry-After` header. */\n retryAfter: number\n}\n\n/**\n * Thrown when TMDB returns HTTP 429.\n *\n * The SDK does NOT retry automatically — that decision is left to the\n * caller, since retry policies vary widely. Inspect `retryAfter` to\n * implement your own backoff.\n */\nexport class TMDBRateLimitError extends TMDBResponseError {\n readonly retryAfter: number\n\n constructor(message: string, options: TMDBRateLimitErrorOptions) {\n super(message, options)\n this.name = 'TMDBRateLimitError'\n this.retryAfter = options.retryAfter\n }\n}\n\n/**\n * Create the appropriate error instance for a non-2xx TMDB response.\n *\n * Returns a {@link TMDBRateLimitError} when the status is 429, otherwise\n * a generic {@link TMDBResponseError}. The error message is extracted from\n * the TMDB `status_message` field when available.\n */\nexport function createResponseError(\n options: TMDBResponseErrorOptions,\n): TMDBResponseError {\n const body = isErrorResponseBody(options.body) ? options.body : undefined\n const message = body?.status_message ?? `${options.status} ${options.statusText}`.trim()\n\n if (options.status === 429) {\n return new TMDBRateLimitError(message, {\n ...options,\n retryAfter: parseRetryAfter(options.headers.get('retry-after')),\n })\n }\n\n return new TMDBResponseError(message, options)\n}\n\n/**\n * Parse the `Retry-After` header into seconds. Accepts both delta-seconds\n * (e.g. \"5\") and HTTP-date forms (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\").\n * Falls back to 1 second when the header is missing or unparseable.\n */\nexport function parseRetryAfter(value: string | null | undefined): number {\n if (value === null || value === undefined) {\n return 1\n }\n\n const trimmed = value.trim()\n if (trimmed === '') {\n return 1\n }\n\n const seconds = Number(trimmed)\n if (Number.isFinite(seconds) && seconds >= 0) {\n return seconds\n }\n\n const date = Date.parse(trimmed)\n if (Number.isFinite(date)) {\n const deltaMs = date - Date.now()\n return Math.max(1, Math.ceil(deltaMs / 1000))\n }\n\n return 1\n}\n\n/** Check if a value has the shape of a TMDB error response body. */\nfunction isErrorResponseBody(value: unknown): value is TMDBErrorResponseBody {\n return typeof value === 'object' && value !== null\n}\n","import { TMDBRequestError } from './errors'\nimport type { ImageSize, RegionCode, LanguageCode, TrendingTimeWindow } from './types'\n\n/** Primitives allowed as query parameter values. */\nexport type QueryPrimitive = string | number | boolean\n\n/** A single query parameter value: primitive, array, or nullish. */\nexport type QueryValue = QueryPrimitive | readonly QueryPrimitive[] | null | undefined\n\n/** Key-value map of query parameters for API requests. */\nexport type QueryParams = Record<string, QueryValue>\n\n/** Default query parameters inherited from the client configuration. */\nexport interface QueryDefaults {\n language?: LanguageCode\n region?: RegionCode\n}\n\nexport const DEFAULT_API_BASE_URL = 'https://api.themoviedb.org/3'\nexport const DEFAULT_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p'\n\n/**\n * Append query parameters to a URL object.\n *\n * - `undefined` and `null` values are skipped.\n * - Arrays are joined with commas (TMDB convention).\n * - All values are converted to strings.\n */\nexport function appendQuery(url: URL, query: QueryParams): void {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue\n }\n\n if (Array.isArray(value)) {\n url.searchParams.set(key, value.map(String).join(','))\n continue\n }\n\n url.searchParams.set(key, String(value))\n }\n}\n\n/**\n * Merge a language query parameter with client defaults.\n *\n * If `query.language` is set it takes precedence; otherwise the client's\n * default language is used.\n */\nexport function withLanguage(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const language = typeof query.language === 'string' ? query.language : defaults.language\n\n return {\n ...query,\n language,\n }\n}\n\n/**\n * Merge language and region defaults for list endpoints.\n *\n * Combines {@link withLanguage} with region fallback from client defaults.\n */\nexport function withListDefaults(\n defaults: QueryDefaults,\n query: QueryParams,\n): QueryParams {\n const region = typeof query.region === 'string' ? query.region : defaults.region\n\n return {\n ...withLanguage(defaults, query),\n region,\n }\n}\n\n/**\n * Convert a string or string array to a comma-separated list.\n *\n * Returns `undefined` if the input is `undefined` (skips the parameter).\n * TMDB uses comma-separated values for multi-value query parameters.\n */\nexport function toCommaList(value: string | readonly string[] | undefined): string | undefined {\n if (value === undefined) {\n return undefined\n }\n\n return typeof value === 'string' ? value : value.join(',')\n}\n\n/**\n * Validate and convert a numeric ID to a string for use in URL paths.\n *\n * @throws {TMDBRequestError} If `value` is not a positive integer.\n */\nexport function toId(value: number, name: string): string {\n if (!Number.isInteger(value) || value <= 0) {\n throw new TMDBRequestError(`${name} must be a positive integer`)\n }\n\n return String(value)\n}\n\n/**\n * Validate and trim a search query string.\n *\n * @throws {TMDBRequestError} If the query is empty after trimming.\n */\nexport function toSearchQuery(value: string): string {\n const query = value.trim()\n\n if (query.length === 0) {\n throw new TMDBRequestError('search query must not be empty')\n }\n\n return query\n}\n\n/**\n * Validate a trending time window value.\n *\n * @throws {TMDBRequestError} If `value` is not `\"day\"` or `\"week\"`.\n */\nexport function toTimeWindow(value: TrendingTimeWindow): TrendingTimeWindow {\n if (value !== 'day' && value !== 'week') {\n throw new TMDBRequestError('timeWindow must be either \"day\" or \"week\"')\n }\n\n return value\n}\n\nexport interface BuildImageUrlOptions {\n baseUrl?: string\n /**\n * Transform the resolved TMDB image URL before returning it. Use this to\n * route requests through a CDN, image proxy, or to add signatures.\n */\n transform?: (url: string) => string\n}\n\n/**\n * Build a full TMDB image URL from the path returned by API payloads.\n * Returns null for nullish image paths so UI code can branch naturally.\n */\nexport function buildImageUrl(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: BuildImageUrlOptions = {},\n): string | null {\n if (path === undefined || path === null || path.trim() === '') {\n return null\n }\n\n const baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_IMAGE_BASE_URL)\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const url = `${baseUrl}/${size}${normalizedPath}`\n\n return options.transform ? options.transform(url) : url\n}\n\n/**\n * Strip trailing slashes from a base URL to ensure consistent path joining.\n */\nexport function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '')\n}\n","import { createResponseError, TMDBRequestError } from './errors'\nimport {\n appendQuery,\n DEFAULT_API_BASE_URL,\n DEFAULT_IMAGE_BASE_URL,\n normalizeBaseUrl,\n type QueryDefaults,\n type QueryParams,\n} from './query'\nimport type { ImageUrlTransform } from './resources/images'\nimport type { JsonValue, LanguageCode, RegionCode } from './types'\n\nexport type { ImageUrlTransform }\n\n/**\n * A minimal fetch-like function signature. Any runtime's native `fetch`\n * or a test double conforming to this shape can be used.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>\n\nexport interface TMDBAccessTokenAuth {\n /** TMDB API Read Access Token. Sent as an Authorization Bearer header. */\n accessToken: string\n apiKey?: never\n}\n\nexport interface TMDBApiKeyAuth {\n /** Legacy v3 API key. Sent as api_key query parameter. */\n apiKey: string\n accessToken?: never\n}\n\nexport type TMDBAuth = TMDBAccessTokenAuth | TMDBApiKeyAuth\n\n/** Internal defaults resolved during client construction. */\nexport interface TMDBClientDefaults extends QueryDefaults {\n imageBaseUrl: string\n}\n\nexport interface TMDBImagesOptions {\n /**\n * Default transform applied to every URL produced by the ImagesHelper.\n * Use this to route TMDB image requests through a CDN, image proxy, or\n * to add signed query parameters. Individual calls can still override it\n * via ImagesHelper.url(path, size, { transform }).\n */\n transform?: ImageUrlTransform\n}\n\nexport type TMDBClientOptions = TMDBAuth & {\n /** Defaults to https://api.themoviedb.org/3. Useful for tests or proxies. */\n baseUrl?: string\n /** Inject a fetch implementation for tests, custom runtimes, or instrumentation. */\n fetch?: FetchLike\n /** Default language for endpoints that accept a language query parameter. */\n defaultLanguage?: LanguageCode\n /** Default region for movie list/search endpoints that accept a region query parameter. */\n defaultRegion?: RegionCode\n /** Custom image host. Defaults to https://image.tmdb.org/t/p. */\n imageBaseUrl?: string\n /** Image-helper configuration: host overrides and URL transforms. */\n images?: TMDBImagesOptions\n /** Additional headers merged into every request before authentication is applied. */\n headers?: HeadersInit\n}\n\n/** Per-request overrides applied when making a single API call. */\nexport interface TMDBRequestOptions {\n headers?: HeadersInit\n query?: QueryParams\n signal?: AbortSignal\n}\n\n/**\n * Transport abstraction for making HTTP requests to the TMDB API.\n *\n * The built-in {@link TMDBHttpClient} implements this interface. You can\n * provide a custom implementation via {@link TMDBFactoryOptions.transport}\n * for testing, caching, or instrumentation.\n */\nexport interface TMDBTransport {\n readonly defaults: TMDBClientDefaults\n get<T>(path: string, options?: TMDBRequestOptions): Promise<T>\n}\n\n/**\n * Built-in HTTP transport that uses the Fetch API.\n *\n * Handles authentication (API key or access token), URL construction,\n * request headers, and response parsing. Use the factory function\n * {@link createTMDB} instead of instantiating this directly.\n */\nexport class TMDBHttpClient implements TMDBTransport {\n readonly defaults: TMDBClientDefaults\n readonly imageTransform: ImageUrlTransform | undefined\n\n readonly #apiKey: string | undefined\n readonly #accessToken: string | undefined\n readonly #baseUrl: string\n readonly #fetch: FetchLike | undefined\n readonly #headers: HeadersInit | undefined\n\n constructor(options: TMDBClientOptions) {\n const accessToken = normalizeSecret('accessToken' in options ? options.accessToken : undefined)\n const apiKey = normalizeSecret('apiKey' in options ? options.apiKey : undefined)\n\n if (Boolean(accessToken) === Boolean(apiKey)) {\n throw new TMDBRequestError('Provide exactly one of accessToken or apiKey')\n }\n\n this.#accessToken = accessToken\n this.#apiKey = apiKey\n this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_API_BASE_URL)\n this.#fetch = options.fetch\n this.#headers = options.headers\n this.defaults = {\n imageBaseUrl: normalizeBaseUrl(options.imageBaseUrl ?? DEFAULT_IMAGE_BASE_URL),\n language: options.defaultLanguage,\n region: options.defaultRegion,\n }\n this.imageTransform = options.images?.transform\n }\n\n async get<T>(path: string, options: TMDBRequestOptions = {}): Promise<T> {\n const url = this.#createUrl(path, options.query ?? {})\n const headers = this.#createHeaders(options.headers)\n const fetchImpl = this.#resolveFetch()\n\n let response: Response\n\n try {\n response = await fetchImpl(url, {\n headers,\n method: 'GET',\n signal: options.signal,\n })\n } catch (error) {\n throw new TMDBRequestError(`TMDB request failed: ${String(error)}`, { cause: error })\n }\n\n const body = await readJson(response)\n\n if (!response.ok) {\n throw createResponseError({\n body,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n url,\n })\n }\n\n return body as T\n }\n\n #resolveFetch(): FetchLike {\n if (this.#fetch !== undefined) {\n return this.#fetch\n }\n\n const globalFetch = globalThis.fetch\n\n if (typeof globalFetch !== 'function') {\n throw new TMDBRequestError('No fetch implementation found. Pass options.fetch in this runtime.')\n }\n\n return globalFetch.bind(globalThis)\n }\n\n #createHeaders(headersInit: HeadersInit | undefined): Headers {\n const headers = new Headers(this.#headers)\n const requestHeaders = new Headers(headersInit)\n\n headers.set('Accept', 'application/json')\n\n for (const [key, value] of requestHeaders) {\n headers.set(key, value)\n }\n\n if (this.#accessToken !== undefined) {\n headers.set('Authorization', `Bearer ${this.#accessToken}`)\n }\n\n return headers\n }\n\n #createUrl(path: string, query: QueryParams): string {\n const relativePath = path.replace(/^\\/+/, '')\n const url = new URL(relativePath, `${this.#baseUrl}/`)\n\n appendQuery(url, {\n ...query,\n api_key: this.#apiKey,\n })\n\n return url.toString()\n }\n}\n\n/**\n * Read and parse a JSON response body.\n *\n * Returns `undefined` for empty responses. If the body is not valid JSON,\n * the raw text string is returned as-is (TMDB occasionally returns plain\n * text for certain error conditions).\n */\nasync function readJson(response: Response): Promise<JsonValue | undefined> {\n const text = await response.text()\n\n if (text.length === 0) {\n return undefined\n }\n\n try {\n return JSON.parse(text) as JsonValue\n } catch {\n return text\n }\n}\n\n/**\n * Normalize a secret value by trimming whitespace and treating empty\n * strings as undefined (not provided).\n */\nfunction normalizeSecret(value: string | undefined): string | undefined {\n const secret = value?.trim()\n return secret === '' ? undefined : secret\n}\n","import type { TMDBTransport } from '../http'\nimport type { Configuration, Country, JobDepartment, Language, Timezone } from '../types'\n\n/**\n * Access TMDB configuration data (image sizes, countries, languages, etc.).\n *\n * Obtained via `client.configuration`.\n */\nexport class ConfigurationResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n details(): Promise<Configuration> {\n return this.#transport.get('/configuration')\n }\n\n countries(): Promise<Country[]> {\n return this.#transport.get('/configuration/countries')\n }\n\n jobs(): Promise<JobDepartment[]> {\n return this.#transport.get('/configuration/jobs')\n }\n\n languages(): Promise<Language[]> {\n return this.#transport.get('/configuration/languages')\n }\n\n primaryTranslations(): Promise<string[]> {\n return this.#transport.get('/configuration/primary_translations')\n }\n\n timezones(): Promise<Timezone[]> {\n return this.#transport.get('/configuration/timezones')\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { withLanguage } from '../query'\nimport type { GenresResponse, LanguageOptions } from '../types'\n\n/**\n * Access TMDB genre lists for movies and TV shows.\n *\n * Obtained via `client.genres`.\n */\nexport class GenresResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/movie/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(options: LanguageOptions = {}): Promise<GenresResponse> {\n return this.#transport.get('/genre/tv/list', {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { buildImageUrl } from '../query'\nimport type { ImageSize } from '../types'\n\n/** Function that transforms a TMDB image URL (e.g. for CDN proxying). */\nexport type ImageUrlTransform = (url: string) => string\n\n/**\n * Helper for constructing TMDB image URLs from API path values.\n *\n * Obtained via `client.images`. Supports optional URL transforms for\n * routing image requests through a CDN or proxy.\n */\nexport class ImagesHelper {\n readonly #transport: TMDBTransport\n readonly #transform: ImageUrlTransform | undefined\n\n constructor(transport: TMDBTransport, transform?: ImageUrlTransform) {\n this.#transport = transport\n this.#transform = transform\n }\n\n url(\n path: string | null | undefined,\n size: ImageSize = 'original',\n options: { transform?: ImageUrlTransform } = {},\n ): string | null {\n return buildImageUrl(path, size, {\n baseUrl: this.#transport.defaults.imageBaseUrl,\n transform: options.transform ?? this.#transform,\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n ListOptions,\n MovieDetails,\n MovieDetailsOptions,\n MovieSummary,\n PagedResponse,\n TMDBObject,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB movie endpoints (popular, top-rated, details, credits, etc.).\n *\n * Obtained via `client.movies`.\n */\nexport class MoviesResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/popular', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n topRated(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/top_rated', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n nowPlaying(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/now_playing', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n upcoming(options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get('/movie/upcoming', {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n movieId: number,\n options: MovieDetailsOptions = {},\n ): Promise<MovieDetails & TAppend> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(movieId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/recommendations`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n similar(movieId: number, options: ListOptions = {}): Promise<PagedResponse<MovieSummary>> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/similar`, {\n query: movieListQuery(this.#transport, options),\n })\n }\n\n videos(movieId: number, options: Pick<ListOptions, 'language'> = {}): Promise<VideosResponse> {\n return this.#transport.get(`/movie/${toId(movieId, 'movieId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for movie list endpoints. */\nfunction movieListQuery(transport: TMDBTransport, options: ListOptions): QueryParams {\n return withListDefaults(transport.defaults, {\n language: options.language,\n page: options.page,\n region: options.region,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toId, withLanguage, type QueryParams } from '../query'\nimport type { LanguageOptions, ListOptions, PagedResponse, PersonDetails, PersonSummary } from '../types'\n\n/**\n * Access TMDB person (actor, director, etc.) endpoints.\n *\n * Obtained via `client.people`.\n */\nexport class PeopleResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<PersonSummary>> {\n return this.#transport.get('/person/popular', {\n query: peopleListQuery(this.#transport, options),\n })\n }\n\n details(personId: number, options: LanguageOptions = {}): Promise<PersonDetails> {\n return this.#transport.get(`/person/${toId(personId, 'personId')}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n\n/** Build query parameters for person list endpoints. */\nfunction peopleListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toSearchQuery, withLanguage, withListDefaults, type QueryParams } from '../query'\nimport type {\n MovieSearchOptions,\n MovieSearchResult,\n MultiSearchOptions,\n PagedResponse,\n PersonSearchResult,\n SearchMultiResult,\n TVSearchOptions,\n TVSearchResult,\n} from '../types'\n\n/**\n * Search TMDB for movies, TV shows, people, or all media types.\n *\n * Obtained via `client.search`.\n */\nexport class SearchResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n movies(query: string, options: MovieSearchOptions = {}): Promise<PagedResponse<MovieSearchResult>> {\n return this.#transport.get('/search/movie', {\n query: movieSearchQuery(this.#transport, query, options),\n })\n }\n\n tv(query: string, options: TVSearchOptions = {}): Promise<PagedResponse<TVSearchResult>> {\n return this.#transport.get('/search/tv', {\n query: tvSearchQuery(this.#transport, query, options),\n })\n }\n\n people(query: string, options: MultiSearchOptions = {}): Promise<PagedResponse<PersonSearchResult>> {\n return this.#transport.get('/search/person', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n }\n\n async multi(\n query: string,\n options: MultiSearchOptions = {},\n ): Promise<PagedResponse<SearchMultiResult>> {\n const response = await this.#transport.get<PagedResponse<SearchMultiResult>>('/search/multi', {\n query: commonSearchQuery(this.#transport, query, options),\n })\n\n const excluded = options.exclude\n if (excluded === undefined || excluded.length === 0) {\n return response\n }\n\n const excludedSet = new Set<string>(excluded)\n return {\n ...response,\n results: response.results.filter((result) => !excludedSet.has(result.media_type)),\n }\n }\n}\n\n/** Build query parameters for movie search. */\nfunction movieSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MovieSearchOptions,\n): QueryParams {\n return withListDefaults(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n primary_release_year: options.primaryReleaseYear,\n query: toSearchQuery(query),\n region: options.region,\n year: options.year,\n })\n}\n\n/** Build query parameters for TV search. */\nfunction tvSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: TVSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n first_air_date_year: options.firstAirDateYear,\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n year: options.year,\n })\n}\n\n/** Build query parameters for person and multi-search. */\nfunction commonSearchQuery(\n transport: TMDBTransport,\n query: string,\n options: MultiSearchOptions,\n): QueryParams {\n return withLanguage(transport.defaults, {\n include_adult: options.includeAdult,\n language: options.language,\n page: options.page,\n query: toSearchQuery(query),\n })\n}\n","import type { TMDBTransport } from '../http'\nimport { toTimeWindow, withLanguage } from '../query'\nimport type {\n LanguageOptions,\n MovieSummary,\n PagedResponse,\n PersonSummary,\n TrendingResult,\n TrendingTimeWindow,\n TVSummary,\n} from '../types'\n\n/**\n * Access TMDB trending content (movies, TV, people) for day/week windows.\n *\n * Obtained via `client.trending`.\n */\nexport class TrendingResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n all(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TrendingResult>> {\n return this.#transport.get(`/trending/all/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n movies(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<MovieSummary & { media_type?: 'movie' }>> {\n return this.#transport.get(`/trending/movie/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n tv(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<TVSummary & { media_type?: 'tv' }>> {\n return this.#transport.get(`/trending/tv/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n people(\n timeWindow: TrendingTimeWindow = 'day',\n options: LanguageOptions = {},\n ): Promise<PagedResponse<PersonSummary & { media_type?: 'person' }>> {\n return this.#transport.get(`/trending/person/${toTimeWindow(timeWindow)}`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n}\n","import type { TMDBTransport } from '../http'\nimport { toCommaList, toId, withLanguage, type QueryParams } from '../query'\nimport type {\n CreditsResponse,\n ImageQueryOptions,\n ImagesResponse,\n LanguageOptions,\n ListOptions,\n PagedResponse,\n TMDBObject,\n TVDetails,\n TVDetailsOptions,\n TVSeasonDetails,\n TVSeasonDetailsOptions,\n TVSummary,\n VideosResponse,\n} from '../types'\n\n/**\n * Access TMDB TV show endpoints (popular, top-rated, details, seasons, etc.).\n *\n * Obtained via `client.tv`.\n */\nexport class TVResource {\n readonly #transport: TMDBTransport\n\n constructor(transport: TMDBTransport) {\n this.#transport = transport\n }\n\n popular(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/popular', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n topRated(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/top_rated', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n airingToday(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/airing_today', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n onTheAir(options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get('/tv/on_the_air', {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n details<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n options: TVDetailsOptions = {},\n ): Promise<TVDetails & TAppend> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}`, {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n })\n }\n\n credits(seriesId: number, options: LanguageOptions = {}): Promise<CreditsResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/credits`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n images(seriesId: number, options: ImageQueryOptions = {}): Promise<ImagesResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/images`, {\n query: withLanguage(this.#transport.defaults, {\n include_image_language: toCommaList(options.includeImageLanguage),\n language: options.language,\n }),\n })\n }\n\n recommendations(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/recommendations`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n similar(seriesId: number, options: Omit<ListOptions, 'region'> = {}): Promise<PagedResponse<TVSummary>> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/similar`, {\n query: tvListQuery(this.#transport, options),\n })\n }\n\n videos(seriesId: number, options: LanguageOptions = {}): Promise<VideosResponse> {\n return this.#transport.get(`/tv/${toId(seriesId, 'seriesId')}/videos`, {\n query: withLanguage(this.#transport.defaults, {\n language: options.language,\n }),\n })\n }\n\n seasonDetails<TAppend extends TMDBObject = TMDBObject>(\n seriesId: number,\n seasonNumber: number,\n options: TVSeasonDetailsOptions = {},\n ): Promise<TVSeasonDetails & TAppend> {\n return this.#transport.get(\n `/tv/${toId(seriesId, 'seriesId')}/season/${toId(seasonNumber, 'seasonNumber')}`,\n {\n query: withLanguage(this.#transport.defaults, {\n append_to_response: toCommaList(options.appendToResponse),\n language: options.language,\n }),\n },\n )\n }\n}\n\n/** Build query parameters for TV list endpoints. */\nfunction tvListQuery(\n transport: TMDBTransport,\n options: Omit<ListOptions, 'region'>,\n): QueryParams {\n return withLanguage(transport.defaults, {\n language: options.language,\n page: options.page,\n })\n}\n","import { TMDBHttpClient, type TMDBClientOptions, type TMDBRequestOptions, type TMDBTransport } from './http'\nimport { ConfigurationResource } from './resources/configuration'\nimport { GenresResource } from './resources/genres'\nimport { ImagesHelper } from './resources/images'\nimport { MoviesResource } from './resources/movies'\nimport { PeopleResource } from './resources/people'\nimport { SearchResource } from './resources/search'\nimport { TrendingResource } from './resources/trending'\nimport { TVResource } from './resources/tv'\n\n/**\n * Options accepted by {@link createTMDB} and the {@link TMDBClient} constructor.\n *\n * Extends {@link TMDBClientOptions} with an optional {@link TMDBTransport} so\n * callers can plug in a custom transport (typically for tests, caching, or\n * instrumentation) without having to mock `fetch` or the factory itself.\n */\nexport type TMDBFactoryOptions = TMDBClientOptions & {\n transport?: TMDBTransport\n}\n\n/**\n * Main SDK entry point.\n *\n * Resource properties are intentionally small and explicit. The SDK focuses on\n * common TMDB workflows first, while request<T>() keeps uncommon endpoints easy\n * to call without waiting for a generated surface area.\n */\nexport class TMDBClient {\n readonly configuration: ConfigurationResource\n readonly genres: GenresResource\n readonly images: ImagesHelper\n readonly movies: MoviesResource\n readonly people: PeopleResource\n readonly search: SearchResource\n readonly trending: TrendingResource\n readonly tv: TVResource\n\n readonly #transport: TMDBTransport\n\n constructor(options: TMDBFactoryOptions) {\n const { transport, images, ...httpOptions } = options\n // When the caller supplies a custom transport we still want to honor the\n // global images.transform option; otherwise read it back from the HTTP\n // client after it has been constructed.\n const fallbackTransform = images?.transform\n const builtInClient = transport === undefined ? new TMDBHttpClient({ ...httpOptions, images }) : undefined\n this.#transport = builtInClient ?? (transport as TMDBTransport)\n\n this.configuration = new ConfigurationResource(this.#transport)\n this.genres = new GenresResource(this.#transport)\n this.images = new ImagesHelper(\n this.#transport,\n builtInClient ? builtInClient.imageTransform : fallbackTransform,\n )\n this.movies = new MoviesResource(this.#transport)\n this.people = new PeopleResource(this.#transport)\n this.search = new SearchResource(this.#transport)\n this.trending = new TrendingResource(this.#transport)\n this.tv = new TVResource(this.#transport)\n }\n\n /**\n * Make a raw GET request to any TMDB endpoint.\n *\n * This is an escape hatch for endpoints not covered by the typed resource\n * helpers. The `path` should be relative to the API base URL (e.g.\n * `/movie/{id}/credits`). Response is parsed as JSON and cast to `T`.\n *\n * @param path - API path relative to the base URL (e.g. `/movie/123`)\n * @param options - Optional request-level overrides (headers, query, signal)\n * @returns Parsed JSON response typed as `T`\n */\n request<T>(path: string, options?: TMDBRequestOptions): Promise<T> {\n return this.#transport.get<T>(path, options)\n }\n}\n\n/**\n * Create a new {@link TMDBClient} instance.\n *\n * @example\n * ```ts\n * const tmdb = createTMDB({ accessToken: 'YOUR_TOKEN' })\n * const { results } = await tmdb.search.movies('Inception')\n * ```\n *\n * @param options - Authentication and configuration options\n * @returns A configured TMDBClient ready to make API calls\n */\nexport function createTMDB(options: TMDBFactoryOptions): TMDBClient {\n return new TMDBClient(options)\n}\n","import type {\n MovieMultiResult,\n MovieSearchResult,\n PersonMultiResult,\n PersonSearchResult,\n SearchMultiResult,\n TVMultiResult,\n TVSearchResult,\n} from './types'\n\n/**\n * Type guard that narrows a `search.multi()` result to a movie entry.\n *\n * The `media_type` field is required on every `/search/multi` payload by\n * TMDB, so this check is safe at runtime and produces a strictly typed\n * MovieSummary on the narrowed branch.\n */\nexport function isMovieSearchResult(\n result: SearchMultiResult,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult\nexport function isMovieSearchResult(\n result: unknown,\n): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a `search.multi()` result to a TV entry. */\nexport function isTVSearchResult(\n result: SearchMultiResult,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult\nexport function isTVSearchResult(\n result: unknown,\n): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a `search.multi()` result to a person entry. */\nexport function isPersonSearchResult(\n result: SearchMultiResult,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult\nexport function isPersonSearchResult(\n result: unknown,\n): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/**\n * Convenience alias: `isMovieSearchResult` works on a `search.movies()`\n * result (which already has the narrow type but is also tagged with\n * `media_type?: 'movie'`), as well as on multi-search results.\n */\nexport function isMovie(result: MovieSearchResult | SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: SearchMultiResult): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult\nexport function isMovie(result: unknown): result is MovieMultiResult {\n return isObjectWithMediaType(result, 'movie')\n}\n\n/** Type guard that narrows a search result to a TV entry. */\nexport function isTV(\n result: TVSearchResult | SearchMultiResult): result is TVMultiResult\nexport function isTV(result: SearchMultiResult): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult\nexport function isTV(result: unknown): result is TVMultiResult {\n return isObjectWithMediaType(result, 'tv')\n}\n\n/** Type guard that narrows a search result to a person entry. */\nexport function isPerson(\n result: PersonSearchResult | SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: SearchMultiResult): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult\nexport function isPerson(result: unknown): result is PersonMultiResult {\n return isObjectWithMediaType(result, 'person')\n}\n\n/** Internal helper: check if a value is an object with a matching `media_type` field. */\nfunction isObjectWithMediaType(\n value: unknown,\n mediaType: 'movie' | 'tv' | 'person',\n): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'media_type' in value &&\n (value as { media_type: unknown }).media_type === mediaType\n )\n}\n","/** Primitive JSON values returned by TMDB. */\nexport type JsonPrimitive = string | number | boolean | null\n\n/** JSON object/array tree returned by TMDB for fields this SDK does not model yet. */\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[]\n\nexport interface JsonObject {\n [key: string]: JsonValue | undefined\n}\n\n/** Escape hatch for append_to_response payloads and future TMDB fields. */\nexport type TMDBObject = Record<string, unknown>\n\n/** Date string in TMDB format (typically `YYYY-MM-DD`). */\nexport type TMDBDateString = string\n\n/** ISO 639-1 language code (e.g. `\"en\"`, `\"zh\"`). */\nexport type LanguageCode = string\n\n/** ISO 3166-1 country/region code (e.g. `\"US\"`, `\"CN\"`). */\nexport type RegionCode = string\n\n/** Supported media types for multi-search results. */\nexport type MediaType = 'movie' | 'tv' | 'person'\n\n/** Time window for trending endpoints: `\"day\"` or `\"week\"`. */\nexport type TrendingTimeWindow = 'day' | 'week'\n\nexport interface PagedResponse<T> {\n page: number\n results: T[]\n total_pages: number\n total_results: number\n}\n\nexport interface Genre {\n id: number\n name: string\n}\n\nexport interface ProductionCompany {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface ProductionCountry {\n iso_3166_1: string\n name: string\n}\n\nexport interface SpokenLanguage {\n english_name: string\n iso_639_1: string\n name: string\n}\n\nexport interface CollectionSummary {\n id: number\n name: string\n poster_path: string | null\n backdrop_path: string | null\n}\n\nexport interface MovieSummary {\n adult: boolean\n backdrop_path: string | null\n genre_ids: number[]\n id: number\n original_language: string\n original_title: string\n overview: string\n popularity: number\n poster_path: string | null\n release_date: TMDBDateString\n title: string\n video: boolean\n vote_average: number\n vote_count: number\n}\n\nexport interface MovieDetails extends Omit<MovieSummary, 'genre_ids'> {\n belongs_to_collection: CollectionSummary | null\n budget: number\n genres: Genre[]\n homepage: string | null\n imdb_id: string | null\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n revenue: number\n runtime: number | null\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n}\n\nexport interface TVSummary {\n adult?: boolean\n backdrop_path: string | null\n first_air_date: TMDBDateString\n genre_ids: number[]\n id: number\n name: string\n origin_country: string[]\n original_language: string\n original_name: string\n overview: string\n popularity: number\n poster_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface CreatedBy {\n id: number\n credit_id: string\n name: string\n gender: number\n profile_path: string | null\n}\n\nexport interface Network {\n id: number\n logo_path: string | null\n name: string\n origin_country: string\n}\n\nexport interface SeasonSummary {\n air_date: TMDBDateString | null\n episode_count: number\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport interface EpisodeGuestStar {\n adult: boolean\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface EpisodeSummary {\n air_date: TMDBDateString | null\n crew: CreditCrewMember[]\n episode_number: number\n episode_type: string\n guest_stars: EpisodeGuestStar[]\n id: number\n name: string\n overview: string\n production_code: string | null\n runtime: number | null\n season_number: number\n show_id: number\n still_path: string | null\n vote_average: number\n vote_count: number\n}\n\nexport interface TVSeasonDetails {\n _id: string\n air_date: TMDBDateString | null\n episodes: EpisodeSummary[]\n id: number\n name: string\n overview: string\n poster_path: string | null\n season_number: number\n vote_average: number\n}\n\nexport type TVSeasonAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'translations'\n | 'videos'\n | (string & {})\n\nexport interface TVSeasonDetailsOptions extends LanguageOptions {\n appendToResponse?: TVSeasonAppendToResponse | readonly TVSeasonAppendToResponse[]\n}\n\nexport interface TVDetails extends Omit<TVSummary, 'genre_ids'> {\n created_by: CreatedBy[]\n episode_run_time: number[]\n genres: Genre[]\n homepage: string | null\n in_production: boolean\n languages: string[]\n last_air_date: TMDBDateString | null\n networks: Network[]\n number_of_episodes: number\n number_of_seasons: number\n production_companies: ProductionCompany[]\n production_countries: ProductionCountry[]\n seasons: SeasonSummary[]\n spoken_languages: SpokenLanguage[]\n status: string\n tagline: string | null\n type: string\n}\n\nexport interface PersonKnownForMovie extends MovieSummary {\n media_type: 'movie'\n}\n\nexport interface PersonKnownForTV extends TVSummary {\n media_type: 'tv'\n}\n\nexport type PersonKnownFor = PersonKnownForMovie | PersonKnownForTV\n\nexport interface PersonSummary {\n adult: boolean\n gender: number\n id: number\n known_for: PersonKnownFor[]\n known_for_department: string\n name: string\n original_name?: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface PersonDetails extends Omit<PersonSummary, 'known_for'> {\n also_known_as: string[]\n biography: string\n birthday: TMDBDateString | null\n deathday: TMDBDateString | null\n homepage: string | null\n imdb_id: string | null\n place_of_birth: string | null\n}\n\nexport interface MovieSearchResult extends MovieSummary {\n media_type?: 'movie'\n}\n\nexport interface TVSearchResult extends TVSummary {\n media_type?: 'tv'\n}\n\nexport interface PersonSearchResult extends PersonSummary {\n media_type?: 'person'\n}\n\nexport type SearchMultiResult =\n | (MovieSummary & { media_type: 'movie' })\n | (TVSummary & { media_type: 'tv' })\n | (PersonSummary & { media_type: 'person' })\n\n/** A single multi-search result narrowed to a specific media type. */\nexport type MovieMultiResult = MovieSummary & { media_type: 'movie' }\nexport type TVMultiResult = TVSummary & { media_type: 'tv' }\nexport type PersonMultiResult = PersonSummary & { media_type: 'person' }\n\nexport type TrendingResult = SearchMultiResult\n\nexport interface CreditCastMember {\n adult?: boolean\n cast_id?: number\n character: string\n credit_id: string\n gender: number | null\n id: number\n known_for_department: string\n name: string\n order: number\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditCrewMember {\n adult?: boolean\n credit_id: string\n department: string\n gender: number | null\n id: number\n job: string\n known_for_department: string\n name: string\n original_name: string\n popularity: number\n profile_path: string | null\n}\n\nexport interface CreditsResponse {\n id: number\n cast: CreditCastMember[]\n crew: CreditCrewMember[]\n}\n\nexport interface Video {\n id: string\n iso_3166_1: string\n iso_639_1: string\n key: string\n name: string\n official: boolean\n published_at: string\n site: string\n size: number\n type: string\n}\n\nexport interface VideosResponse {\n id: number\n results: Video[]\n}\n\nexport interface ImageItem {\n aspect_ratio: number\n height: number\n iso_639_1: string | null\n file_path: string\n vote_average: number\n vote_count: number\n width: number\n}\n\nexport interface ImagesResponse {\n id: number\n backdrops: ImageItem[]\n logos?: ImageItem[]\n posters: ImageItem[]\n}\n\nexport interface ConfigurationImages {\n base_url: string\n secure_base_url: string\n backdrop_sizes: string[]\n logo_sizes: string[]\n poster_sizes: string[]\n profile_sizes: string[]\n still_sizes: string[]\n}\n\nexport interface Configuration {\n images: ConfigurationImages\n change_keys: string[]\n}\n\nexport interface Country {\n iso_3166_1: string\n english_name: string\n native_name: string\n}\n\nexport interface Language {\n iso_639_1: string\n english_name: string\n name: string\n}\n\nexport interface Timezone {\n iso_3166_1: string\n zones: string[]\n}\n\nexport interface JobDepartment {\n department: string\n jobs: string[]\n}\n\nexport interface GenresResponse {\n genres: Genre[]\n}\n\nexport type BackdropSize = 'w300' | 'w780' | 'w1280' | 'original' | (string & {})\nexport type LogoSize = 'w45' | 'w92' | 'w154' | 'w185' | 'w300' | 'w500' | 'original' | (string & {})\nexport type PosterSize = 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original' | (string & {})\nexport type ProfileSize = 'w45' | 'w185' | 'h632' | 'original' | (string & {})\nexport type StillSize = 'w92' | 'w185' | 'w300' | 'original' | (string & {})\nexport type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize\n\n/**\n * Public set of image sizes TMDB currently documents. The SDK does not\n * pin to a static copy of the TMDB docs — TMDB has added new sizes in\n * the past (e.g. `h632` for profile) without notice — but exposing the\n * canonical list lets callers:\n *\n * - iterate over the set to build a size picker\n * - validate user-supplied sizes with `isKnownBackdropSize(...)` etc.\n * - type a variable as a \"known\" size without giving up the\n * `(string & {})` escape hatch for forward-compatibility\n *\n * If TMDB publishes a new size, the SDK will still accept it at runtime\n * (every helper is `(string & {})` permissive), but you will need to\n * add the literal to these constants to get autocomplete on it.\n */\nexport const KNOWN_BACKDROP_SIZES: readonly ['w300', 'w780', 'w1280', 'original'] = Object.freeze(['w300', 'w780', 'w1280', 'original'] as const)\nexport const KNOWN_LOGO_SIZES: readonly ['w45', 'w92', 'w154', 'w185', 'w300', 'w500', 'original'] = Object.freeze([\n 'w45',\n 'w92',\n 'w154',\n 'w185',\n 'w300',\n 'w500',\n 'original',\n] as const)\nexport const KNOWN_POSTER_SIZES: readonly ['w92', 'w154', 'w185', 'w342', 'w500', 'w780', 'original'] = Object.freeze([\n 'w92',\n 'w154',\n 'w185',\n 'w342',\n 'w500',\n 'w780',\n 'original',\n] as const)\nexport const KNOWN_PROFILE_SIZES: readonly ['w45', 'w185', 'h632', 'original'] = Object.freeze(['w45', 'w185', 'h632', 'original'] as const)\nexport const KNOWN_STILL_SIZES: readonly ['w92', 'w185', 'w300', 'original'] = Object.freeze(['w92', 'w185', 'w300', 'original'] as const)\n\nexport type KnownBackdropSize = (typeof KNOWN_BACKDROP_SIZES)[number]\nexport type KnownLogoSize = (typeof KNOWN_LOGO_SIZES)[number]\nexport type KnownPosterSize = (typeof KNOWN_POSTER_SIZES)[number]\nexport type KnownProfileSize = (typeof KNOWN_PROFILE_SIZES)[number]\nexport type KnownStillSize = (typeof KNOWN_STILL_SIZES)[number]\nexport type KnownImageSize =\n | KnownBackdropSize\n | KnownLogoSize\n | KnownPosterSize\n | KnownProfileSize\n | KnownStillSize\n\n/** Union of every documented image size. */\nexport const KNOWN_IMAGE_SIZES: readonly KnownImageSize[] = Object.freeze([\n ...KNOWN_BACKDROP_SIZES,\n ...KNOWN_LOGO_SIZES,\n ...KNOWN_POSTER_SIZES,\n ...KNOWN_PROFILE_SIZES,\n ...KNOWN_STILL_SIZES,\n] as const)\n\n/** O(1) membership check backed by a Set. */\nconst KNOWN_BACKDROP_SET: ReadonlySet<string> = new Set(KNOWN_BACKDROP_SIZES)\nconst KNOWN_LOGO_SET: ReadonlySet<string> = new Set(KNOWN_LOGO_SIZES)\nconst KNOWN_POSTER_SET: ReadonlySet<string> = new Set(KNOWN_POSTER_SIZES)\nconst KNOWN_PROFILE_SET: ReadonlySet<string> = new Set(KNOWN_PROFILE_SIZES)\nconst KNOWN_STILL_SET: ReadonlySet<string> = new Set(KNOWN_STILL_SIZES)\nconst KNOWN_IMAGE_SET: ReadonlySet<string> = new Set(KNOWN_IMAGE_SIZES)\n\nexport function isKnownBackdropSize(value: string): value is KnownBackdropSize {\n return KNOWN_BACKDROP_SET.has(value)\n}\n\nexport function isKnownLogoSize(value: string): value is KnownLogoSize {\n return KNOWN_LOGO_SET.has(value)\n}\n\nexport function isKnownPosterSize(value: string): value is KnownPosterSize {\n return KNOWN_POSTER_SET.has(value)\n}\n\nexport function isKnownProfileSize(value: string): value is KnownProfileSize {\n return KNOWN_PROFILE_SET.has(value)\n}\n\nexport function isKnownStillSize(value: string): value is KnownStillSize {\n return KNOWN_STILL_SET.has(value)\n}\n\n/** True if `value` is in any documented size set. */\nexport function isKnownImageSize(value: string): value is KnownImageSize {\n return KNOWN_IMAGE_SET.has(value)\n}\n\nexport type MovieAppendToResponse =\n | 'account_states'\n | 'alternative_titles'\n | 'changes'\n | 'credits'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'lists'\n | 'recommendations'\n | 'release_dates'\n | 'reviews'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport type TVAppendToResponse =\n | 'account_states'\n | 'aggregate_credits'\n | 'alternative_titles'\n | 'changes'\n | 'content_ratings'\n | 'credits'\n | 'episode_groups'\n | 'external_ids'\n | 'images'\n | 'keywords'\n | 'recommendations'\n | 'reviews'\n | 'screened_theatrically'\n | 'similar'\n | 'translations'\n | 'videos'\n | 'watch/providers'\n | (string & {})\n\nexport interface ListOptions {\n language?: LanguageCode\n page?: number\n region?: RegionCode\n}\n\nexport interface LanguageOptions {\n language?: LanguageCode\n}\n\nexport interface MovieDetailsOptions extends LanguageOptions {\n appendToResponse?: MovieAppendToResponse | readonly MovieAppendToResponse[]\n}\n\nexport interface TVDetailsOptions extends LanguageOptions {\n appendToResponse?: TVAppendToResponse | readonly TVAppendToResponse[]\n}\n\nexport interface MovieSearchOptions extends ListOptions {\n includeAdult?: boolean\n primaryReleaseYear?: string | number\n year?: string | number\n}\n\nexport interface TVSearchOptions extends Omit<ListOptions, 'region'> {\n firstAirDateYear?: string | number\n includeAdult?: boolean\n year?: string | number\n}\n\nexport interface MultiSearchOptions extends Omit<ListOptions, 'region'> {\n includeAdult?: boolean\n /**\n * Media types to exclude from a `search.multi()` response. Filtering is\n * performed client-side because the TMDB multi-search endpoint does not\n * support a server-side media_type filter.\n */\n exclude?: ReadonlyArray<MediaType>\n}\n\nexport interface ImageQueryOptions extends LanguageOptions {\n includeImageLanguage?: string | readonly string[]\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED