tmdb-kit 1.1.0 → 1.2.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 +243 -79
- package/dist/cli.js +1068 -377
- package/dist/client.d.cts +13 -5
- package/dist/client.d.ts +13 -5
- package/dist/errors.d.cts +13 -1
- package/dist/errors.d.ts +13 -1
- package/dist/helpers/cache.d.cts +28 -0
- package/dist/helpers/cache.d.ts +28 -0
- package/dist/helpers/pagination.d.cts +35 -0
- package/dist/helpers/pagination.d.ts +35 -0
- package/dist/helpers/retry.d.cts +47 -0
- package/dist/helpers/retry.d.ts +47 -0
- package/dist/helpers/timeout.d.cts +20 -0
- package/dist/helpers/timeout.d.ts +20 -0
- package/dist/index.cjs +422 -54
- package/dist/index.cjs.map +18 -14
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +422 -54
- package/dist/index.js.map +18 -14
- package/dist/query.d.cts +14 -0
- package/dist/query.d.ts +14 -0
- package/dist/resources/configuration.d.cts +7 -7
- package/dist/resources/configuration.d.ts +7 -7
- package/dist/resources/movies.d.cts +3 -3
- package/dist/resources/movies.d.ts +3 -3
- package/dist/resources/tv.d.cts +9 -1
- package/dist/resources/tv.d.ts +9 -1
- package/dist/types.d.cts +100 -2
- package/dist/types.d.ts +100 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,11 +19,13 @@ A minimal, fully typed SDK and read-only command-line interface (CLI) for The Mo
|
|
|
19
19
|
- [Authentication](#authentication)
|
|
20
20
|
- [Configuration](#configuration)
|
|
21
21
|
- [Custom transport](#custom-transport)
|
|
22
|
+
- [Cancellation](#cancellation)
|
|
22
23
|
- [Supported resources](#supported-resources)
|
|
23
24
|
- [Image URLs](#image-urls)
|
|
24
25
|
- [Search](#search)
|
|
25
26
|
- [Image sizes](#image-sizes)
|
|
26
27
|
- [Errors](#errors)
|
|
28
|
+
- [Optional helpers](#optional-helpers)
|
|
27
29
|
- [CLI](#cli)
|
|
28
30
|
- [Credentials and config](#credentials-and-config)
|
|
29
31
|
- [Commands](#commands)
|
|
@@ -42,9 +44,10 @@ A minimal, fully typed SDK and read-only command-line interface (CLI) for The Mo
|
|
|
42
44
|
- **ESM output**: modern module output with bundled type declarations.
|
|
43
45
|
- **Typed resources**: first-class methods for movies, TV, search, trending, people, genres, configuration, and images.
|
|
44
46
|
- **Injectable transport**: swap the HTTP layer for tests, caching, or instrumentation without mocking `fetch`.
|
|
47
|
+
- **Optional helpers**: async pagination, `Retry-After`-aware retries, `AbortSignal` timeouts, and an LRU memory cache — all opt-in and tree-shakeable.
|
|
45
48
|
- **Image helpers**: build content delivery network (CDN), proxy, or signed URLs with per-request transform overrides.
|
|
46
49
|
- **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.
|
|
50
|
+
- **Tested**: unit and resource tests mock `fetch`; an optional live integration suite validates real API behavior, including the helpers.
|
|
48
51
|
|
|
49
52
|
## Install
|
|
50
53
|
|
|
@@ -100,24 +103,24 @@ A legacy v3 API key is sent as an `api_key` query parameter:
|
|
|
100
103
|
createTMDB({ apiKey: 'your_api_key_here' })
|
|
101
104
|
```
|
|
102
105
|
|
|
103
|
-
Pass exactly one of `accessToken` or `apiKey`. The client throws when both or neither are set.
|
|
106
|
+
Pass exactly one of `accessToken` or `apiKey`. The client throws when both or neither are set. When you supply a `transport`, credentials are optional because the transport owns authentication.
|
|
104
107
|
|
|
105
108
|
### Configuration
|
|
106
109
|
|
|
107
110
|
`createTMDB` accepts these options:
|
|
108
111
|
|
|
109
|
-
| Option | Default
|
|
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`
|
|
114
|
-
| `fetch` | `globalThis.fetch` at request time
|
|
115
|
-
| `defaultLanguage` | TMDB default
|
|
116
|
-
| `defaultRegion` | TMDB default
|
|
117
|
-
| `imageBaseUrl` | `https://image.tmdb.org/t/p`
|
|
118
|
-
| `images.transform` | none
|
|
119
|
-
| `headers` | none
|
|
120
|
-
| `transport` | built-in HTTP client
|
|
112
|
+
| Option | Default | Description |
|
|
113
|
+
| ------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
114
|
+
| `accessToken` | required unless `apiKey` or `transport` is set | API Read Access Token, sent as a Bearer header. |
|
|
115
|
+
| `apiKey` | required unless `accessToken` or `transport` is set | Legacy v3 API key, sent as `api_key`. |
|
|
116
|
+
| `baseUrl` | `https://api.themoviedb.org/3` | API base URL. Useful for proxies and tests. |
|
|
117
|
+
| `fetch` | `globalThis.fetch` at request time | Custom fetch implementation. |
|
|
118
|
+
| `defaultLanguage` | TMDB default | Language for endpoints that accept `language`. |
|
|
119
|
+
| `defaultRegion` | TMDB default | Region for movie lists and search endpoints that accept `region`. |
|
|
120
|
+
| `imageBaseUrl` | `https://image.tmdb.org/t/p` | Image host used by `tmdb.images`. |
|
|
121
|
+
| `images.transform` | none | Default URL transform for `tmdb.images.url()`. |
|
|
122
|
+
| `headers` | none | Extra headers merged into every request before authentication. |
|
|
123
|
+
| `transport` | built-in HTTP client | Custom transport; credentials are not required. See [Custom transport](#custom-transport). |
|
|
121
124
|
|
|
122
125
|
A typical client:
|
|
123
126
|
|
|
@@ -147,23 +150,37 @@ const stub: TMDBTransport = {
|
|
|
147
150
|
get: async (path, _options) => ({ results: [] }),
|
|
148
151
|
}
|
|
149
152
|
|
|
150
|
-
const tmdb = createTMDB({
|
|
153
|
+
const tmdb = createTMDB({ transport: stub })
|
|
151
154
|
```
|
|
152
155
|
|
|
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.
|
|
156
|
+
`transport.get()` runs for every resource and for `request()`, so a single stub covers the whole surface. `TMDBTransport` is part of the public API. The built-in `TMDBHttpClient` is exported too, so you can wrap it instead of reimplementing authentication.
|
|
157
|
+
|
|
158
|
+
### Cancellation
|
|
159
|
+
|
|
160
|
+
Every resource method accepts an `AbortSignal` through its options. Pass the same signal to cancel one or more requests:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const controller = new AbortController()
|
|
164
|
+
const promise = tmdb.movies.popular({ signal: controller.signal })
|
|
165
|
+
|
|
166
|
+
controller.abort()
|
|
167
|
+
await promise // rejects with an AbortError
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`client.request()` accepts the same `signal`. The SDK does not impose a timeout by default; use the optional `withTimeout()` helper (see [Optional helpers](#optional-helpers)) or your runtime's `AbortSignal.timeout()` when you need one.
|
|
154
171
|
|
|
155
172
|
### Supported resources
|
|
156
173
|
|
|
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()`
|
|
174
|
+
| Resource | Methods |
|
|
175
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
176
|
+
| `tmdb.movies` | `popular()`, `topRated()`, `nowPlaying()`, `upcoming()`, `details()`, `credits()`, `images()`, `recommendations()`, `similar()`, `videos()` |
|
|
177
|
+
| `tmdb.tv` | `popular()`, `topRated()`, `airingToday()`, `onTheAir()`, `details()`, `credits()`, `images()`, `recommendations()`, `similar()`, `videos()`, `seasonDetails()`, `seasonCredits()`, `seasonAggregateCredits()`, `seasonImages()`, `seasonVideos()`, `episodeDetails()`, `aggregateCredits()`, `episodeGroups()`, `episodeGroup()` |
|
|
178
|
+
| `tmdb.search` | `movies()`, `tv()`, `people()`, `multi()` |
|
|
179
|
+
| `tmdb.trending` | `all()`, `movies()`, `tv()`, `people()` |
|
|
180
|
+
| `tmdb.people` | `popular()`, `details()`, `combinedCredits()` |
|
|
181
|
+
| `tmdb.genres` | `movies()`, `tv()` |
|
|
182
|
+
| `tmdb.configuration` | `details()`, `countries()`, `jobs()`, `languages()`, `primaryTranslations()`, `timezones()` |
|
|
183
|
+
| `tmdb.images` | `url()` |
|
|
167
184
|
|
|
168
185
|
For an endpoint that is not wrapped yet, use the `request()` escape hatch:
|
|
169
186
|
|
|
@@ -249,19 +266,23 @@ The SDK also exports `KNOWN_BACKDROP_SIZES`, `KNOWN_LOGO_SIZES`, `KNOWN_PROFILE_
|
|
|
249
266
|
### Errors
|
|
250
267
|
|
|
251
268
|
```ts
|
|
252
|
-
import { TMDBRateLimitError, TMDBRequestError, TMDBResponseError } from 'tmdb-kit'
|
|
269
|
+
import { TMDBRateLimitError, TMDBRequestError, TMDBResponseError, TMDBTimeoutError } from 'tmdb-kit'
|
|
253
270
|
|
|
254
271
|
try {
|
|
255
272
|
await tmdb.movies.popular()
|
|
256
273
|
} catch (error) {
|
|
257
274
|
if (error instanceof TMDBRateLimitError) {
|
|
258
|
-
// 429: TMDB asked the caller to back off. The SDK does not retry
|
|
275
|
+
// 429: TMDB asked the caller to back off. The SDK does not retry by
|
|
276
|
+
// default; use retry() or withRetry() if you want automatic backoff.
|
|
259
277
|
console.log('rate limited; retry in', error.retryAfter, 's')
|
|
260
278
|
} else if (error instanceof TMDBResponseError) {
|
|
261
279
|
console.log(error.status, error.statusCode, error.statusMessage)
|
|
262
280
|
} else if (error instanceof TMDBRequestError) {
|
|
263
281
|
// Network failure, missing fetch, or invalid client configuration.
|
|
264
282
|
console.log('request error:', error.message)
|
|
283
|
+
} else if (error instanceof TMDBTimeoutError) {
|
|
284
|
+
// Thrown by withTimeout(), not by the HTTP layer.
|
|
285
|
+
console.log('timed out after', error.timeoutMs, 'ms')
|
|
265
286
|
}
|
|
266
287
|
}
|
|
267
288
|
```
|
|
@@ -276,11 +297,71 @@ try {
|
|
|
276
297
|
| `isRateLimit` | 429 |
|
|
277
298
|
| `isServerError` | 5xx |
|
|
278
299
|
|
|
279
|
-
All errors extend `TMDBError`, which you can use as a single catch-all.
|
|
300
|
+
All errors extend `TMDBError`, which you can use as a single catch-all. `TMDBTimeoutError` is thrown by `withTimeout()` and exposes `timeoutMs`; the HTTP layer never throws it directly.
|
|
301
|
+
|
|
302
|
+
### Optional helpers
|
|
303
|
+
|
|
304
|
+
These helpers are opt-in and never change the default client behavior. They are exported from the package root and tree-shake out of ESM bundles when unused.
|
|
305
|
+
|
|
306
|
+
**Pagination**
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { paginate, paginateItems } from 'tmdb-kit'
|
|
310
|
+
|
|
311
|
+
for await (const page of paginate((page) => tmdb.movies.popular({ page, region: 'CN' }))) {
|
|
312
|
+
console.log(page.page, page.results.length)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Or iterate items directly.
|
|
316
|
+
for await (const movie of paginateItems((page) => tmdb.movies.popular({ page }))) {
|
|
317
|
+
console.log(movie.title)
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`startPage` defaults to 1. `paginate` stops at `total_pages`, an empty page, `endPage` (default 500), or an aborted signal. `endPage` is the last page number to request, so it yields nothing when it is lower than `startPage`.
|
|
322
|
+
|
|
323
|
+
**Retry**
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
import { createTMDB, retry, TMDBHttpClient, withRetry } from 'tmdb-kit'
|
|
327
|
+
|
|
328
|
+
// Wrap one call.
|
|
329
|
+
const movie = await retry(() => tmdb.movies.details(550), { retries: 3 })
|
|
330
|
+
|
|
331
|
+
// Or wrap the transport once. The transport owns authentication, so the
|
|
332
|
+
// factory does not need credentials.
|
|
333
|
+
const http = new TMDBHttpClient({ accessToken: 'your_access_token_here' })
|
|
334
|
+
const retrying = createTMDB({ transport: withRetry(http, { retries: 3 }) })
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Retries 429 and any response that carries `Retry-After` (including 503), retries 408, 5xx and network failures with exponential backoff, and leaves other errors untouched. Defaults are 2 retries, a 250 ms base delay, factor 2, full jitter, and a 60 s cap on `Retry-After`; use `retryOn` to replace the predicate and `onRetry` to observe delays. A wrapper-level `signal` and a per-request `signal` are combined, so aborting either cancels the call. The SDK itself still never retries by default.
|
|
338
|
+
|
|
339
|
+
**Timeout**
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
import { withTimeout } from 'tmdb-kit'
|
|
343
|
+
|
|
344
|
+
const movie = await withTimeout(5_000, (signal) => tmdb.movies.details(550, { signal }))
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Timeouts reject with `TMDBTimeoutError`. The task must forward the signal to the SDK. Pass a parent `signal` in the options to cancel it externally; the parent's reason is preserved.
|
|
348
|
+
|
|
349
|
+
**Memory cache**
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
import { createTMDB, TMDBHttpClient, withMemoryCache } from 'tmdb-kit'
|
|
353
|
+
|
|
354
|
+
const http = new TMDBHttpClient({ accessToken: 'your_access_token_here' })
|
|
355
|
+
const cached = createTMDB({
|
|
356
|
+
transport: withMemoryCache(http, { ttlMs: 60_000, maxEntries: 200 }),
|
|
357
|
+
})
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Defaults are a 5-minute TTL and 100 entries. The cache key includes the path, query, and headers, only successful responses are stored, and `clear()` invalidates every entry. Use one cache instance per client or credential: authentication is not part of the key.
|
|
280
361
|
|
|
281
362
|
## CLI
|
|
282
363
|
|
|
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.
|
|
364
|
+
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 `--format json` (or its `--json` alias) for raw TMDB payloads and `--format ndjson` for line-oriented output.
|
|
284
365
|
|
|
285
366
|
The CLI runs on Node.js 18+ and Bun.
|
|
286
367
|
|
|
@@ -332,69 +413,144 @@ Use `--lang` to override the config language for a single command. `auth logout`
|
|
|
332
413
|
|
|
333
414
|
### Commands
|
|
334
415
|
|
|
335
|
-
Every API command accepts `--lang` and `--
|
|
336
|
-
|
|
337
|
-
| Command
|
|
338
|
-
|
|
|
339
|
-
| `tmdb search <query>`
|
|
340
|
-
| `tmdb movie list [category]`
|
|
341
|
-
| `tmdb movie get <id>`
|
|
342
|
-
| `tmdb movie credits <id>`
|
|
343
|
-
| `tmdb movie images <id>`
|
|
344
|
-
| `tmdb movie videos <id>`
|
|
345
|
-
| `tmdb movie similar <id>`
|
|
346
|
-
| `tmdb movie recommendations <id>`
|
|
347
|
-
| `tmdb tv list [category]`
|
|
348
|
-
| `tmdb tv get <id>`
|
|
349
|
-
| `tmdb tv credits <id>`
|
|
350
|
-
| `tmdb tv images <id>`
|
|
351
|
-
| `tmdb tv videos <id>`
|
|
352
|
-
| `tmdb tv similar <id>`
|
|
353
|
-
| `tmdb tv recommendations <id>`
|
|
354
|
-
| `tmdb tv season <id> <season>`
|
|
355
|
-
| `tmdb
|
|
356
|
-
| `tmdb
|
|
357
|
-
| `tmdb
|
|
358
|
-
| `tmdb
|
|
416
|
+
Every API command accepts `--lang`, `--format`, `--fields`, and `--compact`. Commands that return a paginated list also accept `--all` and `--max-items` with `--format ndjson`. Run `tmdb <command> --help` for the full option list.
|
|
417
|
+
|
|
418
|
+
| Command | Description | Command options |
|
|
419
|
+
| ------------------------------------------------ | --------------------------------------------------------------------------------- | ---------------------------- |
|
|
420
|
+
| `tmdb search <query>` | Search all media, movies, TV, or people. | `--type`, `--year`, `--page` |
|
|
421
|
+
| `tmdb movie list [category]` | List movies. Default `popular`; also `top-rated`, `now-playing`, `upcoming`. | `--page`, `--region` |
|
|
422
|
+
| `tmdb movie get <id>` | Movie details. | `--append` |
|
|
423
|
+
| `tmdb movie credits <id>` | Movie cast and crew. | `--limit` |
|
|
424
|
+
| `tmdb movie images <id>` | Movie image URLs. | `--image-language` |
|
|
425
|
+
| `tmdb movie videos <id>` | Movie videos and trailers. | none |
|
|
426
|
+
| `tmdb movie similar <id>` | Similar movies. | `--page`, `--region` |
|
|
427
|
+
| `tmdb movie recommendations <id>` | Recommended movies. | `--page`, `--region` |
|
|
428
|
+
| `tmdb tv list [category]` | List TV shows. Default `popular`; also `top-rated`, `airing-today`, `on-the-air`. | `--page` |
|
|
429
|
+
| `tmdb tv get <id>` | TV show details. | `--append` |
|
|
430
|
+
| `tmdb tv credits <id>` | TV cast and crew. | `--limit` |
|
|
431
|
+
| `tmdb tv images <id>` | TV image URLs. | `--image-language` |
|
|
432
|
+
| `tmdb tv videos <id>` | TV videos and trailers. | none |
|
|
433
|
+
| `tmdb tv similar <id>` | Similar TV shows. | `--page` |
|
|
434
|
+
| `tmdb tv recommendations <id>` | Recommended TV shows. | `--page` |
|
|
435
|
+
| `tmdb tv season <id> <season>` | TV season and episodes. Use `0` for specials. | none |
|
|
436
|
+
| `tmdb tv episode <id> <season> <episode>` | TV episode details. Use `0` for specials. | `--append` |
|
|
437
|
+
| `tmdb tv aggregate-credits <id>` | Aggregate cast and crew credits for a show. | `--limit` |
|
|
438
|
+
| `tmdb tv season-credits <id> <season>` | Season cast and crew credits. | `--limit` |
|
|
439
|
+
| `tmdb tv season-aggregate-credits <id> <season>` | Aggregate season cast and crew credits. | `--limit` |
|
|
440
|
+
| `tmdb tv season-images <id> <season>` | Season image URLs. | `--image-language` |
|
|
441
|
+
| `tmdb tv season-videos <id> <season>` | Season videos and trailers. | none |
|
|
442
|
+
| `tmdb tv episode-groups <id>` | Alternate episode groups for a show. | none |
|
|
443
|
+
| `tmdb tv episode-group <group-id>` | Episodes in an alternate group. | none |
|
|
444
|
+
| `tmdb person get <id>` | Person details. | none |
|
|
445
|
+
| `tmdb person credits <id>` | Combined cast and crew credits. | `--limit` |
|
|
446
|
+
| `tmdb trending [type]` | Trending media. Default `all`; also `movie`, `tv`, `person`. | `--window`, `--page` |
|
|
447
|
+
| `tmdb genres [type]` | Genres. Default `movie`; also `tv`. | none |
|
|
359
448
|
|
|
360
449
|
Credential and config commands:
|
|
361
450
|
|
|
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. | `--
|
|
366
|
-
| `tmdb auth logout` | Remove saved credentials. | none
|
|
367
|
-
| `tmdb config show` | Show config values with secrets masked. | `--
|
|
368
|
-
| `tmdb config path` | Print the config file path. | none
|
|
369
|
-
| `tmdb config test` | Verify credentials with an authenticated request. | `--
|
|
370
|
-
| `tmdb config set <key> [value]` | Set `token`, `api-key`, `language`, or `region`. | none
|
|
371
|
-
| `tmdb config unset <key>` | Remove a config value. | none
|
|
451
|
+
| Command | Description | Command options |
|
|
452
|
+
| ------------------------------- | ------------------------------------------------------ | ----------------------------------- |
|
|
453
|
+
| `tmdb auth login` | Validate and save credentials. | `--token-stdin`, `--force` |
|
|
454
|
+
| `tmdb auth status` | Show credential source, masked token, and config path. | `--format`, `--fields`, `--compact` |
|
|
455
|
+
| `tmdb auth logout` | Remove saved credentials. | none |
|
|
456
|
+
| `tmdb config show` | Show config values with secrets masked. | `--format`, `--fields`, `--compact` |
|
|
457
|
+
| `tmdb config path` | Print the config file path. | none |
|
|
458
|
+
| `tmdb config test` | Verify credentials with an authenticated request. | `--format`, `--fields`, `--compact` |
|
|
459
|
+
| `tmdb config set <key> [value]` | Set `token`, `api-key`, `language`, or `region`. | none |
|
|
460
|
+
| `tmdb config unset <key>` | Remove a config value. | none |
|
|
372
461
|
|
|
373
462
|
### Common options
|
|
374
463
|
|
|
375
|
-
| Option
|
|
376
|
-
|
|
|
377
|
-
| `--json
|
|
378
|
-
| `--
|
|
379
|
-
| `--
|
|
380
|
-
| `--
|
|
381
|
-
| `--
|
|
382
|
-
| `--
|
|
383
|
-
| `--
|
|
384
|
-
| `--
|
|
385
|
-
| `--
|
|
386
|
-
| `--
|
|
464
|
+
| Option | Description |
|
|
465
|
+
| ------------------------------- | ----------------------------------------------------------------------------------- |
|
|
466
|
+
| `--format <text\|json\|ndjson>` | Output format. `json` prints the raw response, `ndjson` prints one record per line. |
|
|
467
|
+
| `--fields <list>` | Comma-separated top-level fields to keep. Requires `--format json` or `ndjson`. |
|
|
468
|
+
| `--json` | Alias for `--format json`. |
|
|
469
|
+
| `--compact` | Print JSON on a single line instead of pretty-printing it. |
|
|
470
|
+
| `--all` | Follow pagination to the last page. List commands only; requires `ndjson`. |
|
|
471
|
+
| `--max-items <number>` | Stop after this many items. List commands only; requires `ndjson`. |
|
|
472
|
+
| `--lang <code>` | Language for this command. Defaults to config `language`, then `en-US`. |
|
|
473
|
+
| `--page <number>` | Page number. Defaults to `1`. |
|
|
474
|
+
| `--region <code>` | Region for movie lists, similar, and recommendations. Defaults to config `region`. |
|
|
475
|
+
| `--limit <number>` | Maximum rows for credits. Defaults to `10`. |
|
|
476
|
+
| `--append <list>` | Comma-separated `append_to_response` values, such as `credits,videos`. |
|
|
477
|
+
| `--image-language <list>` | Comma-separated image language codes. |
|
|
478
|
+
| `--year <year>` | Movie release year or TV first-air year. Only with `--type movie` or `--type tv`. |
|
|
479
|
+
| `--type <value>` | Media selector for `search`: `all`, `movie`, `tv`, or `person`. |
|
|
480
|
+
| `--window <day\|week>` | Trending window. Defaults to `week`. |
|
|
387
481
|
|
|
388
482
|
`--version` prints the CLI version.
|
|
389
483
|
|
|
390
484
|
### Output and exit codes
|
|
391
485
|
|
|
392
|
-
The default output is a compact summary for reading in a terminal. Use `--json` for scripts:
|
|
486
|
+
The default output is a compact summary for reading in a terminal. Use `--format json` for scripts; `--json` is a shorter alias:
|
|
393
487
|
|
|
394
488
|
```bash
|
|
395
|
-
tmdb movie get 550 --json | jq '.title, .release_date'
|
|
489
|
+
tmdb movie get 550 --format json | jq '.title, .release_date'
|
|
490
|
+
tmdb movie get 550 --json | jq '.title'
|
|
491
|
+
tmdb movie get 550 --format json --compact # single line, for line-oriented tools
|
|
396
492
|
```
|
|
397
493
|
|
|
494
|
+
`--compact` only affects `json` output and is ignored for `text`. Combining `--json` with an explicit `--format text` or `--format ndjson` is a usage error.
|
|
495
|
+
|
|
496
|
+
#### NDJSON
|
|
497
|
+
|
|
498
|
+
`--format ndjson` (alias `jsonl`) prints one JSON object per line. Responses with a `results` array stream as three record kinds:
|
|
499
|
+
|
|
500
|
+
<!-- prettier-ignore -->
|
|
501
|
+
```json
|
|
502
|
+
{"type":"meta","page":1,"total_pages":5,"total_results":100}
|
|
503
|
+
{"type":"item","index":0,"value":{"id":550,"title":"Fight Club"}}
|
|
504
|
+
{"type":"summary","count":20,"pages":1}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
`meta` is the response envelope without `results`, `index` is zero-based, and `summary` closes the stream with the item count and pages read. Every other response emits a single record:
|
|
508
|
+
|
|
509
|
+
<!-- prettier-ignore -->
|
|
510
|
+
```json
|
|
511
|
+
{"type":"result","value":{"id":550,"title":"Fight Club"}}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Because the stream is line-oriented, a missing `summary` line means the command failed; the reason is still on stderr as a single `{"type":"error",...}` record.
|
|
515
|
+
|
|
516
|
+
#### Pagination
|
|
517
|
+
|
|
518
|
+
List commands (`search`, `trending`, `movie list/similar/recommendations`, and `tv list/similar/recommendations`) accept `--all` to follow pagination from `--page` to the last page, and `--max-items` to stop early:
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
tmdb trending movie --format ndjson --all --max-items 100
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
`--max-items` caps the number of `item` records with or without `--all`. Both flags require `--format ndjson`, and `--all` may issue many requests: TMDB caps lists at 500 pages and the command stops at that limit.
|
|
525
|
+
|
|
526
|
+
#### Selecting fields
|
|
527
|
+
|
|
528
|
+
`--fields` keeps only the listed top-level fields. For detail commands it projects the response; for list commands it projects each entry in `results` while keeping the envelope:
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
tmdb movie get 550 --format json --fields id,title,release_date
|
|
532
|
+
tmdb movie list --format ndjson --fields id,title | jq -c 'select(.type == "item")'
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Fields that a record does not have are omitted. If none of the requested fields exist, the command exits `2` and lists the available names. Nested paths are not supported, and `--fields` requires `--format json` or `--format ndjson`.
|
|
536
|
+
|
|
537
|
+
When JSON output is active, errors go to stderr as one JSON object and stdout stays empty, so a pipeline never receives a partial payload:
|
|
538
|
+
|
|
539
|
+
<!-- prettier-ignore -->
|
|
540
|
+
```json
|
|
541
|
+
{"type":"error","kind":"not_found","message":"TMDB request failed (404): ...","exitCode":4,"status":404}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
| Field | Meaning |
|
|
545
|
+
| ------------ | ---------------------------------------------------------------------------- |
|
|
546
|
+
| `type` | Always `error`. |
|
|
547
|
+
| `kind` | `usage`, `auth`, `not_found`, `rate_limit`, `network`, `api`, or `internal`. |
|
|
548
|
+
| `message` | Human-readable description. |
|
|
549
|
+
| `exitCode` | Process exit code, matching the table below. |
|
|
550
|
+
| `status` | HTTP status, when the failure came from a TMDB response. |
|
|
551
|
+
| `requestId` | TMDB `x-request-id`, when the response included one. |
|
|
552
|
+
| `retryAfter` | Seconds to wait before retrying, for rate limit errors. |
|
|
553
|
+
|
|
398
554
|
Exit codes:
|
|
399
555
|
|
|
400
556
|
| Code | Meaning |
|
|
@@ -421,6 +577,12 @@ tmdb trending movie --window day --json | jq '.results[].title'
|
|
|
421
577
|
# Season 1 episodes for a TV show
|
|
422
578
|
tmdb tv season 1399 1 --json | jq '.episodes[].name'
|
|
423
579
|
|
|
580
|
+
# Episode details (season 0 = specials)
|
|
581
|
+
tmdb tv episode 1399 1 1
|
|
582
|
+
|
|
583
|
+
# Alternate episode groups
|
|
584
|
+
tmdb tv episode-groups 1399
|
|
585
|
+
|
|
424
586
|
# Save defaults for later commands
|
|
425
587
|
tmdb config set language zh-CN
|
|
426
588
|
tmdb config set region CN
|
|
@@ -438,12 +600,14 @@ bun run test:coverage
|
|
|
438
600
|
bun run build
|
|
439
601
|
```
|
|
440
602
|
|
|
441
|
-
Run the integration suite with a real token:
|
|
603
|
+
Run the integration suite with a real token. It exercises every SDK resource, the optional helpers, and the CLI against the live API:
|
|
442
604
|
|
|
443
605
|
```bash
|
|
444
606
|
TMDB_ACCESS_TOKEN=your_access_token_here bun run test:integration
|
|
445
607
|
```
|
|
446
608
|
|
|
609
|
+
Set `TMDB_API_ENDPOINT` to run the SDK suites against a compatible mirror. The `Integration` GitHub workflow runs the same suite nightly, on manual dispatch, and on pull requests that touch the SDK, CLI, or integration tests. Add a `TMDB_ACCESS_TOKEN` repository secret to enable it, and an optional `TMDB_API_KEY` secret to also cover legacy v3 key auth; fork and Dependabot pull requests skip the live job because repository secrets are not available to them.
|
|
610
|
+
|
|
447
611
|
Build and run the CLI from source:
|
|
448
612
|
|
|
449
613
|
```bash
|