@lorenzopant/tmdb 1.19.0 → 1.20.1

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/README.md CHANGED
@@ -20,122 +20,260 @@ npm install @lorenzopant/tmdb
20
20
  // or
21
21
  pnpm add @lorenzopant/tmdb
22
22
  // or
23
- yard add @lorenzopant/tmdb
23
+ yarn add @lorenzopant/tmdb
24
24
  ```
25
25
 
26
26
  ---
27
27
 
28
- ## Usage
28
+ ## Quick Start
29
29
 
30
30
  ```typescript
31
- import { TMDB } from "@lorenzopant/tmdb";
32
-
33
- const tmdb = new TMDB("your_access_token");
34
-
35
- async function searchMovies() {
36
- try {
37
- const movies = await tmdb.search.movies({ query: "Fight Club" });
38
- console.log(movies);
39
- } catch (error) {
40
- if (error instanceof TMDBError) {
41
- console.error("TMDB Error:", error.message);
42
- console.error("HTTP Status:", error.http_status_code);
43
- console.error("TMDB Status Code:", error.tmdb_status_code);
44
- } else {
45
- console.error("Unknown error:", error);
46
- }
47
- }
48
- }
31
+ import { TMDB, TMDBError } from "@lorenzopant/tmdb";
32
+
33
+ const tmdb = new TMDB(process.env.TMDB_ACCESS_TOKEN!);
49
34
 
50
- searchMovies();
35
+ const movie = await tmdb.movies.details({ movie_id: 550 });
36
+ console.log(movie.title); // "Fight Club"
51
37
  ```
52
38
 
53
39
  ---
54
40
 
55
- ## API
41
+ ## Namespaces
42
+
43
+ Every namespace maps directly to a TMDB API section. All methods are fully typed.
44
+
45
+ | Namespace | Description |
46
+ | ------------------------ | ----------------------------------------------------------------- |
47
+ | `tmdb.movies` | Movie details, credits, images, videos, recommendations, and more |
48
+ | `tmdb.movie_lists` | Now Playing, Popular, Top Rated, Upcoming |
49
+ | `tmdb.tv_series` | TV series details, credits, seasons, episode groups |
50
+ | `tmdb.tv_lists` | Airing Today, On The Air, Popular, Top Rated TV |
51
+ | `tmdb.tv_seasons` | Season details, credits, images |
52
+ | `tmdb.tv_episodes` | Episode details, credits, images |
53
+ | `tmdb.tv_episode_groups` | Episode group details |
54
+ | `tmdb.search` | Search movies, TV shows, people, collections, keywords |
55
+ | `tmdb.discover` | Discover movies and TV shows by filter |
56
+ | `tmdb.trending` | Trending movies, TV, and people |
57
+ | `tmdb.people` | Person details, credits, images, translations |
58
+ | `tmdb.people_lists` | Popular people |
59
+ | `tmdb.collections` | Collection details and images |
60
+ | `tmdb.companies` | Company details, alternative names, images |
61
+ | `tmdb.credits` | Credit details |
62
+ | `tmdb.genres` | Movie and TV genre lists |
63
+ | `tmdb.keywords` | Keyword details and associated movies |
64
+ | `tmdb.certifications` | Movie and TV certifications per region |
65
+ | `tmdb.changes` | Recent content changes |
66
+ | `tmdb.configuration` | TMDB configuration, countries, languages, timezones |
67
+ | `tmdb.find` | Find resources by external ID (IMDb, TVDB, etc.) |
68
+ | `tmdb.networks` | TV network details |
69
+ | `tmdb.watch_providers` | Watch providers by region |
70
+ | `tmdb.lists` | User-created list management |
71
+ | `tmdb.account` | Account details and user lists |
72
+ | `tmdb.authentication` | Token-based authentication flows |
73
+ | `tmdb.guest_sessions` | Guest session rated movies/TV/episodes |
74
+ | `tmdb.reviews` | Review details |
75
+ | `tmdb.images` | Image URL builder (see below) |
76
+ | `tmdb.v4` | TMDB API v4 (auth, account, lists — requires JWT) |
56
77
 
57
- ### `TMDB`
78
+ ---
58
79
 
59
- The main client class. **Each API method supports all the parameters supported by TMDB API**, for example the search method supports: query, language, region, year, primary_release_year and so on...
80
+ ## Constructor Options
60
81
 
61
- #### Constructor
82
+ ```typescript
83
+ const tmdb = new TMDB(accessToken, {
84
+ language: "en-US", // ISO 639-1: default language for all requests
85
+ region: "US", // ISO 3166-1: default region for all requests
86
+ timezone: "America/New_York", // default timezone for TV airing queries
87
+ logger: true, // enable built-in request/response logging
88
+ deduplication: true, // deduplicate concurrent identical requests (default: true)
89
+ rate_limit: true, // auto-queue requests to stay within TMDB rate limits
90
+ cache: true, // enable in-memory TTL-based response caching
91
+ images: {
92
+ secure_images_url: true,
93
+ default_image_sizes: { posters: "w500", backdrops: "w780" },
94
+ },
95
+ });
96
+ ```
97
+
98
+ ### `logger`
62
99
 
63
100
  ```typescript
64
- const tmdb = new TMDB(accessToken: string, options?: TMDBOptions);
101
+ // Built-in console logger
102
+ const tmdb = new TMDB(token, { logger: true });
103
+
104
+ // Custom logger function
105
+ const tmdb = new TMDB(token, {
106
+ logger: (entry) => {
107
+ if (entry.type === "response") {
108
+ console.log(`[TMDB] ${entry.endpoint} → ${entry.status} (${entry.durationMs}ms)`);
109
+ }
110
+ },
111
+ });
65
112
  ```
66
113
 
67
- - `accessToken`: **required**. Your TMDB API v4 access token.
68
- - `options.logger`: Enable debug logging for all network requests.
114
+ ### `rate_limit`
69
115
 
70
- Example:
116
+ Automatically queues requests to stay within TMDB's API limits (~40 req/s). Useful for bulk scripts.
71
117
 
72
118
  ```typescript
73
- const tmdb = new TMDB("your_access_token", { logger: true });
119
+ // Default limits
120
+ const tmdb = new TMDB(token, { rate_limit: true });
121
+
122
+ // Custom budget
123
+ const tmdb = new TMDB(token, { rate_limit: { max_requests: 30, per_ms: 1_000 } });
74
124
  ```
75
125
 
76
- Custom logger:
126
+ ### `cache`
127
+
128
+ In-memory TTL-based caching for GET requests. Entries expire lazily on access.
77
129
 
78
130
  ```typescript
79
- const tmdb = new TMDB("your_access_token", {
80
- logger: (entry) => {
81
- if (entry.type === "response") {
82
- console.log("TMDB:", entry.endpoint, entry.status, entry.durationMs);
83
- }
131
+ // 5-minute TTL, no size limit (defaults)
132
+ const tmdb = new TMDB(token, { cache: true });
133
+
134
+ // Custom TTL and bounded size
135
+ const tmdb = new TMDB(token, {
136
+ cache: {
137
+ ttl: 60_000, // 60 seconds
138
+ max_size: 500, // evict oldest entry when limit is reached
139
+ excluded_endpoints: ["/trending", /\/discover\//],
140
+ },
141
+ });
142
+
143
+ // Runtime cache controls
144
+ tmdb.cache?.invalidate("/movie/now_playing"); // remove one entry
145
+ tmdb.cache?.clear(); // remove all entries
146
+ console.log(tmdb.cache?.size); // number of cached entries
147
+ ```
148
+
149
+ ### `interceptors`
150
+
151
+ Hook into every request or response globally.
152
+
153
+ ```typescript
154
+ const tmdb = new TMDB(token, {
155
+ interceptors: {
156
+ request: (ctx) => {
157
+ // Inject a param into every request
158
+ return { ...ctx, params: { ...ctx.params, include_adult: false } };
159
+ },
160
+ response: {
161
+ onSuccess: (data) => {
162
+ myAnalytics.track("tmdb_response", data);
163
+ },
164
+ onError: (error) => {
165
+ Sentry.captureException(error);
166
+ },
167
+ },
84
168
  },
85
169
  });
86
170
  ```
87
171
 
88
172
  ---
89
173
 
90
- ### `Search`
174
+ ## Examples
91
175
 
92
- Search for movies:
176
+ ### Movie details
93
177
 
94
178
  ```typescript
95
- tmdb.search.movies({ query: "Fight Club" });
179
+ const movie = await tmdb.movies.details({ movie_id: 550 });
180
+ console.log(movie.title); // "Fight Club"
181
+ console.log(movie.release_date); // "1999-10-15"
96
182
  ```
97
183
 
98
- Returns a **typed response** containing movies.
184
+ ### `append_to_response` typed overloads
99
185
 
100
- ---
186
+ Fetch related data in a single request. The return type is automatically extended with the appended fields.
187
+
188
+ ```typescript
189
+ const movie = await tmdb.movies.details({
190
+ movie_id: 550,
191
+ append_to_response: ["credits", "videos"],
192
+ });
101
193
 
102
- ### `Movie Lists`
194
+ // TypeScript knows these are present:
195
+ console.log(movie.credits.cast[0].name);
196
+ console.log(movie.videos.results[0].key);
197
+ ```
103
198
 
104
- Now Playing, Popular, Top Rated and Upcoming movies:
199
+ ### Search
105
200
 
106
201
  ```typescript
107
- tmdb.movie_lists.now_playing();
108
- tmdb.movie_lists.top_rated();
109
- tmdb.movie_lists.popular();
110
- tmdb.movie_lists.upcoming();
202
+ const results = await tmdb.search.movies({ query: "Inception", language: "en-US" });
203
+ console.log(results.results[0].title); // "Inception"
111
204
  ```
112
205
 
113
- Returns a **typed response** containing movies.
206
+ ### TV series
114
207
 
115
- ---
208
+ ```typescript
209
+ const show = await tmdb.tv_series.details({ series_id: 1396 });
210
+ console.log(show.name); // "Breaking Bad"
116
211
 
117
- ### `Movie`
212
+ const season = await tmdb.tv_seasons.details({ series_id: 1396, season_number: 1 });
213
+ console.log(season.episodes.length);
214
+ ```
118
215
 
119
- Details, alternative titles, changes, credits, external IDs and more:
216
+ ### Discover
120
217
 
121
218
  ```typescript
122
- tmdb.movie.details({ movie_id: 550 });
123
- tmdb.movie.alternative_titles({ movie_id: 550 });
124
- tmdb.movie.changes({ movie_id: 550 });
125
- tmdb.movie.credits({ movie_id: 550 });
126
- tmdb.movie.external_ids({ movie_id: 550 });
219
+ const action = await tmdb.discover.movies({
220
+ with_genres: "28",
221
+ sort_by: "vote_average.desc",
222
+ "vote_count.gte": 1000,
223
+ });
224
+ ```
127
225
 
128
- ...and more
226
+ ### Trending
227
+
228
+ ```typescript
229
+ const trending = await tmdb.trending.movies({ time_window: "week" });
129
230
  ```
130
231
 
131
- Returns a **typed response** containing movies.
232
+ ### Image URLs
233
+
234
+ ```typescript
235
+ const movie = await tmdb.movies.details({ movie_id: 550 });
236
+
237
+ // Build a full URL from a path
238
+ const posterUrl = tmdb.images.poster(movie.poster_path!, "w500");
239
+ const backdropUrl = tmdb.images.backdrop(movie.backdrop_path!, "w1280");
240
+
241
+ // Or enable auto-enrichment so all image paths in every response are resolved automatically
242
+ const tmdb = new TMDB(token, {
243
+ images: { autocomplete_images: true, secure_images_url: true },
244
+ });
245
+ ```
246
+
247
+ ### Error handling
248
+
249
+ ```typescript
250
+ import { TMDB, TMDBError } from "@lorenzopant/tmdb";
251
+
252
+ try {
253
+ const movie = await tmdb.movies.details({ movie_id: 0 });
254
+ } catch (error) {
255
+ if (error instanceof TMDBError) {
256
+ console.error(error.message); // human-readable message
257
+ console.error(error.http_status_code); // e.g. 404
258
+ console.error(error.tmdb_status_code); // TMDB-specific status code
259
+ }
260
+ }
261
+ ```
262
+
263
+ ### TMDB API v4 (requires JWT access token)
264
+
265
+ ```typescript
266
+ const tmdb = new TMDB(jwtAccessToken);
267
+
268
+ const lists = await tmdb.v4.lists.list({ account_id: "me" });
269
+ ```
132
270
 
133
271
  ---
134
272
 
135
273
  ## Requirements
136
274
 
137
- - Node.js 18+ recommended
138
- - Works on frontend (React, Vue) but **don't expose sensitive access tokens** to users!
275
+ - Node.js 18+
276
+ - Works in frontend frameworks (React, Vue, Next.js) **never expose your access token to the browser in production**
139
277
 
140
278
  ---
141
279