@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 +198 -60
- package/dist/index.d.mts +583 -9
- package/dist/index.mjs +1 -4411
- package/package.json +2 -2
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
|
-
|
|
23
|
+
yarn add @lorenzopant/tmdb
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Quick Start
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
import { TMDB } from "@lorenzopant/tmdb";
|
|
32
|
-
|
|
33
|
-
const tmdb = new TMDB(
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
78
|
+
---
|
|
58
79
|
|
|
59
|
-
|
|
80
|
+
## Constructor Options
|
|
60
81
|
|
|
61
|
-
|
|
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
|
-
|
|
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
|
-
|
|
68
|
-
- `options.logger`: Enable debug logging for all network requests.
|
|
114
|
+
### `rate_limit`
|
|
69
115
|
|
|
70
|
-
|
|
116
|
+
Automatically queues requests to stay within TMDB's API limits (~40 req/s). Useful for bulk scripts.
|
|
71
117
|
|
|
72
118
|
```typescript
|
|
73
|
-
|
|
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
|
-
|
|
126
|
+
### `cache`
|
|
127
|
+
|
|
128
|
+
In-memory TTL-based caching for GET requests. Entries expire lazily on access.
|
|
77
129
|
|
|
78
130
|
```typescript
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
174
|
+
## Examples
|
|
91
175
|
|
|
92
|
-
|
|
176
|
+
### Movie details
|
|
93
177
|
|
|
94
178
|
```typescript
|
|
95
|
-
tmdb.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
199
|
+
### Search
|
|
105
200
|
|
|
106
201
|
```typescript
|
|
107
|
-
tmdb.
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
212
|
+
const season = await tmdb.tv_seasons.details({ series_id: 1396, season_number: 1 });
|
|
213
|
+
console.log(season.episodes.length);
|
|
214
|
+
```
|
|
118
215
|
|
|
119
|
-
|
|
216
|
+
### Discover
|
|
120
217
|
|
|
121
218
|
```typescript
|
|
122
|
-
tmdb.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
226
|
+
### Trending
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const trending = await tmdb.trending.movies({ time_window: "week" });
|
|
129
230
|
```
|
|
130
231
|
|
|
131
|
-
|
|
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+
|
|
138
|
-
- Works
|
|
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
|
|