tmdb-kit 1.0.0 → 1.1.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/README.md +293 -198
- package/dist/cli.js +3132 -0
- package/dist/client.d.cts +63 -0
- package/dist/client.d.ts +63 -0
- package/dist/errors.d.cts +74 -0
- package/dist/errors.d.ts +74 -0
- package/dist/http.d.cts +80 -0
- package/dist/http.d.ts +80 -0
- package/dist/index.cjs +747 -768
- package/dist/index.cjs.map +23 -1
- package/dist/index.d.cts +8 -783
- package/dist/index.d.ts +8 -783
- package/dist/index.js +707 -745
- package/dist/index.js.map +23 -1
- package/dist/query.d.cts +77 -0
- package/dist/query.d.ts +77 -0
- package/dist/resources/configuration.d.cts +17 -0
- package/dist/resources/configuration.d.ts +17 -0
- package/dist/resources/genres.d.cts +13 -0
- package/dist/resources/genres.d.ts +13 -0
- package/dist/resources/images.d.cts +17 -0
- package/dist/resources/images.d.ts +17 -0
- package/dist/resources/movies.d.cts +21 -0
- package/dist/resources/movies.d.ts +21 -0
- package/dist/resources/people.d.cts +14 -0
- package/dist/resources/people.d.ts +14 -0
- package/dist/resources/search.d.cts +15 -0
- package/dist/resources/search.d.ts +15 -0
- package/dist/resources/trending.d.cts +23 -0
- package/dist/resources/trending.d.ts +23 -0
- package/dist/resources/tv.d.cts +22 -0
- package/dist/resources/tv.d.ts +22 -0
- package/dist/search-guards.d.cts +32 -0
- package/dist/search-guards.d.ts +32 -0
- package/dist/types.d.cts +452 -0
- package/dist/types.d.ts +452 -0
- package/package.json +26 -19
package/README.md
CHANGED
|
@@ -6,29 +6,67 @@
|
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
[](https://github.com/isaced/tmdb-kit/actions/workflows/ci.yml)
|
|
8
8
|
|
|
9
|
-
A minimal, fully typed
|
|
10
|
-
|
|
11
|
-
`tmdb-kit` covers
|
|
9
|
+
A minimal, fully typed SDK and read-only command-line interface (CLI) for The Movie Database (TMDB). Zero runtime dependencies. Built for Node.js, Bun, and edge runtimes.
|
|
10
|
+
|
|
11
|
+
`tmdb-kit` covers common TMDB workflows: movies, TV shows, search, trending, people, genres, and images. Use it as a library, or run the bundled `tmdb` command in your terminal.
|
|
12
|
+
|
|
13
|
+
## Contents
|
|
14
|
+
|
|
15
|
+
- [Features](#features)
|
|
16
|
+
- [Install](#install)
|
|
17
|
+
- [SDK](#sdk)
|
|
18
|
+
- [Create a client](#create-a-client)
|
|
19
|
+
- [Authentication](#authentication)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Custom transport](#custom-transport)
|
|
22
|
+
- [Supported resources](#supported-resources)
|
|
23
|
+
- [Image URLs](#image-urls)
|
|
24
|
+
- [Search](#search)
|
|
25
|
+
- [Image sizes](#image-sizes)
|
|
26
|
+
- [Errors](#errors)
|
|
27
|
+
- [CLI](#cli)
|
|
28
|
+
- [Credentials and config](#credentials-and-config)
|
|
29
|
+
- [Commands](#commands)
|
|
30
|
+
- [Common options](#common-options)
|
|
31
|
+
- [Output and exit codes](#output-and-exit-codes)
|
|
32
|
+
- [Examples](#examples)
|
|
33
|
+
- [Development](#development)
|
|
34
|
+
- [References](#references)
|
|
12
35
|
|
|
13
36
|
## Features
|
|
14
37
|
|
|
15
|
-
- **Zero dependencies
|
|
16
|
-
- **Universal runtime
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
38
|
+
- **Zero dependencies**: nothing to audit, nothing to conflict.
|
|
39
|
+
- **Universal runtime**: uses only `fetch`, `Headers`, `URL`, and `AbortSignal`. Works on Node.js 18+, Bun, Cloudflare Workers, Vercel Edge, and any fetch-compatible environment.
|
|
40
|
+
- **SDK and CLI**: typed resource methods for your app, plus `tmdb` and `tmdb-kit` binaries for terminal use.
|
|
41
|
+
- **Strict TypeScript**: full type safety with autocomplete for request options, response shapes, image sizes, and error handling.
|
|
42
|
+
- **ESM output**: modern module output with bundled type declarations.
|
|
43
|
+
- **Typed resources**: first-class methods for movies, TV, search, trending, people, genres, configuration, and images.
|
|
44
|
+
- **Injectable transport**: swap the HTTP layer for tests, caching, or instrumentation without mocking `fetch`.
|
|
45
|
+
- **Image helpers**: build content delivery network (CDN), proxy, or signed URLs with per-request transform overrides.
|
|
46
|
+
- **Search type guards**: narrow `search.multi()` results to movies, TV, or people with runtime-checked helpers.
|
|
47
|
+
- **Tested**: unit and resource tests mock `fetch`; an optional live integration suite validates real API behavior.
|
|
24
48
|
|
|
25
49
|
## Install
|
|
26
50
|
|
|
51
|
+
Install the SDK with npm:
|
|
52
|
+
|
|
27
53
|
```bash
|
|
28
54
|
npm install tmdb-kit
|
|
29
55
|
```
|
|
30
56
|
|
|
31
|
-
|
|
57
|
+
Install the CLI globally:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install --global tmdb-kit
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The CLI is available as `tmdb`.
|
|
64
|
+
|
|
65
|
+
## SDK
|
|
66
|
+
|
|
67
|
+
Create a client, authenticate, and call typed resource methods. The client uses the Fetch API and has no runtime dependencies.
|
|
68
|
+
|
|
69
|
+
### Create a client
|
|
32
70
|
|
|
33
71
|
```ts
|
|
34
72
|
import { createTMDB } from 'tmdb-kit'
|
|
@@ -46,79 +84,60 @@ const movie = await tmdb.movies.details(popular.results[0]!.id, {
|
|
|
46
84
|
const posterUrl = tmdb.images.url(movie.poster_path, 'w500')
|
|
47
85
|
```
|
|
48
86
|
|
|
49
|
-
|
|
87
|
+
### Authentication
|
|
50
88
|
|
|
51
|
-
|
|
52
|
-
const { createTMDB } = require('tmdb-kit')
|
|
89
|
+
The SDK targets the TMDB v3 API at `api.themoviedb.org/3`. Two authentication methods are supported.
|
|
53
90
|
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Deno:
|
|
91
|
+
An API Read Access Token is recommended and works with both v3 and v4:
|
|
58
92
|
|
|
59
93
|
```ts
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const tmdb = createTMDB({ accessToken: Deno.env.get('TMDB_ACCESS_TOKEN')! })
|
|
94
|
+
createTMDB({ accessToken: 'your_access_token_here' })
|
|
63
95
|
```
|
|
64
96
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
The SDK targets the **TMDB v3 API** (`api.themoviedb.org/3`). Two authentication methods are supported:
|
|
68
|
-
|
|
69
|
-
**API Read Access Token** (recommended) — works with both v3 and v4:
|
|
97
|
+
A legacy v3 API key is sent as an `api_key` query parameter:
|
|
70
98
|
|
|
71
99
|
```ts
|
|
72
|
-
createTMDB({
|
|
100
|
+
createTMDB({ apiKey: 'your_api_key_here' })
|
|
73
101
|
```
|
|
74
102
|
|
|
75
|
-
|
|
103
|
+
Pass exactly one of `accessToken` or `apiKey`. The client throws when both or neither are set.
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
createTMDB({ apiKey: 'tmdb-v3-api-key' })
|
|
79
|
-
```
|
|
105
|
+
### Configuration
|
|
80
106
|
|
|
81
|
-
|
|
107
|
+
`createTMDB` accepts these options:
|
|
82
108
|
|
|
83
|
-
|
|
109
|
+
| Option | Default | Description |
|
|
110
|
+
| ------------------ | ------------------------------------ | ----------------------------------------------------------------- |
|
|
111
|
+
| `accessToken` | required unless `apiKey` is set | API Read Access Token, sent as a Bearer header. |
|
|
112
|
+
| `apiKey` | required unless `accessToken` is set | Legacy v3 API key, sent as `api_key`. |
|
|
113
|
+
| `baseUrl` | `https://api.themoviedb.org/3` | API base URL. Useful for proxies and tests. |
|
|
114
|
+
| `fetch` | `globalThis.fetch` at request time | Custom fetch implementation. |
|
|
115
|
+
| `defaultLanguage` | TMDB default | Language for endpoints that accept `language`. |
|
|
116
|
+
| `defaultRegion` | TMDB default | Region for movie lists and search endpoints that accept `region`. |
|
|
117
|
+
| `imageBaseUrl` | `https://image.tmdb.org/t/p` | Image host used by `tmdb.images`. |
|
|
118
|
+
| `images.transform` | none | Default URL transform for `tmdb.images.url()`. |
|
|
119
|
+
| `headers` | none | Extra headers merged into every request before authentication. |
|
|
120
|
+
| `transport` | built-in HTTP client | Custom transport, see [Custom transport](#custom-transport). |
|
|
84
121
|
|
|
85
|
-
|
|
122
|
+
A typical client:
|
|
86
123
|
|
|
87
124
|
```ts
|
|
88
|
-
import { createTMDB } from 'tmdb-kit'
|
|
89
|
-
|
|
90
125
|
const tmdb = createTMDB({
|
|
91
|
-
accessToken: '
|
|
92
|
-
|
|
93
|
-
// Defaults to https://api.themoviedb.org/3. Useful for tests or proxies.
|
|
94
|
-
baseUrl: 'https://api.themoviedb.org/3',
|
|
95
|
-
|
|
96
|
-
// Inject a fetch implementation. The SDK reads `globalThis.fetch` lazily
|
|
97
|
-
// on every request, so test-time mocks (vi.spyOn, etc.) are picked up
|
|
98
|
-
// automatically after the client has been constructed.
|
|
99
|
-
fetch: customFetch,
|
|
100
|
-
|
|
101
|
-
// Defaults applied to every request that supports them.
|
|
126
|
+
accessToken: 'your_access_token_here',
|
|
102
127
|
defaultLanguage: 'en-US',
|
|
103
128
|
defaultRegion: 'US',
|
|
104
|
-
|
|
105
|
-
// Custom image host. Defaults to https://image.tmdb.org/t/p.
|
|
106
|
-
imageBaseUrl: 'https://image.tmdb.org/t/p',
|
|
107
|
-
|
|
108
|
-
// Image URL transform applied by the ImagesHelper. See "Image URLs".
|
|
129
|
+
headers: { 'X-Client': 'my-app' },
|
|
109
130
|
images: {
|
|
110
131
|
transform: (url) => url.replace('image.tmdb.org/t/p', 'img-proxy.example/tmdb'),
|
|
111
132
|
},
|
|
112
|
-
|
|
113
|
-
// Extra headers merged into every request before authentication.
|
|
114
|
-
headers: { 'X-Client': 'my-app' },
|
|
115
133
|
})
|
|
116
134
|
```
|
|
117
135
|
|
|
118
|
-
|
|
136
|
+
The SDK reads `globalThis.fetch` lazily on every request. Spies on `globalThis.fetch` are picked up after the client has been constructed.
|
|
137
|
+
|
|
138
|
+
### Custom transport
|
|
119
139
|
|
|
120
|
-
For tests, caching, or instrumentation,
|
|
121
|
-
layer instead of mocking `fetch`:
|
|
140
|
+
For tests, caching, or instrumentation, swap the entire transport layer instead of mocking `fetch`:
|
|
122
141
|
|
|
123
142
|
```ts
|
|
124
143
|
import { createTMDB, type TMDBTransport } from 'tmdb-kit'
|
|
@@ -128,64 +147,25 @@ const stub: TMDBTransport = {
|
|
|
128
147
|
get: async (path, _options) => ({ results: [] }),
|
|
129
148
|
}
|
|
130
149
|
|
|
131
|
-
const tmdb = createTMDB({ accessToken: '
|
|
150
|
+
const tmdb = createTMDB({ accessToken: 'your_access_token_here', transport: stub })
|
|
132
151
|
```
|
|
133
152
|
|
|
134
|
-
`transport.get()`
|
|
135
|
-
escape hatch, so a single stub covers the whole surface area.
|
|
136
|
-
`TMDBTransport` is exported as part of the public API.
|
|
153
|
+
`transport.get()` runs for every resource and for `request()`, so a single stub covers the whole surface. `TMDBTransport` is part of the public API.
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
### Supported resources
|
|
139
156
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
tmdb.movies
|
|
143
|
-
tmdb.
|
|
144
|
-
tmdb.movies
|
|
145
|
-
tmdb.movies
|
|
146
|
-
tmdb.
|
|
147
|
-
tmdb.movies
|
|
148
|
-
tmdb.
|
|
149
|
-
tmdb.
|
|
150
|
-
tmdb.movies.videos(550)
|
|
151
|
-
|
|
152
|
-
tmdb.tv.popular()
|
|
153
|
-
tmdb.tv.topRated()
|
|
154
|
-
tmdb.tv.airingToday()
|
|
155
|
-
tmdb.tv.onTheAir()
|
|
156
|
-
tmdb.tv.details(1399)
|
|
157
|
-
tmdb.tv.credits(1399)
|
|
158
|
-
tmdb.tv.images(1399)
|
|
159
|
-
tmdb.tv.recommendations(1399)
|
|
160
|
-
tmdb.tv.similar(1399)
|
|
161
|
-
tmdb.tv.videos(1399)
|
|
162
|
-
tmdb.tv.seasonDetails(1399, 1)
|
|
163
|
-
|
|
164
|
-
tmdb.search.movies('Dune')
|
|
165
|
-
tmdb.search.tv('Dark')
|
|
166
|
-
tmdb.search.people('Sofia Coppola')
|
|
167
|
-
tmdb.search.multi('Tom Hardy')
|
|
168
|
-
|
|
169
|
-
tmdb.trending.all('week')
|
|
170
|
-
tmdb.trending.movies('day')
|
|
171
|
-
tmdb.trending.tv('day')
|
|
172
|
-
tmdb.trending.people('week')
|
|
173
|
-
|
|
174
|
-
tmdb.people.popular()
|
|
175
|
-
tmdb.people.details(31)
|
|
176
|
-
|
|
177
|
-
tmdb.genres.movies()
|
|
178
|
-
tmdb.genres.tv()
|
|
179
|
-
|
|
180
|
-
tmdb.configuration.details()
|
|
181
|
-
tmdb.configuration.countries()
|
|
182
|
-
tmdb.configuration.jobs()
|
|
183
|
-
tmdb.configuration.languages()
|
|
184
|
-
tmdb.configuration.primaryTranslations()
|
|
185
|
-
tmdb.configuration.timezones()
|
|
186
|
-
```
|
|
157
|
+
| Resource | Methods |
|
|
158
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
159
|
+
| `tmdb.movies` | `popular()`, `topRated()`, `nowPlaying()`, `upcoming()`, `details()`, `credits()`, `images()`, `recommendations()`, `similar()`, `videos()` |
|
|
160
|
+
| `tmdb.tv` | `popular()`, `topRated()`, `airingToday()`, `onTheAir()`, `details()`, `credits()`, `images()`, `recommendations()`, `similar()`, `videos()`, `seasonDetails()` |
|
|
161
|
+
| `tmdb.search` | `movies()`, `tv()`, `people()`, `multi()` |
|
|
162
|
+
| `tmdb.trending` | `all()`, `movies()`, `tv()`, `people()` |
|
|
163
|
+
| `tmdb.people` | `popular()`, `details()`, `combinedCredits()` |
|
|
164
|
+
| `tmdb.genres` | `movies()`, `tv()` |
|
|
165
|
+
| `tmdb.configuration` | `details()`, `countries()`, `jobs()`, `languages()`, `primaryTranslations()`, `timezones()` |
|
|
166
|
+
| `tmdb.images` | `url()` |
|
|
187
167
|
|
|
188
|
-
For an endpoint that is not wrapped yet:
|
|
168
|
+
For an endpoint that is not wrapped yet, use the `request()` escape hatch:
|
|
189
169
|
|
|
190
170
|
```ts
|
|
191
171
|
const response = await tmdb.request<{ results: unknown[] }>('/discover/movie', {
|
|
@@ -196,34 +176,29 @@ const response = await tmdb.request<{ results: unknown[] }>('/discover/movie', {
|
|
|
196
176
|
})
|
|
197
177
|
```
|
|
198
178
|
|
|
199
|
-
|
|
179
|
+
### Image URLs
|
|
200
180
|
|
|
201
|
-
`tmdb.images.url(path, size)` builds a fully
|
|
202
|
-
helper returns `null` for nullish paths so UI code can branch naturally:
|
|
181
|
+
`tmdb.images.url(path, size)` builds a fully qualified image URL. It returns `null` for nullish paths so UI code can branch naturally:
|
|
203
182
|
|
|
204
183
|
```ts
|
|
205
184
|
const posterUrl = tmdb.images.url(movie.poster_path, 'w500')
|
|
206
185
|
```
|
|
207
186
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
Pass a `transform` callback to rewrite the resolved URL. The most common
|
|
211
|
-
use case is pointing TMDB image requests at a self-hosted proxy:
|
|
187
|
+
Pass a `transform` callback to route images through a CDN or proxy:
|
|
212
188
|
|
|
213
189
|
```ts
|
|
214
190
|
const tmdb = createTMDB({
|
|
215
|
-
accessToken: '
|
|
191
|
+
accessToken: 'your_access_token_here',
|
|
216
192
|
images: {
|
|
217
193
|
transform: (url) => url.replace('https://image.tmdb.org/t/p', 'https://img-proxy.example/tmdb'),
|
|
218
194
|
},
|
|
219
195
|
})
|
|
220
196
|
|
|
221
197
|
tmdb.images.url('/abc.jpg', 'w500')
|
|
222
|
-
//
|
|
198
|
+
// 'https://img-proxy.example/tmdb/w500/abc.jpg'
|
|
223
199
|
```
|
|
224
200
|
|
|
225
|
-
|
|
226
|
-
signed query parameters for selected sizes:
|
|
201
|
+
Pass a one-off transform per call to add signed query parameters:
|
|
227
202
|
|
|
228
203
|
```ts
|
|
229
204
|
tmdb.images.url('/abc.jpg', 'original', {
|
|
@@ -231,25 +206,14 @@ tmdb.images.url('/abc.jpg', 'original', {
|
|
|
231
206
|
})
|
|
232
207
|
```
|
|
233
208
|
|
|
234
|
-
The transform is never invoked for nullish paths, so `null` results stay
|
|
235
|
-
`null`.
|
|
236
|
-
|
|
237
|
-
`buildImageUrl(path, size, options)` is exported directly for callers
|
|
238
|
-
that want to build URLs without a `TMDBClient` instance.
|
|
209
|
+
The transform is never invoked for nullish paths, so `null` results stay `null`. `buildImageUrl(path, size, options)` is exported for callers that build URLs without a `TMDBClient` instance.
|
|
239
210
|
|
|
240
|
-
|
|
211
|
+
### Search
|
|
241
212
|
|
|
242
|
-
`search.multi()` returns a union of movie
|
|
243
|
-
out media types you do not want and narrow the result type with the
|
|
244
|
-
provided type guards:
|
|
213
|
+
`search.multi()` returns a union of movie, TV, and person results. Filter media types and narrow the result type with the provided type guards:
|
|
245
214
|
|
|
246
215
|
```ts
|
|
247
|
-
import {
|
|
248
|
-
createTMDB,
|
|
249
|
-
isMovieSearchResult,
|
|
250
|
-
isTVSearchResult,
|
|
251
|
-
isPersonSearchResult,
|
|
252
|
-
} from 'tmdb-kit'
|
|
216
|
+
import { createTMDB, isMovieSearchResult, isTVSearchResult, isPersonSearchResult } from 'tmdb-kit'
|
|
253
217
|
|
|
254
218
|
const { results } = await tmdb.search.multi('Inception', {
|
|
255
219
|
exclude: ['person'],
|
|
@@ -260,104 +224,235 @@ const tvShows = results.filter(isTVSearchResult) // TVMultiResult[]
|
|
|
260
224
|
const people = results.filter(isPersonSearchResult) // PersonMultiResult[]
|
|
261
225
|
```
|
|
262
226
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- Short-name aliases `isMovie` / `isTV` / `isPerson` are also exported
|
|
267
|
-
for callers that prefer them.
|
|
268
|
-
- The single-resource search methods (`search.movies`, `search.tv`,
|
|
269
|
-
`search.people`) already return the narrowed result type, so the
|
|
270
|
-
guards are only useful for `search.multi()` payloads.
|
|
227
|
+
`exclude` performs client-side filtering because the TMDB multi-search endpoint has no server-side media type filter. `total_results` reflects the unfiltered payload, and the filtered count is `results.length`.
|
|
228
|
+
|
|
229
|
+
The short-name aliases `isMovie`, `isTV`, and `isPerson` are also exported. The single-resource search methods already return narrowed types, so the guards matter only for `search.multi()`.
|
|
271
230
|
|
|
272
|
-
|
|
231
|
+
### Image sizes
|
|
273
232
|
|
|
274
|
-
The `ImageSize` type is intentionally permissive
|
|
275
|
-
sizes in the past (e.g. `h632` for profile) without notice, and the SDK
|
|
276
|
-
keeps the `(string & {})` escape hatch so any future size keeps
|
|
277
|
-
working at runtime. If you need the canonical set of documented sizes,
|
|
278
|
-
the SDK ships them as readonly constants:
|
|
233
|
+
The `ImageSize` type is intentionally permissive. TMDB has added sizes without notice, such as `h632` for profiles, so the SDK keeps the `(string & {})` escape hatch for forward compatibility. The SDK also ships the documented sizes as readonly constants:
|
|
279
234
|
|
|
280
235
|
```ts
|
|
281
|
-
import {
|
|
282
|
-
|
|
283
|
-
KNOWN_LOGO_SIZES,
|
|
284
|
-
KNOWN_POSTER_SIZES,
|
|
285
|
-
KNOWN_PROFILE_SIZES,
|
|
286
|
-
KNOWN_STILL_SIZES,
|
|
287
|
-
KNOWN_IMAGE_SIZES,
|
|
288
|
-
isKnownBackdropSize,
|
|
289
|
-
isKnownImageSize,
|
|
290
|
-
// …plus one helper per type
|
|
291
|
-
} from 'tmdb-kit'
|
|
292
|
-
|
|
293
|
-
// Iterate to build a size picker
|
|
236
|
+
import { KNOWN_POSTER_SIZES, isKnownPosterSize } from 'tmdb-kit'
|
|
237
|
+
|
|
294
238
|
for (const size of KNOWN_POSTER_SIZES) {
|
|
295
239
|
console.log(size) // 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original'
|
|
296
240
|
}
|
|
297
241
|
|
|
298
|
-
// Validate user-supplied sizes at runtime
|
|
299
242
|
if (!isKnownPosterSize(userInput)) {
|
|
300
243
|
throw new Error(`Unknown TMDB poster size: ${userInput}`)
|
|
301
244
|
}
|
|
302
245
|
```
|
|
303
246
|
|
|
304
|
-
`
|
|
305
|
-
`KnownProfileSize` / `KnownStillSize` / `KnownImageSize` are the
|
|
306
|
-
matching TS literal-union types for callers that want strict typing
|
|
307
|
-
without giving up forward-compatibility.
|
|
247
|
+
The SDK also exports `KNOWN_BACKDROP_SIZES`, `KNOWN_LOGO_SIZES`, `KNOWN_PROFILE_SIZES`, `KNOWN_STILL_SIZES`, `KNOWN_IMAGE_SIZES`, and a matching type guard for each list. The literal-union types are `KnownBackdropSize`, `KnownPosterSize`, `KnownLogoSize`, `KnownProfileSize`, `KnownStillSize`, and `KnownImageSize`.
|
|
308
248
|
|
|
309
|
-
|
|
249
|
+
### Errors
|
|
310
250
|
|
|
311
251
|
```ts
|
|
312
|
-
import {
|
|
313
|
-
TMDBRateLimitError,
|
|
314
|
-
TMDBRequestError,
|
|
315
|
-
TMDBResponseError,
|
|
316
|
-
} from 'tmdb-kit'
|
|
252
|
+
import { TMDBRateLimitError, TMDBRequestError, TMDBResponseError } from 'tmdb-kit'
|
|
317
253
|
|
|
318
254
|
try {
|
|
319
255
|
await tmdb.movies.popular()
|
|
320
256
|
} catch (error) {
|
|
321
257
|
if (error instanceof TMDBRateLimitError) {
|
|
322
|
-
// 429
|
|
323
|
-
// automatically; back off for `retryAfter` seconds (or use your own
|
|
324
|
-
// policy) and try again.
|
|
258
|
+
// 429: TMDB asked the caller to back off. The SDK does not retry.
|
|
325
259
|
console.log('rate limited; retry in', error.retryAfter, 's')
|
|
326
260
|
} else if (error instanceof TMDBResponseError) {
|
|
327
261
|
console.log(error.status, error.statusCode, error.statusMessage)
|
|
328
262
|
} else if (error instanceof TMDBRequestError) {
|
|
329
|
-
//
|
|
330
|
-
// error, no fetch implementation found, or invalid client configuration).
|
|
263
|
+
// Network failure, missing fetch, or invalid client configuration.
|
|
331
264
|
console.log('request error:', error.message)
|
|
332
265
|
}
|
|
333
266
|
}
|
|
334
267
|
```
|
|
335
268
|
|
|
336
|
-
`TMDBResponseError` exposes convenience getters for
|
|
337
|
-
|
|
269
|
+
`TMDBResponseError` exposes convenience getters for common status codes:
|
|
270
|
+
|
|
271
|
+
| Getter | Status |
|
|
272
|
+
| ---------------- | ------ |
|
|
273
|
+
| `isUnauthorized` | 401 |
|
|
274
|
+
| `isForbidden` | 403 |
|
|
275
|
+
| `isNotFound` | 404 |
|
|
276
|
+
| `isRateLimit` | 429 |
|
|
277
|
+
| `isServerError` | 5xx |
|
|
278
|
+
|
|
279
|
+
All errors extend `TMDBError`, which you can use as a single catch-all.
|
|
280
|
+
|
|
281
|
+
## CLI
|
|
282
|
+
|
|
283
|
+
The `tmdb` command is a read-only client for the same TMDB API. It reads credentials from the environment or a config file, prints human-readable summaries by default, and accepts `--json` for raw TMDB payloads.
|
|
284
|
+
|
|
285
|
+
The CLI runs on Node.js 18+ and Bun.
|
|
338
286
|
|
|
339
|
-
|
|
340
|
-
| --- | --- |
|
|
341
|
-
| `isUnauthorized` | 401 |
|
|
342
|
-
| `isForbidden` | 403 |
|
|
343
|
-
| `isNotFound` | 404 |
|
|
344
|
-
| `isRateLimit` | 429 |
|
|
345
|
-
| `isServerError` | 5xx |
|
|
287
|
+
### Credentials and config
|
|
346
288
|
|
|
347
|
-
|
|
348
|
-
|
|
289
|
+
The CLI checks credentials in this order:
|
|
290
|
+
|
|
291
|
+
1. `TMDB_ACCESS_TOKEN`
|
|
292
|
+
2. `TMDB_API_KEY` (legacy v3 API key)
|
|
293
|
+
3. `accessToken` in the config file
|
|
294
|
+
4. `apiKey` in the config file
|
|
295
|
+
|
|
296
|
+
Environment variables take precedence over the config file. `TMDB_BASE_URL` overrides the API base URL for every command.
|
|
297
|
+
|
|
298
|
+
The config file lives at:
|
|
299
|
+
|
|
300
|
+
- Windows: `%APPDATA%\tmdb-kit\config.json`
|
|
301
|
+
- macOS and Linux: `$XDG_CONFIG_HOME/tmdb-kit/config.json`, or `~/.config/tmdb-kit/config.json` when `XDG_CONFIG_HOME` is unset
|
|
302
|
+
|
|
303
|
+
On Unix, the directory is created with mode `0700` and the file with mode `0600`.
|
|
304
|
+
|
|
305
|
+
Set up credentials with the auth commands:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
tmdb auth login # prompt, validate, and save a credential
|
|
309
|
+
tmdb auth login --force # replace existing credentials
|
|
310
|
+
printf '%s' "$TMDB_ACCESS_TOKEN" | tmdb auth login --token-stdin --force
|
|
311
|
+
tmdb auth status # source, masked token, and config path
|
|
312
|
+
tmdb auth logout # remove saved credentials
|
|
313
|
+
tmdb config test # verify credentials with a TMDB request
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`auth login` validates the credential with a TMDB request before saving it. `config test` performs the same check without changing the config. Use `--force` to replace existing credentials, or to save a config token while an environment variable is set and stdin is not a TTY.
|
|
317
|
+
|
|
318
|
+
Manage defaults with `config`:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
tmdb config set language zh-CN
|
|
322
|
+
tmdb config set region CN
|
|
323
|
+
tmdb config set token # prompts; secrets are not accepted as arguments
|
|
324
|
+
tmdb config unset language
|
|
325
|
+
tmdb config show # masked values and config path
|
|
326
|
+
tmdb config path
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Config keys are `token` or `accessToken`, `api-key` or `apiKey`, `language`, and `region`. Secrets entered with `config set token` or `config set api-key` are read from a prompt, never from the command line. `auth status` and `config show` mask stored secrets.
|
|
330
|
+
|
|
331
|
+
Use `--lang` to override the config language for a single command. `auth logout` removes saved credentials but leaves environment variables in place.
|
|
332
|
+
|
|
333
|
+
### Commands
|
|
334
|
+
|
|
335
|
+
Every API command accepts `--lang` and `--json`. Run `tmdb <command> --help` for the full option list.
|
|
336
|
+
|
|
337
|
+
| Command | Description | Command options |
|
|
338
|
+
| --------------------------------- | --------------------------------------------------------------------------------- | ---------------------------- |
|
|
339
|
+
| `tmdb search <query>` | Search all media, movies, TV, or people. | `--type`, `--year`, `--page` |
|
|
340
|
+
| `tmdb movie list [category]` | List movies. Default `popular`; also `top-rated`, `now-playing`, `upcoming`. | `--page`, `--region` |
|
|
341
|
+
| `tmdb movie get <id>` | Movie details. | `--append` |
|
|
342
|
+
| `tmdb movie credits <id>` | Movie cast and crew. | `--limit` |
|
|
343
|
+
| `tmdb movie images <id>` | Movie image URLs. | `--image-language` |
|
|
344
|
+
| `tmdb movie videos <id>` | Movie videos and trailers. | none |
|
|
345
|
+
| `tmdb movie similar <id>` | Similar movies. | `--page`, `--region` |
|
|
346
|
+
| `tmdb movie recommendations <id>` | Recommended movies. | `--page`, `--region` |
|
|
347
|
+
| `tmdb tv list [category]` | List TV shows. Default `popular`; also `top-rated`, `airing-today`, `on-the-air`. | `--page` |
|
|
348
|
+
| `tmdb tv get <id>` | TV show details. | `--append` |
|
|
349
|
+
| `tmdb tv credits <id>` | TV cast and crew. | `--limit` |
|
|
350
|
+
| `tmdb tv images <id>` | TV image URLs. | `--image-language` |
|
|
351
|
+
| `tmdb tv videos <id>` | TV videos and trailers. | none |
|
|
352
|
+
| `tmdb tv similar <id>` | Similar TV shows. | `--page` |
|
|
353
|
+
| `tmdb tv recommendations <id>` | Recommended TV shows. | `--page` |
|
|
354
|
+
| `tmdb tv season <id> <season>` | TV season and episodes. Use `0` for specials. | none |
|
|
355
|
+
| `tmdb person get <id>` | Person details. | none |
|
|
356
|
+
| `tmdb person credits <id>` | Combined cast and crew credits. | `--limit` |
|
|
357
|
+
| `tmdb trending [type]` | Trending media. Default `all`; also `movie`, `tv`, `person`. | `--window`, `--page` |
|
|
358
|
+
| `tmdb genres [type]` | Genres. Default `movie`; also `tv`. | none |
|
|
359
|
+
|
|
360
|
+
Credential and config commands:
|
|
361
|
+
|
|
362
|
+
| Command | Description | Command options |
|
|
363
|
+
| ------------------------------- | ------------------------------------------------------ | -------------------------- |
|
|
364
|
+
| `tmdb auth login` | Validate and save credentials. | `--token-stdin`, `--force` |
|
|
365
|
+
| `tmdb auth status` | Show credential source, masked token, and config path. | `--json` |
|
|
366
|
+
| `tmdb auth logout` | Remove saved credentials. | none |
|
|
367
|
+
| `tmdb config show` | Show config values with secrets masked. | `--json` |
|
|
368
|
+
| `tmdb config path` | Print the config file path. | none |
|
|
369
|
+
| `tmdb config test` | Verify credentials with an authenticated request. | `--json` |
|
|
370
|
+
| `tmdb config set <key> [value]` | Set `token`, `api-key`, `language`, or `region`. | none |
|
|
371
|
+
| `tmdb config unset <key>` | Remove a config value. | none |
|
|
372
|
+
|
|
373
|
+
### Common options
|
|
374
|
+
|
|
375
|
+
| Option | Description |
|
|
376
|
+
| ------------------------- | ---------------------------------------------------------------------------------- |
|
|
377
|
+
| `--json` | Print the raw TMDB JSON response instead of the formatted summary. |
|
|
378
|
+
| `--lang <code>` | Language for this command. Defaults to config `language`, then `en-US`. |
|
|
379
|
+
| `--page <number>` | Page number. Defaults to `1`. |
|
|
380
|
+
| `--region <code>` | Region for movie lists, similar, and recommendations. Defaults to config `region`. |
|
|
381
|
+
| `--limit <number>` | Maximum rows for credits. Defaults to `10`. |
|
|
382
|
+
| `--append <list>` | Comma-separated `append_to_response` values, such as `credits,videos`. |
|
|
383
|
+
| `--image-language <list>` | Comma-separated image language codes. |
|
|
384
|
+
| `--year <year>` | Movie release year or TV first-air year. Only with `--type movie` or `--type tv`. |
|
|
385
|
+
| `--type <value>` | Media selector for `search`: `all`, `movie`, `tv`, or `person`. |
|
|
386
|
+
| `--window <day\|week>` | Trending window. Defaults to `week`. |
|
|
387
|
+
|
|
388
|
+
`--version` prints the CLI version.
|
|
389
|
+
|
|
390
|
+
### Output and exit codes
|
|
391
|
+
|
|
392
|
+
The default output is a compact summary for reading in a terminal. Use `--json` for scripts:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
tmdb movie get 550 --json | jq '.title, .release_date'
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Exit codes:
|
|
399
|
+
|
|
400
|
+
| Code | Meaning |
|
|
401
|
+
| ---- | -------------------------------------------------------------- |
|
|
402
|
+
| `0` | Success. |
|
|
403
|
+
| `1` | Unexpected error, network failure, or non-auth TMDB response. |
|
|
404
|
+
| `2` | Invalid command usage or input. |
|
|
405
|
+
| `3` | Missing or rejected credentials, or a config read/write error. |
|
|
406
|
+
| `4` | TMDB returned `404 Not Found`. |
|
|
407
|
+
| `5` | TMDB rate limit (`429 Too Many Requests`). |
|
|
408
|
+
|
|
409
|
+
### Examples
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
# Search movies released in 2010
|
|
413
|
+
tmdb search "Inception" --type movie --year 2010
|
|
414
|
+
|
|
415
|
+
# Movie details with credits and videos
|
|
416
|
+
tmdb movie get 550 --append credits,videos
|
|
417
|
+
|
|
418
|
+
# Trending movies today, raw JSON
|
|
419
|
+
tmdb trending movie --window day --json | jq '.results[].title'
|
|
420
|
+
|
|
421
|
+
# Season 1 episodes for a TV show
|
|
422
|
+
tmdb tv season 1399 1 --json | jq '.episodes[].name'
|
|
423
|
+
|
|
424
|
+
# Save defaults for later commands
|
|
425
|
+
tmdb config set language zh-CN
|
|
426
|
+
tmdb config set region CN
|
|
427
|
+
```
|
|
349
428
|
|
|
350
429
|
## Development
|
|
351
430
|
|
|
431
|
+
Requires [Bun](https://bun.sh) 1.4.4+. The published package still runs on Node.js 18+.
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
bun install
|
|
435
|
+
bun run format
|
|
436
|
+
bun run typecheck
|
|
437
|
+
bun run test:coverage
|
|
438
|
+
bun run build
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
Run the integration suite with a real token:
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
TMDB_ACCESS_TOKEN=your_access_token_here bun run test:integration
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Build and run the CLI from source:
|
|
448
|
+
|
|
352
449
|
```bash
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
npm run test:coverage
|
|
356
|
-
npm run build
|
|
450
|
+
bun run build:cli
|
|
451
|
+
bun dist/cli.js --help
|
|
357
452
|
```
|
|
358
453
|
|
|
359
454
|
## References
|
|
360
455
|
|
|
361
456
|
- [TMDB authentication](https://developer.themoviedb.org/docs/authentication-application)
|
|
362
457
|
- [TMDB API reference](https://developer.themoviedb.org/reference/intro/getting-started)
|
|
363
|
-
- [
|
|
458
|
+
- [Bun bundler docs](https://bun.com/docs/bundler)
|