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 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