Skip to content

Commit 3b49030

Browse files
committed
feat(tmdb): adds initial service
1 parent 680ee18 commit 3b49030

20 files changed

+931
-0
lines changed

src/models/tmdb/tmdb-auth.model.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export type TmdbAuthRequestToken = {
2+
request_token: string;
3+
};
4+
5+
export type TmdbAuthAccessToken = {
6+
access_token: string;
7+
account_id: string;
8+
};

src/models/tmdb/tmdb-client.model.ts

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import type { RecursiveRecord } from '~/utils/typescript.utils';
2+
3+
import {
4+
type BaseOptions,
5+
type BaseQuery,
6+
type BaseRequest,
7+
type BaseTemplate,
8+
type BaseTemplateOptions,
9+
ClientEndpoint,
10+
type ResponseOrTypedResponse,
11+
} from '~/services/common/base-client';
12+
13+
export type TmdbClientSettings = {
14+
/** The domain name (e.g. https://api4.thetmdb.com) */
15+
endpoint: string;
16+
/** The consumer client identifier */
17+
useragent: string;
18+
/** The app read-only api key */
19+
readToken: string;
20+
/** token time-to-live (15 minutes) */
21+
requestTokenTTL: number;
22+
};
23+
24+
export type TmdbClientAuthentication = {
25+
/** User access token if there is an active session */
26+
accessToken?: string;
27+
/** The app read-only api key */
28+
readToken?: string;
29+
};
30+
31+
export type TmdbParamPagination = {
32+
page?: number;
33+
};
34+
35+
export type TmdbApiParam = RecursiveRecord;
36+
export type TmdbClientOptions = BaseOptions<TmdbClientSettings, TmdbApiResponse>;
37+
38+
export type TmdbApiResponseData<T = unknown> = T & {
39+
status_code: number;
40+
status_message: string;
41+
success: boolean;
42+
};
43+
44+
export type TmdbApiPagination = {
45+
page?: number;
46+
total_pages?: number;
47+
total_results?: number;
48+
};
49+
50+
export type TmdbApiResponsePageData<T = unknown> = TmdbApiPagination & {
51+
results: T[];
52+
};
53+
54+
export type TmdbPaginatedData<T = unknown> = {
55+
data: T[];
56+
pagination: TmdbApiPagination;
57+
};
58+
59+
export type TmdbApiResponse<T = unknown> = ResponseOrTypedResponse<T>;
60+
61+
export type TmdbApiQuery<T = unknown> = BaseQuery<BaseRequest, T>;
62+
export type TmdbApiTemplateOptions = BaseTemplateOptions & {
63+
/** If the method requires user authentication */
64+
auth?: boolean;
65+
};
66+
67+
export type TmdbApiTemplate<Parameter extends TmdbApiParam = TmdbApiParam> = BaseTemplate<Parameter, TmdbApiTemplateOptions>;
68+
69+
export interface TmdbClientEndpoint<Parameter extends TmdbApiParam = Record<string, never>, Response = unknown> {
70+
(param?: Parameter, init?: BodyInit): Promise<TmdbApiResponse<Response>>;
71+
}
72+
73+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
74+
export class TmdbClientEndpoint<
75+
Parameter extends TmdbApiParam = Record<string, never>,
76+
Response = unknown,
77+
Cache extends boolean = true,
78+
> extends ClientEndpoint<Parameter, Response, Cache, TmdbApiTemplateOptions> {}
79+
80+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- this is a recursive type
81+
export type ITmdbApi<Parameter extends TmdbApiParam = any, Response = unknown, Cache extends boolean = boolean> = {
82+
[key: string]: TmdbClientEndpoint<Parameter, Response, Cache> | ITmdbApi<Parameter>;
83+
};
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { TmdbMovie } from '~/models/tmdb/tmdb-movie.model';
2+
3+
export type TmdbCollection = {
4+
id: number;
5+
name: string;
6+
poster_path: string;
7+
backdrop_path: string;
8+
parts?: TmdbMovie[];
9+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export type TmdbConfiguration = {
2+
images: {
3+
base_url: string;
4+
secure_base_url: string;
5+
backdrop_sizes: string[];
6+
logo_sizes: string[];
7+
poster_sizes: string[];
8+
profile_sizes: string[];
9+
still_sizes: string[];
10+
};
11+
change_keys: string[];
12+
};

src/models/tmdb/tmdb-credit.model.ts

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
export type TmdbCreditSeason = {
2+
air_date: string;
3+
episode_count: number;
4+
id: number;
5+
name: string;
6+
overview: string;
7+
poster_path: string;
8+
season_number: number;
9+
show_id: number;
10+
};
11+
12+
export type TmdbCreditPerson = {
13+
adult: boolean;
14+
id: number;
15+
name: string;
16+
original_name: string;
17+
media_type: string;
18+
popularity: number;
19+
gender: number;
20+
known_for_department: string;
21+
profile_path: string;
22+
};
23+
24+
export type TmdbCreditEpisode = {
25+
id: number;
26+
name: string;
27+
overview: string;
28+
media_type: string;
29+
vote_average: number;
30+
vote_count: number;
31+
/** Air date of the episode (YYYY-MM-DD) */
32+
air_date: string;
33+
episode_number: number;
34+
episode_type: string;
35+
production_code: string;
36+
runtime: number;
37+
season_number: number;
38+
show_id: number;
39+
still_path: string;
40+
};
41+
42+
export type TmdbCreditMedia = {
43+
adult: boolean;
44+
backdrop_path: string;
45+
id: number;
46+
name: string;
47+
original_language: string;
48+
original_name: string;
49+
overview: string;
50+
poster_path: string;
51+
media_type: string;
52+
genre_ids: number[];
53+
popularity: number;
54+
first_air_date: string;
55+
vote_average: number;
56+
vote_count: number;
57+
origin_country: string[];
58+
character: string;
59+
episodes: TmdbCreditEpisode[];
60+
seasons: TmdbCreditSeason[];
61+
};
62+
63+
export type TmdbCredit = {
64+
credit_type: string;
65+
department: string;
66+
job: string;
67+
media: TmdbCreditMedia;
68+
media_type: string;
69+
id: string;
70+
person: TmdbCreditPerson;
71+
};

src/models/tmdb/tmdb-entity.model.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
export const EntityType = {
2+
Short: 'short',
3+
Extended: 'extended',
4+
Any: 'any',
5+
} as const;
6+
7+
export type Any = typeof EntityType.Any;
8+
export type Short = typeof EntityType.Short;
9+
export type Extended = typeof EntityType.Extended;
10+
11+
export type EntityTypes = (typeof EntityType)[keyof typeof EntityType];
12+
13+
export type TmdbGenre = {
14+
id: number;
15+
name: string;
16+
};
17+
18+
export type TmdbCompany = {
19+
id: number;
20+
logo_path?: string;
21+
name: string;
22+
origin_country: string;
23+
parent_company?: TmdbCompany;
24+
description?: string;
25+
headquarters?: string;
26+
homepage?: string;
27+
};
28+
29+
export type TmdbCountry = {
30+
/** The ISO 3166-1 code of the country */
31+
iso_3166_1: string;
32+
name: string;
33+
};
34+
35+
export type TmdbLanguage = {
36+
english_name: string;
37+
iso_639_1: string;
38+
name: string;
39+
};
40+
41+
export type TmdbNetwork = {
42+
id: number;
43+
logo_path: string;
44+
name: string;
45+
origin_country: string;
46+
headquarters?: string;
47+
homepage?: string;
48+
};
49+
50+
export type TmdbCertification = {
51+
certification: string;
52+
meaning: string;
53+
order: number;
54+
};
55+
56+
export type TmdbKeyword = {
57+
id: number;
58+
name: string;
59+
};

src/models/tmdb/tmdb-episode.model.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { EntityTypes, Extended, Short } from '~/models/tmdb/tmdb-entity.model';
2+
import type { TmdbPerson } from '~/models/tmdb/tmdb-person.model';
3+
4+
export type TmdbEpisodeShort = {
5+
id: number;
6+
name: string;
7+
overview: string;
8+
vote_average: number;
9+
vote_count: number;
10+
/** Air date of the episode (YYYY-MM-DD) */
11+
air_date: string;
12+
episode_number: number;
13+
production_code: string;
14+
runtime: number;
15+
season_number: number;
16+
still_path: string;
17+
};
18+
19+
export type TmdbEpisodePerson = TmdbPerson & {
20+
credit_id: string;
21+
original_name: string;
22+
};
23+
24+
export type TmdbEpisodePersonCrew = TmdbEpisodePerson & {
25+
department: string;
26+
job: string;
27+
};
28+
29+
export type TmdbEpisodeGuestStar = TmdbEpisodePerson & {
30+
character: string;
31+
order: number;
32+
};
33+
34+
export type TmdbEpisodeExtended = TmdbEpisodeShort & {
35+
crew: TmdbEpisodePersonCrew[];
36+
guest_stars: TmdbEpisodeGuestStar[];
37+
};
38+
39+
export type TmdbEpisode<T extends EntityTypes = Short> = T extends Extended
40+
? TmdbEpisodeExtended
41+
: T extends Short
42+
? TmdbEpisodeShort
43+
: TmdbEpisodeExtended | TmdbEpisodeShort;

src/models/tmdb/tmdb-list.model.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export type TmdbList = {
2+
account_object_id: string;
3+
adult: number;
4+
average_rating: number;
5+
backdrop_path: string;
6+
/** UTC date when the list was created (YYYY-MM-DD HH:mm:ss UTC) */
7+
created_at: string;
8+
description: string;
9+
featured: number;
10+
id: number;
11+
/** The ISO 3166-1 code of the country */
12+
iso_3166_1: string;
13+
/** The ISO 639-1 code of the language */
14+
iso_639_1: string;
15+
name: string;
16+
number_of_items: number;
17+
poster_path: string;
18+
public: number;
19+
revenue: number;
20+
runtime: string;
21+
sort_by: number;
22+
/** UTC date when the list was updated (YYYY-MM-DD HH:mm:ss UTC) */
23+
updated_at: string;
24+
};

src/models/tmdb/tmdb-movie.model.ts

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { TmdbCollection } from '~/models/tmdb/tmdb-collection.model';
2+
import type { EntityTypes, Extended, Short, TmdbCompany, TmdbCountry, TmdbGenre, TmdbLanguage } from '~/models/tmdb/tmdb-entity.model';
3+
4+
export type TmdbMovieShort = {
5+
adult: boolean;
6+
backdrop_path: string;
7+
genre_ids: number[];
8+
id: number;
9+
original_language: string;
10+
original_title: string;
11+
overview: string;
12+
popularity: number;
13+
poster_path: string;
14+
/** The date of release YYYY-MM-DD */
15+
release_date: string;
16+
title: string;
17+
video: boolean;
18+
vote_average: number;
19+
vote_count: number;
20+
};
21+
22+
export type TmdbMovieExtended = TmdbMovieShort & {
23+
belongs_to_collection?: TmdbCollection;
24+
budget: number;
25+
genres: TmdbGenre[];
26+
homepage: string;
27+
imdb_id: string;
28+
production_companies: TmdbCompany[];
29+
production_countries: TmdbCountry[];
30+
revenue: number;
31+
runtime: number;
32+
spoken_languages: TmdbLanguage[];
33+
status: string;
34+
tagline: string;
35+
};
36+
37+
export type TmdbMovie<T extends EntityTypes = Short> = T extends Extended
38+
? TmdbMovieExtended
39+
: T extends Short
40+
? TmdbMovieShort
41+
: TmdbMovieShort | TmdbMovieExtended;

src/models/tmdb/tmdb-person.model.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { EntityTypes, Extended, Short } from '~/models/tmdb/tmdb-entity.model';
2+
3+
export type TmdbPersonShort = {
4+
adult: boolean;
5+
gender: number;
6+
id: number;
7+
known_for_department: string;
8+
name: string;
9+
popularity: number;
10+
profile_path: string;
11+
};
12+
13+
export type TmdbPersonExtended = TmdbPersonShort & {
14+
also_known_as: string[];
15+
biography: string;
16+
birthday: string;
17+
deathday: string;
18+
homepage: string;
19+
imdb_id: string;
20+
place_of_birth: string;
21+
};
22+
23+
export type TmdbPerson<T extends EntityTypes = Short> = T extends Extended
24+
? TmdbPersonExtended
25+
: T extends Short
26+
? TmdbPersonShort
27+
: TmdbPersonShort | TmdbPersonExtended;

0 commit comments

Comments
 (0)