diff --git a/src/endpoints/configuration.ts b/src/endpoints/configuration.ts new file mode 100644 index 0000000..c2089f2 --- /dev/null +++ b/src/endpoints/configuration.ts @@ -0,0 +1,13 @@ +import { BaseEndpoint } from './base'; +import { Configuration } from '../types/configuration'; + +export class ConfigurationEndpoint extends BaseEndpoint { + constructor(protected readonly accessToken: string) { + super(accessToken); + } + + async getCurrent(): Promise { + return await this.api.get(`/configuration`); + } + +} diff --git a/src/endpoints/index.ts b/src/endpoints/index.ts index 9420b5d..04d76d8 100644 --- a/src/endpoints/index.ts +++ b/src/endpoints/index.ts @@ -7,3 +7,4 @@ export * from './credits'; export * from './search'; export * from './genre'; export * from './movies'; +export * from './configuration'; diff --git a/src/endpoints/movies.ts b/src/endpoints/movies.ts index d360a29..b7374c3 100644 --- a/src/endpoints/movies.ts +++ b/src/endpoints/movies.ts @@ -1,5 +1,18 @@ import { BaseEndpoint } from './base'; -import { AlternativeTitles, MovieDetails } from '../types/movie'; +import { + AlternativeTitles, + Credits, + Images, + Keywords, LatestMovie, MovieChanges, + MovieDetails, MovieLists, MovieRecommendations, MovieReviews, MoviesPlayingNow, MovieTranslations, PopularMovies, + ReleaseDates, + SimilarMovies, TopRatedMovies, UpcomingMovies, + Videos, +} from '../types/movie'; +import { ExternalIds } from '../types'; +import { WatchProviders } from '../types/watch-providers'; +import { ChangeOptions } from './changes'; +import querystring from 'querystring'; const BASE_MOVIE = '/movie'; @@ -16,4 +29,90 @@ export class MoviesEndpoint extends BaseEndpoint{ return await this.api.get(`${BASE_MOVIE}/${id}/alternative_titles`); } + async changes(id: number, options?: ChangeOptions): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/${id}/changes?${params}`); + } + + async credits(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/credits`); + } + + async externalIds(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/external_ids`); + } + + async images(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/images`); + } + + async keywords(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/keywords`); + } + + async lists(id: number, options?: {page?: number}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/${id}/lists?${params}`); + } + + async recommendations(id: number, options?: {page?: number}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/${id}/recommendations?${params}`); + } + + async releaseDates(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/release_dates`); + } + + async reviews(id: number, options?: {page?: number}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/${id}/reviews?${params}`); + } + + async similar(id: number, options?: {page?: number}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/${id}/similar?${params}`); + } + + async translations(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/translations`); + } + + async videos(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/videos`); + } + + /** + * Powered by JustWatch + * @param id + */ + async watchProviders(id: number): Promise{ + return await this.api.get(`${BASE_MOVIE}/${id}/watch/providers`); + } + + async latest(): Promise{ + return await this.api.get(`${BASE_MOVIE}/latest`); + } + + async nowPlaying(options?: {page?: number, region?: string}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/now_playing?${params}`); + } + + async popular(options?: {page?: number}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/popular?${params}`); + } + + async topRated(options?: {page?: number, region?: string}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/top_rated?${params}`); + } + + async upcoming(options?: {page?: number, region?: string}): Promise{ + const params = querystring.encode(options); + return await this.api.get(`${BASE_MOVIE}/upcoming?${params}`); + } } + + diff --git a/src/tmdb.ts b/src/tmdb.ts index e735b17..cb51150 100644 --- a/src/tmdb.ts +++ b/src/tmdb.ts @@ -6,6 +6,7 @@ import { GenreEndpoint, MoviesEndpoint, SearchEndpoint, + ConfigurationEndpoint, } from './endpoints'; export default class TMDB { @@ -19,6 +20,10 @@ export default class TMDB { return new AccountEndpoint(this.accessToken); } + get configuration(): ConfigurationEndpoint { + return new ConfigurationEndpoint(this.accessToken); + } + get certifications(): CertificationEndpoint { return new CertificationEndpoint(this.accessToken); } diff --git a/src/types/changes.d.ts b/src/types/changes.d.ts index 1a73363..c5f59dd 100644 --- a/src/types/changes.d.ts +++ b/src/types/changes.d.ts @@ -9,3 +9,4 @@ export interface Changes{ total_pages: number; total_results: number; } + diff --git a/src/types/configuration.d.ts b/src/types/configuration.d.ts new file mode 100644 index 0000000..1972655 --- /dev/null +++ b/src/types/configuration.d.ts @@ -0,0 +1,114 @@ + +export interface Images { + base_url: string; + secure_base_url: string; + backdrop_sizes: BackdropSizes[]; + logo_sizes: LogoSizes[]; + poster_sizes: PosterSizes[]; + profile_sizes: ProfileSizes[]; + still_sizes: StillSizes[]; +} + +export interface Configuration { + images: Images; + change_keys: ChangeKeys[]; +} + + +export const enum BackdropSizes { + W300 = 'w300', + W780 = 'w780', + W1280 = 'w1280', + ORIGINAL = 'original' +} + +export const enum LogoSizes { + W45= 'w45', + W92= 'w92', + W154= 'w154', + W185= 'w185', + W300 = 'w300', + W500 = 'w500', + ORIGINAL = 'original' +} + +export const enum PosterSizes { + W92= 'w92', + W154= 'w154', + W185='w185', + W300 = 'w300', + W500 = 'w500', + W780 = 'w780', + ORIGINAL = 'original' +} + +export const enum ProfileSizes { + W45 = 'w45', + W185 = 'w185', + W632 = 'w632', + ORIGINAL = 'original' +} + + +export const enum StillSizes { + W92= 'w92', + W185 = 'w185', + W300 = 'w300', + ORIGINAL = 'original' +} + +export const enum ChangeKeys { + ADULT = 'adult', + AIR_DATE = 'air_date', + ALSO_KNOWN_AS = 'also_known_as', + ALTERNATIVE_TITLES = 'alternative_titles', + BIOGRAPHY = 'biography', + BIRTHDAY = 'birthday', + BUDGET = 'budget', + CAST = 'cast', + CERTIFICATIONS = 'certifications', + CHARACTER_NAMES = 'character_names', + CREATED_BY = 'created_by', + CREW = 'crew', + DEATHDAY = 'deathday', + EPISODE = 'episode', + EPISODE_NUMBER = 'episode_number', + EPISODE_RUN_TIME = 'episode_run_time', + FREEBASE_ID = 'freebase_id', + FREEBASE_MID = 'freebase_mid', + GENERAL = 'general', + GENRES = 'genres', + GUEST_STARS = 'guest_stars', + HOMEPAGE = 'homepage', + IMAGES = 'images', + IMDB_ID = 'imdb_id', + LANGUAGES = 'languages', + NAME = 'name', + NETWORK = 'network', + ORIGIN_COUNTRY = 'origin_country', + ORIGINAL_NAME = 'original_name', + ORIGINAL_TITLE = 'original_title', + OVERVIEW = 'overview', + PARTS = 'parts', + PLACE_OF_BIRTH = 'place_of_birth', + PLOT_KEYWORDS = 'plot_keywords', + PRODUCTION_CODE = 'production_code', + PRODUCTION_COMPANIES = 'production_companies', + PRODUCTION_COUNTRIES = 'production_countries', + RELEASES = 'releases', + REVENUE = 'revenue', + RUNTIME = 'runtime', + SEASON = 'season', + SEASON_NUMBER = 'season_number', + SEASON_REGULAR = 'season_regular', + SPOKEN_LANGUAGES = 'spoken_languages', + STATUS = 'status', + TAGLINE = 'tagline', + TITLE = 'title', + TRANSLATIONS = 'translations', + TVDB_ID = 'tvdb_id', + TVRAGE_ID = 'tvrage_id', + TYPE = 'type', + VIDEO = 'video', + VIDEOS = 'videos' +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 118d132..3c3ac25 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -86,6 +86,15 @@ export interface Genre { name: string; } +export interface ExternalIds { + imdb_id: string; + facebook_id: string; + instagram_id: string; + twitter_id: string; + id: number; +} + + export { certs, credits, diff --git a/src/types/movie.d.ts b/src/types/movie.d.ts index 062aa91..da54111 100644 --- a/src/types/movie.d.ts +++ b/src/types/movie.d.ts @@ -1,4 +1,4 @@ -import { Genre } from './index'; +import { Genre, Movie } from './index'; export interface ProductionCompany { id: number; @@ -56,3 +56,291 @@ export interface AlternativeTitles { id: number; titles: Title[]; } + +export interface Cast { + adult: boolean; + gender: number; + id: number; + known_for_department: string; + name: string; + original_name: string; + popularity: number; + profile_path: string; + cast_id: number; + character: string; + credit_id: string; + order: number; +} + +export interface Crew { + adult: boolean; + gender: number; + id: number; + known_for_department: string; + name: string; + original_name: string; + popularity: number; + profile_path: string; + credit_id: string; + department: string; + job: string; +} + +export interface Credits { + id: number; + cast: Cast[]; + crew: Crew[]; +} + + +export interface Backdrop { + aspect_ratio: number; + file_path: string; + height: number; + iso_639_1?: any; + vote_average: number; + vote_count: number; + width: number; +} + +export interface Poster { + aspect_ratio: number; + file_path: string; + height: number; + iso_639_1: string; + vote_average: number; + vote_count: number; + width: number; +} + +export interface Images { + id: number; + backdrops: Backdrop[]; + posters: Poster[]; +} + + +export interface Video { + id: string; + iso_639_1: string; + iso_3166_1: string; + key: string; + name: string; + site: string; + size: number; + type: string; +} + +export interface Videos { + id: number; + results: Video[]; +} + +export interface Keywords { + id: number; + keywords: Array<{ + id: number; + name: string; + }> + +} + +export interface ReleaseDate { + certification: string; + iso_639_1: string; + release_date: Date; + type: number; + note: string; +} + +export interface ReleaseDateResult { + iso_3166_1: string; + release_dates: ReleaseDate[]; +} + +export interface ReleaseDates { + id: number; + results: ReleaseDateResult[]; +} + + +export interface SimilarMovies { + page: number; + results: Movie[]; + total_pages: number; + total_results: number; +} + + +export interface AuthorDetails { + name: string; + username: string; + avatar_path: string; + rating?: number; +} + +export interface Review { + author: string; + author_details: AuthorDetails; + content: string; + created_at: Date; + id: string; + updated_at: Date; + url: string; +} + +export interface MovieReviews { + id: number; + page: number; + results: Review[]; + total_pages: number; + total_results: number; +} + + +export interface TranslationData { + title: string; + overview: string; + homepage: string; +} + +export interface Translation { + iso_3166_1: string; + iso_639_1: string; + name: string; + english_name: string; + data: TranslationData; +} + +export interface MovieTranslations { + id: number; + translations: Translation[]; +} + + +export interface MovieList { + description: string; + favorite_count: number; + id: number; + item_count: number; + iso_639_1: string; + list_type: string; + name: string; + poster_path: string; +} + +export interface MovieLists { + id: number; + page: number; + results: MovieList[]; + total_pages: number; + total_results: number; +} + + +export interface MovieChangeItem { + id: string; + action: string; + time: string; + iso_639_1: string; + value: string; + original_value: string; +} + +export interface MovieChange { + key: string; + items: MovieChangeItem[]; +} + +export interface MovieChanges { + changes: MovieChange[]; +} + + +export interface MovieRecommendation { + adult: boolean; + backdrop_path?: any; + genre_ids: number[]; + id: number; + original_language: string; + original_title: string; + overview: string; + release_date: string; + poster_path?: any; + popularity: number; + title: string; + video: boolean; + vote_average: number; + vote_count: number; +} + +export interface MovieRecommendations { + page: number; + results: MovieRecommendation[]; + total_pages: number; + total_results: number; +} + + +export interface LatestMovie { + adult: boolean; + backdrop_path?: any; + belongs_to_collection?: any; + budget: number; + genres: Genre[]; + homepage: string; + id: number; + imdb_id: string; + original_language: string; + original_title: string; + overview: string; + popularity: number; + poster_path: string; + production_companies: any[]; + production_countries: any[]; + release_date: string; + revenue: number; + runtime: number; + spoken_languages: any[]; + status: string; + tagline: string; + title: string; + video: boolean; + vote_average: number; + vote_count: number; +} + + +export interface Dates { + maximum: string; + minimum: string; +} + +export interface MoviesPlayingNow { + page: number; + results: Movie[]; + dates: Dates; + total_pages: number; + total_results: number; +} + +export interface PopularMovies { + page: number; + results: Movie[]; + total_results: number; + total_pages: number; +} + +export interface TopRatedMovies { + page: number; + results: Movie[]; + total_results: number; + total_pages: number; +} + +export interface UpcomingMovies { + page: number; + results: Movie[]; + total_results: number; + total_pages: number; +} diff --git a/src/types/watch-providers.d.ts b/src/types/watch-providers.d.ts new file mode 100644 index 0000000..1ca7859 --- /dev/null +++ b/src/types/watch-providers.d.ts @@ -0,0 +1,302 @@ + +export interface Flatrate { + display_priority: number; + logo_path: string; + provider_id: number; + provider_name: string; +} + +export interface Rent { + display_priority: number; + logo_path: string; + provider_id: number; + provider_name: string; +} + +export interface Buy { + display_priority: number; + logo_path: string; + provider_id: number; + provider_name: string; +} + + +export interface WatchLocale { + AR: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + AT: { + link: string; + rent: Rent[]; + buy: Buy[]; + }; + AU: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + BE: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + rent: Rent[]; + }; + BR: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + CA: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + CH: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + CL: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + CO: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + CZ: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + rent: Rent[]; + }; + DE: { + link: string; + rent: Rent[]; + buy: Buy[]; + }; + DK: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + EC: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + EE: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + ES: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + FI: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + rent: Rent[]; + }; + FR: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + GB: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + GR: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + HU: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + ID: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + IE: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + IN: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + rent: Rent[]; + }; + IT: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + rent: Rent[]; + }; + JP: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + KR: { + link: string; + buy: Buy[]; + rent: Rent[]; + flatrate: Flatrate[]; + }; + LT: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + }; + LV: { + link: string; + buy: Buy[]; + flatrate: Flatrate[]; + }; + MX: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + MY: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + NL: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + NO: { + link: string; + buy: Buy[]; + rent: Rent[]; + flatrate: Flatrate[]; + }; + NZ: { + link: string; + buy: Buy[]; + rent: Rent[]; + flatrate: Flatrate[]; + }; + PE: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + PH: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + PL: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + PT: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + RO: { + link: string; + flatrate: Flatrate[]; + }; + RU: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + SE: { + link: string; + rent: Rent[]; + flatrate: Flatrate[]; + buy: Buy[]; + }; + SG: { + link: string; + flatrate: Flatrate[]; + buy: Buy[]; + rent: Rent[]; + }; + TH: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + TR: { + link: string; + buy: Buy[]; + rent: Rent[]; + flatrate: Flatrate[]; + }; + US: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; + VE: { + link: string; + flatrate: Flatrate[]; + rent: Rent[]; + buy: Buy[]; + }; + ZA: { + link: string; + rent: Rent[]; + buy: Buy[]; + flatrate: Flatrate[]; + }; +} + +export interface WatchProviders { + id: number; + results: WatchLocale; +} + + diff --git a/src/utils/getImagePath.ts b/src/utils/getImagePath.ts new file mode 100644 index 0000000..793a9ca --- /dev/null +++ b/src/utils/getImagePath.ts @@ -0,0 +1,12 @@ +/** + * Utility method to construct full url for image + * based on configuration + * + * https://developers.themoviedb.org/3/getting-started/images + * @param {string} baseUrl base image url + * @param {string} fileSize file size + * @param {string} imagePath raw image path + */ +export const getFullImagePath = (baseUrl: string, fileSize: string, imagePath: string): string => { + return `${baseUrl}${fileSize}${imagePath}`; +};