tmdb-kit 0.1.0-beta.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 +159 -0
- package/dist/index.cjs +465 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +513 -0
- package/dist/index.d.ts +513 -0
- package/dist/index.js +459 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# tmdb-kit
|
|
2
|
+
|
|
3
|
+
A tiny, typed, zero-runtime-dependency TMDB SDK for Node.js, Bun, Deno, and edge runtimes.
|
|
4
|
+
|
|
5
|
+
This package intentionally does not generate code from OpenAPI. It ships a small hand-designed API surface for common TMDB workflows, plus a typed `request<T>()` escape hatch for endpoints that are not wrapped yet.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Zero runtime dependencies.
|
|
10
|
+
- Built with tsdown and published as ESM + CommonJS.
|
|
11
|
+
- Uses only Web standard APIs: `fetch`, `Headers`, `URL`, and `AbortSignal`.
|
|
12
|
+
- Works in Node.js 18+, Bun, Deno, Cloudflare Workers, Vercel Edge, and other fetch-compatible runtimes.
|
|
13
|
+
- Typed resources for movies, TV, search, trending, people, genres, configuration, credits, videos, and images.
|
|
14
|
+
- High-coverage unit tests with mocked fetch; no real TMDB requests in tests.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install tmdb-kit
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { createTMDB } from 'tmdb-kit'
|
|
26
|
+
|
|
27
|
+
const tmdb = createTMDB({
|
|
28
|
+
accessToken: process.env.TMDB_ACCESS_TOKEN!,
|
|
29
|
+
defaultLanguage: 'en-US',
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const popular = await tmdb.movies.popular({ page: 1 })
|
|
33
|
+
const movie = await tmdb.movies.details(popular.results[0]!.id, {
|
|
34
|
+
appendToResponse: ['credits', 'videos'],
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const posterUrl = tmdb.images.url(movie.poster_path, 'w500')
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
CommonJS:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
const { createTMDB } = require('tmdb-kit')
|
|
44
|
+
|
|
45
|
+
const tmdb = createTMDB({ accessToken: process.env.TMDB_ACCESS_TOKEN })
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Deno:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createTMDB } from 'npm:tmdb-kit'
|
|
52
|
+
|
|
53
|
+
const tmdb = createTMDB({ accessToken: Deno.env.get('TMDB_ACCESS_TOKEN')! })
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Authentication
|
|
57
|
+
|
|
58
|
+
The recommended option is TMDB's API Read Access Token:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
createTMDB({ accessToken: 'tmdb-read-access-token' })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The legacy v3 `api_key` query parameter is also supported:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
createTMDB({ apiKey: 'tmdb-v3-api-key' })
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Exactly one of `accessToken` or `apiKey` is required.
|
|
71
|
+
|
|
72
|
+
## Supported Resources
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
tmdb.movies.popular()
|
|
76
|
+
tmdb.movies.topRated()
|
|
77
|
+
tmdb.movies.nowPlaying()
|
|
78
|
+
tmdb.movies.upcoming()
|
|
79
|
+
tmdb.movies.details(550, { appendToResponse: ['credits', 'videos'] })
|
|
80
|
+
tmdb.movies.credits(550)
|
|
81
|
+
tmdb.movies.images(550)
|
|
82
|
+
tmdb.movies.recommendations(550)
|
|
83
|
+
tmdb.movies.similar(550)
|
|
84
|
+
tmdb.movies.videos(550)
|
|
85
|
+
|
|
86
|
+
tmdb.tv.popular()
|
|
87
|
+
tmdb.tv.topRated()
|
|
88
|
+
tmdb.tv.airingToday()
|
|
89
|
+
tmdb.tv.onTheAir()
|
|
90
|
+
tmdb.tv.details(1399)
|
|
91
|
+
tmdb.tv.credits(1399)
|
|
92
|
+
tmdb.tv.images(1399)
|
|
93
|
+
tmdb.tv.recommendations(1399)
|
|
94
|
+
tmdb.tv.similar(1399)
|
|
95
|
+
tmdb.tv.videos(1399)
|
|
96
|
+
|
|
97
|
+
tmdb.search.movies('Dune')
|
|
98
|
+
tmdb.search.tv('Dark')
|
|
99
|
+
tmdb.search.people('Sofia Coppola')
|
|
100
|
+
tmdb.search.multi('Tom Hardy')
|
|
101
|
+
|
|
102
|
+
tmdb.trending.all('week')
|
|
103
|
+
tmdb.trending.movies('day')
|
|
104
|
+
tmdb.trending.tv('day')
|
|
105
|
+
tmdb.trending.people('week')
|
|
106
|
+
|
|
107
|
+
tmdb.people.popular()
|
|
108
|
+
tmdb.people.details(31)
|
|
109
|
+
|
|
110
|
+
tmdb.genres.movies()
|
|
111
|
+
tmdb.genres.tv()
|
|
112
|
+
|
|
113
|
+
tmdb.configuration.details()
|
|
114
|
+
tmdb.configuration.countries()
|
|
115
|
+
tmdb.configuration.jobs()
|
|
116
|
+
tmdb.configuration.languages()
|
|
117
|
+
tmdb.configuration.primaryTranslations()
|
|
118
|
+
tmdb.configuration.timezones()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For an endpoint that is not wrapped yet:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
const response = await tmdb.request<{ results: unknown[] }>('/discover/movie', {
|
|
125
|
+
query: {
|
|
126
|
+
sort_by: 'popularity.desc',
|
|
127
|
+
with_genres: [28, 12],
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Errors
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { TMDBResponseError } from 'tmdb-kit'
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
await tmdb.movies.popular()
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (error instanceof TMDBResponseError) {
|
|
141
|
+
console.log(error.status, error.statusCode, error.statusMessage)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Development
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npm install
|
|
150
|
+
npm run typecheck
|
|
151
|
+
npm run test:coverage
|
|
152
|
+
npm run build
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## References
|
|
156
|
+
|
|
157
|
+
- [TMDB authentication](https://developer.themoviedb.org/docs/authentication-application)
|
|
158
|
+
- [TMDB API reference](https://developer.themoviedb.org/reference/intro/getting-started)
|
|
159
|
+
- [tsdown output formats](https://tsdown.dev/options/output-format)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/errors.ts
|
|
3
|
+
/** Base class for all SDK-originated errors. */
|
|
4
|
+
var TMDBError = class extends Error {
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options);
|
|
7
|
+
this.name = "TMDBError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
/** Thrown before a request is sent or when fetch itself rejects. */
|
|
11
|
+
var TMDBRequestError = class extends TMDBError {
|
|
12
|
+
constructor(message, options) {
|
|
13
|
+
super(message, options);
|
|
14
|
+
this.name = "TMDBRequestError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/** Thrown when TMDB returns a non-2xx response. */
|
|
18
|
+
var TMDBResponseError = class extends TMDBError {
|
|
19
|
+
body;
|
|
20
|
+
headers;
|
|
21
|
+
requestId;
|
|
22
|
+
status;
|
|
23
|
+
statusCode;
|
|
24
|
+
statusMessage;
|
|
25
|
+
statusText;
|
|
26
|
+
url;
|
|
27
|
+
constructor(message, options) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "TMDBResponseError";
|
|
30
|
+
this.body = options.body;
|
|
31
|
+
this.headers = options.headers;
|
|
32
|
+
this.requestId = options.headers.get("x-request-id");
|
|
33
|
+
this.status = options.status;
|
|
34
|
+
this.statusText = options.statusText;
|
|
35
|
+
this.url = options.url;
|
|
36
|
+
const body = isErrorResponseBody(options.body) ? options.body : void 0;
|
|
37
|
+
this.statusCode = body?.status_code;
|
|
38
|
+
this.statusMessage = body?.status_message;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function createResponseError(options) {
|
|
42
|
+
return new TMDBResponseError((isErrorResponseBody(options.body) ? options.body : void 0)?.status_message ?? `${options.status} ${options.statusText}`.trim(), options);
|
|
43
|
+
}
|
|
44
|
+
function isErrorResponseBody(value) {
|
|
45
|
+
return typeof value === "object" && value !== null;
|
|
46
|
+
}
|
|
47
|
+
function appendQuery(url, query) {
|
|
48
|
+
for (const [key, value] of Object.entries(query)) {
|
|
49
|
+
if (value === void 0 || value === null) continue;
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
url.searchParams.set(key, value.map(String).join(","));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
url.searchParams.set(key, String(value));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function withLanguage(defaults, query) {
|
|
58
|
+
const language = typeof query.language === "string" ? query.language : defaults.language;
|
|
59
|
+
return {
|
|
60
|
+
...query,
|
|
61
|
+
language
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function withListDefaults(defaults, query) {
|
|
65
|
+
const region = typeof query.region === "string" ? query.region : defaults.region;
|
|
66
|
+
return {
|
|
67
|
+
...withLanguage(defaults, query),
|
|
68
|
+
region
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function toCommaList(value) {
|
|
72
|
+
if (value === void 0) return;
|
|
73
|
+
return typeof value === "string" ? value : value.join(",");
|
|
74
|
+
}
|
|
75
|
+
function toId(value, name) {
|
|
76
|
+
if (!Number.isInteger(value) || value <= 0) throw new TMDBRequestError(`${name} must be a positive integer`);
|
|
77
|
+
return String(value);
|
|
78
|
+
}
|
|
79
|
+
function toSearchQuery(value) {
|
|
80
|
+
const query = value.trim();
|
|
81
|
+
if (query.length === 0) throw new TMDBRequestError("search query must not be empty");
|
|
82
|
+
return query;
|
|
83
|
+
}
|
|
84
|
+
function toTimeWindow(value) {
|
|
85
|
+
if (value !== "day" && value !== "week") throw new TMDBRequestError("timeWindow must be either \"day\" or \"week\"");
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Build a full TMDB image URL from the path returned by API payloads.
|
|
90
|
+
* Returns null for nullish image paths so UI code can branch naturally.
|
|
91
|
+
*/
|
|
92
|
+
function buildImageUrl(path, size = "original", options = {}) {
|
|
93
|
+
if (path === void 0 || path === null || path.trim() === "") return null;
|
|
94
|
+
return `${normalizeBaseUrl(options.baseUrl ?? "https://image.tmdb.org/t/p")}/${size}${path.startsWith("/") ? path : `/${path}`}`;
|
|
95
|
+
}
|
|
96
|
+
function normalizeBaseUrl(baseUrl) {
|
|
97
|
+
return baseUrl.replace(/\/+$/, "");
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/http.ts
|
|
101
|
+
var TMDBHttpClient = class {
|
|
102
|
+
defaults;
|
|
103
|
+
#apiKey;
|
|
104
|
+
#accessToken;
|
|
105
|
+
#baseUrl;
|
|
106
|
+
#fetch;
|
|
107
|
+
#headers;
|
|
108
|
+
constructor(options) {
|
|
109
|
+
const accessToken = normalizeSecret("accessToken" in options ? options.accessToken : void 0);
|
|
110
|
+
const apiKey = normalizeSecret("apiKey" in options ? options.apiKey : void 0);
|
|
111
|
+
if (Boolean(accessToken) === Boolean(apiKey)) throw new TMDBRequestError("Provide exactly one of accessToken or apiKey");
|
|
112
|
+
const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
113
|
+
if (typeof fetchImpl !== "function") throw new TMDBRequestError("No fetch implementation found. Pass options.fetch in this runtime.");
|
|
114
|
+
this.#accessToken = accessToken;
|
|
115
|
+
this.#apiKey = apiKey;
|
|
116
|
+
this.#baseUrl = normalizeBaseUrl(options.baseUrl ?? "https://api.themoviedb.org/3");
|
|
117
|
+
this.#fetch = fetchImpl;
|
|
118
|
+
this.#headers = options.headers;
|
|
119
|
+
this.defaults = {
|
|
120
|
+
imageBaseUrl: normalizeBaseUrl(options.imageBaseUrl ?? "https://image.tmdb.org/t/p"),
|
|
121
|
+
language: options.defaultLanguage,
|
|
122
|
+
region: options.defaultRegion
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async get(path, options = {}) {
|
|
126
|
+
const url = this.#createUrl(path, options.query ?? {});
|
|
127
|
+
const headers = this.#createHeaders(options.headers);
|
|
128
|
+
let response;
|
|
129
|
+
try {
|
|
130
|
+
response = await this.#fetch(url, {
|
|
131
|
+
headers,
|
|
132
|
+
method: "GET",
|
|
133
|
+
signal: options.signal
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
throw new TMDBRequestError(`TMDB request failed: ${String(error)}`, { cause: error });
|
|
137
|
+
}
|
|
138
|
+
const body = await readJson(response);
|
|
139
|
+
if (!response.ok) throw createResponseError({
|
|
140
|
+
body,
|
|
141
|
+
headers: response.headers,
|
|
142
|
+
status: response.status,
|
|
143
|
+
statusText: response.statusText,
|
|
144
|
+
url
|
|
145
|
+
});
|
|
146
|
+
return body;
|
|
147
|
+
}
|
|
148
|
+
#createHeaders(headersInit) {
|
|
149
|
+
const headers = new Headers(this.#headers);
|
|
150
|
+
const requestHeaders = new Headers(headersInit);
|
|
151
|
+
headers.set("Accept", "application/json");
|
|
152
|
+
for (const [key, value] of requestHeaders) headers.set(key, value);
|
|
153
|
+
if (this.#accessToken !== void 0) headers.set("Authorization", `Bearer ${this.#accessToken}`);
|
|
154
|
+
return headers;
|
|
155
|
+
}
|
|
156
|
+
#createUrl(path, query) {
|
|
157
|
+
const relativePath = path.replace(/^\/+/, "");
|
|
158
|
+
const url = new URL(relativePath, `${this.#baseUrl}/`);
|
|
159
|
+
appendQuery(url, {
|
|
160
|
+
...query,
|
|
161
|
+
api_key: this.#apiKey
|
|
162
|
+
});
|
|
163
|
+
return url.toString();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
async function readJson(response) {
|
|
167
|
+
const text = await response.text();
|
|
168
|
+
if (text.length === 0) return;
|
|
169
|
+
try {
|
|
170
|
+
return JSON.parse(text);
|
|
171
|
+
} catch {
|
|
172
|
+
return text;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function normalizeSecret(value) {
|
|
176
|
+
const secret = value?.trim();
|
|
177
|
+
return secret === "" ? void 0 : secret;
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/resources/configuration.ts
|
|
181
|
+
var ConfigurationResource = class {
|
|
182
|
+
#transport;
|
|
183
|
+
constructor(transport) {
|
|
184
|
+
this.#transport = transport;
|
|
185
|
+
}
|
|
186
|
+
details() {
|
|
187
|
+
return this.#transport.get("/configuration");
|
|
188
|
+
}
|
|
189
|
+
countries() {
|
|
190
|
+
return this.#transport.get("/configuration/countries");
|
|
191
|
+
}
|
|
192
|
+
jobs() {
|
|
193
|
+
return this.#transport.get("/configuration/jobs");
|
|
194
|
+
}
|
|
195
|
+
languages() {
|
|
196
|
+
return this.#transport.get("/configuration/languages");
|
|
197
|
+
}
|
|
198
|
+
primaryTranslations() {
|
|
199
|
+
return this.#transport.get("/configuration/primary_translations");
|
|
200
|
+
}
|
|
201
|
+
timezones() {
|
|
202
|
+
return this.#transport.get("/configuration/timezones");
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/resources/genres.ts
|
|
207
|
+
var GenresResource = class {
|
|
208
|
+
#transport;
|
|
209
|
+
constructor(transport) {
|
|
210
|
+
this.#transport = transport;
|
|
211
|
+
}
|
|
212
|
+
movies(options = {}) {
|
|
213
|
+
return this.#transport.get("/genre/movie/list", { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
214
|
+
}
|
|
215
|
+
tv(options = {}) {
|
|
216
|
+
return this.#transport.get("/genre/tv/list", { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region src/resources/images.ts
|
|
221
|
+
var ImagesHelper = class {
|
|
222
|
+
#transport;
|
|
223
|
+
constructor(transport) {
|
|
224
|
+
this.#transport = transport;
|
|
225
|
+
}
|
|
226
|
+
url(path, size = "original") {
|
|
227
|
+
return buildImageUrl(path, size, { baseUrl: this.#transport.defaults.imageBaseUrl });
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
//#endregion
|
|
231
|
+
//#region src/resources/movies.ts
|
|
232
|
+
var MoviesResource = class {
|
|
233
|
+
#transport;
|
|
234
|
+
constructor(transport) {
|
|
235
|
+
this.#transport = transport;
|
|
236
|
+
}
|
|
237
|
+
popular(options = {}) {
|
|
238
|
+
return this.#transport.get("/movie/popular", { query: movieListQuery(this.#transport, options) });
|
|
239
|
+
}
|
|
240
|
+
topRated(options = {}) {
|
|
241
|
+
return this.#transport.get("/movie/top_rated", { query: movieListQuery(this.#transport, options) });
|
|
242
|
+
}
|
|
243
|
+
nowPlaying(options = {}) {
|
|
244
|
+
return this.#transport.get("/movie/now_playing", { query: movieListQuery(this.#transport, options) });
|
|
245
|
+
}
|
|
246
|
+
upcoming(options = {}) {
|
|
247
|
+
return this.#transport.get("/movie/upcoming", { query: movieListQuery(this.#transport, options) });
|
|
248
|
+
}
|
|
249
|
+
details(movieId, options = {}) {
|
|
250
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}`, { query: withLanguage(this.#transport.defaults, {
|
|
251
|
+
append_to_response: toCommaList(options.appendToResponse),
|
|
252
|
+
language: options.language
|
|
253
|
+
}) });
|
|
254
|
+
}
|
|
255
|
+
credits(movieId, options = {}) {
|
|
256
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/credits`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
257
|
+
}
|
|
258
|
+
images(movieId, options = {}) {
|
|
259
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/images`, { query: withLanguage(this.#transport.defaults, {
|
|
260
|
+
include_image_language: toCommaList(options.includeImageLanguage),
|
|
261
|
+
language: options.language
|
|
262
|
+
}) });
|
|
263
|
+
}
|
|
264
|
+
recommendations(movieId, options = {}) {
|
|
265
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/recommendations`, { query: movieListQuery(this.#transport, options) });
|
|
266
|
+
}
|
|
267
|
+
similar(movieId, options = {}) {
|
|
268
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/similar`, { query: movieListQuery(this.#transport, options) });
|
|
269
|
+
}
|
|
270
|
+
videos(movieId, options = {}) {
|
|
271
|
+
return this.#transport.get(`/movie/${toId(movieId, "movieId")}/videos`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
function movieListQuery(transport, options) {
|
|
275
|
+
return withListDefaults(transport.defaults, {
|
|
276
|
+
language: options.language,
|
|
277
|
+
page: options.page,
|
|
278
|
+
region: options.region
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region src/resources/people.ts
|
|
283
|
+
var PeopleResource = class {
|
|
284
|
+
#transport;
|
|
285
|
+
constructor(transport) {
|
|
286
|
+
this.#transport = transport;
|
|
287
|
+
}
|
|
288
|
+
popular(options = {}) {
|
|
289
|
+
return this.#transport.get("/person/popular", { query: peopleListQuery(this.#transport, options) });
|
|
290
|
+
}
|
|
291
|
+
details(personId, options = {}) {
|
|
292
|
+
return this.#transport.get(`/person/${toId(personId, "personId")}`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
function peopleListQuery(transport, options) {
|
|
296
|
+
return withLanguage(transport.defaults, {
|
|
297
|
+
language: options.language,
|
|
298
|
+
page: options.page
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/resources/search.ts
|
|
303
|
+
var SearchResource = class {
|
|
304
|
+
#transport;
|
|
305
|
+
constructor(transport) {
|
|
306
|
+
this.#transport = transport;
|
|
307
|
+
}
|
|
308
|
+
movies(query, options = {}) {
|
|
309
|
+
return this.#transport.get("/search/movie", { query: movieSearchQuery(this.#transport, query, options) });
|
|
310
|
+
}
|
|
311
|
+
tv(query, options = {}) {
|
|
312
|
+
return this.#transport.get("/search/tv", { query: tvSearchQuery(this.#transport, query, options) });
|
|
313
|
+
}
|
|
314
|
+
people(query, options = {}) {
|
|
315
|
+
return this.#transport.get("/search/person", { query: commonSearchQuery(this.#transport, query, options) });
|
|
316
|
+
}
|
|
317
|
+
multi(query, options = {}) {
|
|
318
|
+
return this.#transport.get("/search/multi", { query: commonSearchQuery(this.#transport, query, options) });
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
function movieSearchQuery(transport, query, options) {
|
|
322
|
+
return withListDefaults(transport.defaults, {
|
|
323
|
+
include_adult: options.includeAdult,
|
|
324
|
+
language: options.language,
|
|
325
|
+
page: options.page,
|
|
326
|
+
primary_release_year: options.primaryReleaseYear,
|
|
327
|
+
query: toSearchQuery(query),
|
|
328
|
+
region: options.region,
|
|
329
|
+
year: options.year
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function tvSearchQuery(transport, query, options) {
|
|
333
|
+
return withLanguage(transport.defaults, {
|
|
334
|
+
first_air_date_year: options.firstAirDateYear,
|
|
335
|
+
include_adult: options.includeAdult,
|
|
336
|
+
language: options.language,
|
|
337
|
+
page: options.page,
|
|
338
|
+
query: toSearchQuery(query),
|
|
339
|
+
year: options.year
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function commonSearchQuery(transport, query, options) {
|
|
343
|
+
return withLanguage(transport.defaults, {
|
|
344
|
+
include_adult: options.includeAdult,
|
|
345
|
+
language: options.language,
|
|
346
|
+
page: options.page,
|
|
347
|
+
query: toSearchQuery(query)
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
//#endregion
|
|
351
|
+
//#region src/resources/trending.ts
|
|
352
|
+
var TrendingResource = class {
|
|
353
|
+
#transport;
|
|
354
|
+
constructor(transport) {
|
|
355
|
+
this.#transport = transport;
|
|
356
|
+
}
|
|
357
|
+
all(timeWindow = "day", options = {}) {
|
|
358
|
+
return this.#transport.get(`/trending/all/${toTimeWindow(timeWindow)}`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
359
|
+
}
|
|
360
|
+
movies(timeWindow = "day", options = {}) {
|
|
361
|
+
return this.#transport.get(`/trending/movie/${toTimeWindow(timeWindow)}`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
362
|
+
}
|
|
363
|
+
tv(timeWindow = "day", options = {}) {
|
|
364
|
+
return this.#transport.get(`/trending/tv/${toTimeWindow(timeWindow)}`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
365
|
+
}
|
|
366
|
+
people(timeWindow = "day", options = {}) {
|
|
367
|
+
return this.#transport.get(`/trending/person/${toTimeWindow(timeWindow)}`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region src/resources/tv.ts
|
|
372
|
+
var TVResource = class {
|
|
373
|
+
#transport;
|
|
374
|
+
constructor(transport) {
|
|
375
|
+
this.#transport = transport;
|
|
376
|
+
}
|
|
377
|
+
popular(options = {}) {
|
|
378
|
+
return this.#transport.get("/tv/popular", { query: tvListQuery(this.#transport, options) });
|
|
379
|
+
}
|
|
380
|
+
topRated(options = {}) {
|
|
381
|
+
return this.#transport.get("/tv/top_rated", { query: tvListQuery(this.#transport, options) });
|
|
382
|
+
}
|
|
383
|
+
airingToday(options = {}) {
|
|
384
|
+
return this.#transport.get("/tv/airing_today", { query: tvListQuery(this.#transport, options) });
|
|
385
|
+
}
|
|
386
|
+
onTheAir(options = {}) {
|
|
387
|
+
return this.#transport.get("/tv/on_the_air", { query: tvListQuery(this.#transport, options) });
|
|
388
|
+
}
|
|
389
|
+
details(seriesId, options = {}) {
|
|
390
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}`, { query: withLanguage(this.#transport.defaults, {
|
|
391
|
+
append_to_response: toCommaList(options.appendToResponse),
|
|
392
|
+
language: options.language
|
|
393
|
+
}) });
|
|
394
|
+
}
|
|
395
|
+
credits(seriesId, options = {}) {
|
|
396
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/credits`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
397
|
+
}
|
|
398
|
+
images(seriesId, options = {}) {
|
|
399
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/images`, { query: withLanguage(this.#transport.defaults, {
|
|
400
|
+
include_image_language: toCommaList(options.includeImageLanguage),
|
|
401
|
+
language: options.language
|
|
402
|
+
}) });
|
|
403
|
+
}
|
|
404
|
+
recommendations(seriesId, options = {}) {
|
|
405
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/recommendations`, { query: tvListQuery(this.#transport, options) });
|
|
406
|
+
}
|
|
407
|
+
similar(seriesId, options = {}) {
|
|
408
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/similar`, { query: tvListQuery(this.#transport, options) });
|
|
409
|
+
}
|
|
410
|
+
videos(seriesId, options = {}) {
|
|
411
|
+
return this.#transport.get(`/tv/${toId(seriesId, "seriesId")}/videos`, { query: withLanguage(this.#transport.defaults, { language: options.language }) });
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
function tvListQuery(transport, options) {
|
|
415
|
+
return withLanguage(transport.defaults, {
|
|
416
|
+
language: options.language,
|
|
417
|
+
page: options.page
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/client.ts
|
|
422
|
+
/**
|
|
423
|
+
* Main SDK entry point.
|
|
424
|
+
*
|
|
425
|
+
* Resource properties are intentionally small and explicit. The SDK focuses on
|
|
426
|
+
* common TMDB workflows first, while request<T>() keeps uncommon endpoints easy
|
|
427
|
+
* to call without waiting for a generated surface area.
|
|
428
|
+
*/
|
|
429
|
+
var TMDBClient = class {
|
|
430
|
+
configuration;
|
|
431
|
+
genres;
|
|
432
|
+
images;
|
|
433
|
+
movies;
|
|
434
|
+
people;
|
|
435
|
+
search;
|
|
436
|
+
trending;
|
|
437
|
+
tv;
|
|
438
|
+
#http;
|
|
439
|
+
constructor(options) {
|
|
440
|
+
this.#http = new TMDBHttpClient(options);
|
|
441
|
+
this.configuration = new ConfigurationResource(this.#http);
|
|
442
|
+
this.genres = new GenresResource(this.#http);
|
|
443
|
+
this.images = new ImagesHelper(this.#http);
|
|
444
|
+
this.movies = new MoviesResource(this.#http);
|
|
445
|
+
this.people = new PeopleResource(this.#http);
|
|
446
|
+
this.search = new SearchResource(this.#http);
|
|
447
|
+
this.trending = new TrendingResource(this.#http);
|
|
448
|
+
this.tv = new TVResource(this.#http);
|
|
449
|
+
}
|
|
450
|
+
request(path, options) {
|
|
451
|
+
return this.#http.get(path, options);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
function createTMDB(options) {
|
|
455
|
+
return new TMDBClient(options);
|
|
456
|
+
}
|
|
457
|
+
//#endregion
|
|
458
|
+
exports.TMDBClient = TMDBClient;
|
|
459
|
+
exports.TMDBError = TMDBError;
|
|
460
|
+
exports.TMDBRequestError = TMDBRequestError;
|
|
461
|
+
exports.TMDBResponseError = TMDBResponseError;
|
|
462
|
+
exports.buildImageUrl = buildImageUrl;
|
|
463
|
+
exports.createTMDB = createTMDB;
|
|
464
|
+
|
|
465
|
+
//# sourceMappingURL=index.cjs.map
|