@lorenzopant/tmdb 1.24.0 → 1.25.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 CHANGED
@@ -244,6 +244,23 @@ const tmdb = new TMDB(token, {
244
244
  });
245
245
  ```
246
246
 
247
+ #### Standalone image URL builder
248
+
249
+ Only need the image URL builder and not the rest of the SDK? Import `ImageAPI` from the
250
+ `@lorenzopant/tmdb/image` subpath. It ships as its own ~3.4 kB bundle with no TMDB client and no
251
+ endpoint code, so you don't pull in the full SDK:
252
+
253
+ ```typescript
254
+ import { ImageAPI } from "@lorenzopant/tmdb/image";
255
+
256
+ const images = new ImageAPI({ secure_images_url: true });
257
+
258
+ const posterUrl = images.poster("/abc123.jpg", "w500");
259
+ const backdropUrl = images.backdrop("/def456.jpg", "w1280");
260
+ ```
261
+
262
+ `ImageAPI` needs no API token — it only builds URLs from paths.
263
+
247
264
  ### Error handling
248
265
 
249
266
  ```typescript
@@ -0,0 +1,2 @@
1
+ import { _ as ProfileSize, a as FallbackUrlConfig, d as ImagesConfig, g as PosterSize, l as ImageSize, p as LogoSize, r as BackdropSize, t as ImageAPI, x as ImageCollectionKey, y as StillSize } from "./images.mjs";
2
+ export { type BackdropSize, type FallbackUrlConfig, ImageAPI, type ImageCollectionKey, type ImageSize, type ImagesConfig, type LogoSize, type PosterSize, type ProfileSize, type StillSize };
package/dist/image.mjs ADDED
@@ -0,0 +1 @@
1
+ import{t as e}from"./images.mjs";export{e as ImageAPI};
@@ -0,0 +1,573 @@
1
+ //#region src/types/config/languages.d.ts
2
+ type LanguageISO6391 = "ay" | "ch" | "fj" | "it" | "nv" | "qu" | "ru" | "sc" | "sw" | "tn" | "ur" | "ho" | "km" | "kj" | "tt" | "ps" | "cn" | "mk" | "yo" | "fo" | "ff" | "ig" | "io" | "id" | "ko" | "mo" | "nr" | "pi" | "so" | "sq" | "ta" | "tl" | "th" | "ve" | "vo" | "cu" | "kw" | "fr" | "fy" | "ht" | "ie" | "ia" | "mh" | "rn" | "se" | "gd" | "ii" | "lo" | "la" | "ny" | "oj" | "ab" | "ar" | "ee" | "hi" | "an" | "ba" | "bn" | "bi" | "et" | "eu" | "gl" | "ha" | "hz" | "iu" | "jv" | "kr" | "mn" | "my" | "na" | "pt" | "sd" | "zu" | "ak" | "hu" | "ik" | "ks" | "ka" | "lg" | "oc" | "uz" | "xh" | "za" | "zh" | "el" | "ga" | "gn" | "gu" | "kl" | "kn" | "ky" | "nl" | "sl" | "sr" | "ss" | "ug" | "bg" | "co" | "cy" | "dv" | "ki" | "mt" | "ne" | "si" | "sn" | "su" | "to" | "wa" | "cr" | "fi" | "hr" | "mg" | "nb" | "ts" | "vi" | "hy" | "av" | "az" | "gv" | "sh" | "lv" | "mr" | "pl" | "rm" | "tr" | "xx" | "ca" | "de" | "rw" | "ln" | "ro" | "ty" | "ti" | "he" | "as" | "bo" | "dz" | "eo" | "ja" | "ng" | "no" | "pa" | "sa" | "am" | "fa" | "aa" | "ae" | "br" | "is" | "kk" | "lt" | "mi" | "ms" | "or" | "st" | "tk" | "af" | "bm" | "bs" | "cs" | "ce" | "kv" | "lb" | "nd" | "sk" | "sm" | "tg" | "wo" | "yi" | "be" | "cv" | "da" | "en" | "kg" | "ku" | "li" | "lu" | "ml" | "nn" | "om" | "os" | "sg" | "es" | "sv" | "te" | "tw" | "uk";
3
+ /**
4
+ * Defined as const for utility purposes.
5
+ * Last update: 20 Nov 2025
6
+ */
7
+ type PrimaryTranslations = "af-ZA" | "ar-AE" | "ar-SA" | "be-BY" | "bg-BG" | "bn-BD" | "ca-ES" | "ch-GU" | "cn-CN" | "cs-CZ" | "cy-GB" | "da-DK" | "de-AT" | "de-CH" | "de-DE" | "el-GR" | "en-AU" | "en-CA" | "en-GB" | "en-IE" | "en-NZ" | "en-US" | "eo-EO" | "es-ES" | "es-MX" | "et-EE" | "eu-ES" | "fa-IR" | "fi-FI" | "fr-CA" | "fr-FR" | "ga-IE" | "gd-GB" | "gl-ES" | "he-IL" | "hi-IN" | "hr-HR" | "hu-HU" | "id-ID" | "it-IT" | "ja-JP" | "ka-GE" | "kk-KZ" | "kn-IN" | "ko-KR" | "ky-KG" | "lt-LT" | "lv-LV" | "ml-IN" | "mr-IN" | "ms-MY" | "ms-SG" | "nb-NO" | "nl-BE" | "nl-NL" | "no-NO" | "pa-IN" | "pl-PL" | "pt-BR" | "pt-PT" | "ro-RO" | "ru-RU" | "si-LK" | "sk-SK" | "sl-SI" | "sq-AL" | "sr-RS" | "sv-SE" | "ta-IN" | "te-IN" | "th-TH" | "tl-PH" | "tr-TR" | "uk-UA" | "vi-VN" | "zh-CN" | "zh-HK" | "zh-SG" | "zh-TW" | "zu-ZA";
8
+ /**
9
+ * As per TMDB documentation:
10
+ * https://developer.themoviedb.org/reference/configuration-primary-translations
11
+ */
12
+ type Language = PrimaryTranslations | LanguageISO6391;
13
+ //#endregion
14
+ //#region src/types/config/configuration.d.ts
15
+ type ImageConfiguration = {
16
+ /** Base URL for constructing image URLs (HTTP) */base_url: string; /** Secure base URL for constructing image URLs (HTTPS) */
17
+ secure_base_url: string; /** Available size options for backdrop images */
18
+ backdrop_sizes: string[]; /** Available size options for logo images */
19
+ logo_sizes: string[]; /** Available size options for poster images */
20
+ poster_sizes: string[]; /** Available size options for profile images */
21
+ profile_sizes: string[]; /** Available size options for still images (from TV shows/episodes) */
22
+ still_sizes: string[];
23
+ };
24
+ type ConfigurationResponse = {
25
+ /** Image configuration settings including base URLs and available sizes */images: ImageConfiguration; /** List of keys that can be used to track configuration changes */
26
+ change_keys: string[];
27
+ };
28
+ type ConfigurationCountry = {
29
+ /** ISO 3166-1 alpha-2 country code */iso_3166_1: CountryISO3166_1; /** English name of the country */
30
+ english_name: string; /** Native name of the country in its local language */
31
+ native_name: string;
32
+ };
33
+ type ConfigurationCountriesParams = {
34
+ /** ISO 639-1 language code for localized country names */language?: Language;
35
+ };
36
+ type ConfigurationJob = {
37
+ /** Name of the department (e.g., "Production", "Sound", "Camera") */department: string; /** List of job titles within this department */
38
+ jobs: string[];
39
+ };
40
+ type ConfigurationLanguage = {
41
+ /** ISO 639-1 two-letter language code */iso_639_1: string; /** English name of the language */
42
+ english_name: string; /** Native name of the language */
43
+ name: string;
44
+ };
45
+ type ConfigurationTimezone = {
46
+ /** ISO 3166-1 two-letter country code */iso_3166_1: string; /** List of timezone identifiers for this country (e.g., "America/New_York") */
47
+ zones: string[];
48
+ };
49
+ //#endregion
50
+ //#region src/types/config/countries.d.ts
51
+ declare const TMDBCountries: ConfigurationCountry[];
52
+ type CountryISO3166_1 = "AD" | "AE" | "AF" | "AG" | "AI" | "AL" | "AM" | "AN" | "AO" | "AQ" | "AR" | "AS" | "AT" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BE" | "BF" | "BG" | "BH" | "BI" | "BJ" | "BM" | "BN" | "BO" | "BR" | "BS" | "BT" | "BU" | "BV" | "BW" | "BY" | "BZ" | "CA" | "CC" | "CD" | "CF" | "CG" | "CH" | "CI" | "CK" | "CL" | "CM" | "CN" | "CO" | "CR" | "CS" | "CU" | "CV" | "CX" | "CY" | "CZ" | "DE" | "DJ" | "DK" | "DM" | "DO" | "DZ" | "EC" | "EE" | "EG" | "EH" | "ER" | "ES" | "ET" | "FI" | "FJ" | "FK" | "FM" | "FO" | "FR" | "GA" | "GB" | "GD" | "GE" | "GF" | "GH" | "GI" | "GL" | "GM" | "GN" | "GP" | "GQ" | "GR" | "GS" | "GT" | "GU" | "GW" | "GY" | "HK" | "HM" | "HN" | "HR" | "HT" | "HU" | "ID" | "IE" | "IL" | "IN" | "IO" | "IQ" | "IR" | "IS" | "IT" | "JM" | "JO" | "JP" | "KE" | "KG" | "KH" | "KI" | "KM" | "KN" | "KP" | "KR" | "KW" | "KY" | "KZ" | "LA" | "LB" | "LC" | "LI" | "LK" | "LR" | "LS" | "LT" | "LU" | "LV" | "LY" | "MA" | "MC" | "MD" | "ME" | "MG" | "MH" | "MK" | "ML" | "MM" | "MN" | "MO" | "MP" | "MQ" | "MR" | "MS" | "MT" | "MU" | "MV" | "MW" | "MX" | "MY" | "MZ" | "NA" | "NC" | "NE" | "NF" | "NG" | "NI" | "NL" | "NO" | "NP" | "NR" | "NU" | "NZ" | "OM" | "PA" | "PE" | "PF" | "PG" | "PH" | "PK" | "PL" | "PM" | "PN" | "PR" | "PS" | "PT" | "PW" | "PY" | "QA" | "RE" | "RO" | "RS" | "RU" | "RW" | "SA" | "SB" | "SC" | "SD" | "SE" | "SG" | "SH" | "SI" | "SJ" | "SK" | "SL" | "SM" | "SN" | "SO" | "SR" | "SS" | "ST" | "SU" | "SV" | "SY" | "SZ" | "TC" | "TD" | "TF" | "TG" | "TH" | "TJ" | "TK" | "TL" | "TM" | "TN" | "TO" | "TP" | "TR" | "TT" | "TV" | "TW" | "TZ" | "UA" | "UG" | "UM" | "US" | "UY" | "UZ" | "VA" | "VC" | "VE" | "VG" | "VI" | "VN" | "VU" | "WF" | "WS" | "XC" | "XG" | "XI" | "XK" | "YE" | "YT" | "YU" | "ZA" | "ZM" | "ZR" | "ZW";
53
+ //#endregion
54
+ //#region src/types/common/media.d.ts
55
+ /**
56
+ * Represents a genre of a movie or TV show.
57
+ */
58
+ type Genre = {
59
+ id: number;
60
+ name: string;
61
+ };
62
+ /**
63
+ * Response containing available genres
64
+ */
65
+ type GenresResponse = {
66
+ /** Array of genre objects with ID and name */genres: Genre[];
67
+ };
68
+ /**
69
+ * Represents a production company involved in creating a movie or TV show.
70
+ */
71
+ type ProductionCompany = {
72
+ id: number;
73
+ logo_path?: string;
74
+ name: string;
75
+ origin_country: string;
76
+ };
77
+ /**
78
+ * Represents a country where a movie or TV show was produced.
79
+ */
80
+ type ProductionCountry = {
81
+ iso_3166_1: string;
82
+ name: string;
83
+ };
84
+ /**
85
+ * Represents a spoken language in a movie or TV show.
86
+ */
87
+ type SpokenLanguage = {
88
+ english_name: string;
89
+ iso_639_1: string;
90
+ name: string;
91
+ };
92
+ /**
93
+ * Represents a collection of movies.
94
+ */
95
+ type MovieCollection = {
96
+ id: number;
97
+ name: string;
98
+ poster_path?: string;
99
+ backdrop_path?: string;
100
+ };
101
+ /**
102
+ * Represents common class for cast and crew types
103
+ */
104
+ type Credit = {
105
+ adult: boolean;
106
+ gender?: number;
107
+ id: number;
108
+ known_for_department: string;
109
+ name: string;
110
+ original_name: string;
111
+ popularity: number;
112
+ profile_path?: string;
113
+ credit_id: string;
114
+ };
115
+ /**
116
+ * Represents a cast member in a movie or TV show.
117
+ */
118
+ type Cast = Credit & {
119
+ cast_id?: number;
120
+ character: string;
121
+ order: number;
122
+ };
123
+ /**
124
+ * Represents a crew member in a movie or TV show.
125
+ */
126
+ type Crew = Credit & {
127
+ department: string;
128
+ job: string;
129
+ };
130
+ /**
131
+ * Represents a keyword entry
132
+ */
133
+ type Keyword = {
134
+ id: number;
135
+ name: string;
136
+ };
137
+ /**
138
+ * Represents an alternative name entry for a company or network.
139
+ *
140
+ * @see https://developer.themoviedb.org/reference/company-alternative-names
141
+ * @see https://developer.themoviedb.org/reference/network-alternative-names
142
+ */
143
+ type AlternativeName = {
144
+ /** The alternative name. */name: string; /** The type or context of the alternative name (e.g. "short name", "abbreviation"). */
145
+ type: string;
146
+ };
147
+ /**
148
+ * Represents the response from the TMDB alternative names endpoint
149
+ * for a company or network.
150
+ *
151
+ * @see https://developer.themoviedb.org/reference/company-alternative-names
152
+ * @see https://developer.themoviedb.org/reference/network-alternative-names
153
+ */
154
+ type AlternativeNamesResult = {
155
+ /** The unique TMDB identifier of the company or network. */id: number; /** A list of alternative names associated with the company or network. */
156
+ results: AlternativeName[];
157
+ };
158
+ /**
159
+ * Alternative title entry
160
+ */
161
+ type AlternativeTitle = {
162
+ /** Alternative title text */title: string; /** ISO 3166-1 country code where this title is used */
163
+ iso_3166_1: string; /** Type of title (e.g., "original title", "working title") */
164
+ type: string;
165
+ };
166
+ type VideoResults = {
167
+ /** Media identifier. Absent when this resource is fetched via `append_to_response` rather than standalone. */id?: number | string; /** Array of video items */
168
+ results: VideoItem[];
169
+ };
170
+ /**
171
+ * Video metadata and details
172
+ */
173
+ type VideoItem = {
174
+ /** ISO 639-1 language code of the video */iso_639_1: string; /** ISO 3166-1 country code where the video is available */
175
+ iso_3166_1: string; /** Video title or name */
176
+ name: string; /** Unique video key/ID on the hosting platform */
177
+ key: string; /** Video hosting platform (e.g., "YouTube", "Vimeo") */
178
+ site: string; /** Video resolution/size (e.g., 1080, 720) */
179
+ size: number; /** Type of video (e.g., "Trailer", "Teaser", "Clip", "Featurette", "Behind the Scenes") */
180
+ type: string; /** Whether this is an official video from the content distributor */
181
+ official: boolean; /** Publication date and time (ISO 8601 format) */
182
+ published_at: string; /** Unique video identifier in TMDB */
183
+ id: string;
184
+ };
185
+ /**
186
+ * Watch provider monetization filters supported by TMDB media discovery endpoints.
187
+ */
188
+ type WatchMonetizationType = "flatrate" | "free" | "ads" | "rent" | "buy";
189
+ /**
190
+ * Base properties shared between movie and TV show results
191
+ */
192
+ type BaseKnownForItem = {
193
+ adult: boolean;
194
+ backdrop_path?: string;
195
+ id: number;
196
+ original_language: string;
197
+ overview: string;
198
+ poster_path?: string;
199
+ genre_ids: number[];
200
+ popularity: number; /** Whether the item is flagged as softcore content */
201
+ softcore: boolean;
202
+ vote_average: number;
203
+ vote_count: number;
204
+ };
205
+ /**
206
+ * Movie item in known_for array
207
+ */
208
+ type KnownForMovie = BaseKnownForItem & {
209
+ /** Media type discriminator */media_type: "movie"; /** Movie title (localized) */
210
+ title: string; /** Original title in the original language */
211
+ original_title: string; /** Release date in ISO 8601 format (YYYY-MM-DD) */
212
+ release_date: string; /** Whether a video is available on TMDB */
213
+ video: boolean;
214
+ };
215
+ /**
216
+ * TV show item in known_for array
217
+ */
218
+ type KnownForTV = BaseKnownForItem & {
219
+ /** Media type discriminator */media_type: "tv"; /** Series name (localized) */
220
+ name: string; /** Original series name */
221
+ original_name: string; /** First air date (YYYY-MM-DD) */
222
+ first_air_date: string; /** Origin country codes (ISO 3166-1 array) */
223
+ origin_country: CountryISO3166_1[];
224
+ };
225
+ /**
226
+ * Union type for items in the known_for array (can be either movie or TV show)
227
+ */
228
+ type KnownForItem = KnownForMovie | KnownForTV;
229
+ /** Available media types on TMDB */
230
+ type MediaType = "movie" | "tv";
231
+ /**
232
+ * Content rating information for a TV show or movie
233
+ */
234
+ type ContentRating = {
235
+ /** Additional content descriptors or advisory warnings (e.g., "violence", "language", "nudity") */descriptors: string[]; /** ISO 3166-1 country code where this rating applies */
236
+ iso_3166_1: string; /** Age or content rating (e.g., "TV-MA", "PG-13", "TV-14", "R") */
237
+ rating: string;
238
+ };
239
+ /**
240
+ * Individual movie review with author information
241
+ */
242
+ type Review = {
243
+ /** Review author's display name */author: string; /** Detailed information about the review author */
244
+ author_details: ReviewAuthorDetails; /** Full review text content */
245
+ content: string; /** Timestamp when the review was created (ISO 8601) */
246
+ created_at: string; /** Unique review identifier */
247
+ id: string; /** Timestamp of last update (ISO 8601) */
248
+ updated_at: string; /** URL to the review on TMDB website */
249
+ url: string;
250
+ };
251
+ /**
252
+ * Author information for a movie review
253
+ */
254
+ type ReviewAuthorDetails = {
255
+ /** Author's full name */name: string; /** Author's username on TMDB */
256
+ username: string; /** Path to author's avatar image (optional) */
257
+ avatar_path?: string; /** Rating given by the author (0-10 scale, optional) */
258
+ rating?: number;
259
+ };
260
+ /** Collection of translations for a media item (object with `id` and `translations`). */
261
+ type TranslationResults<T> = {
262
+ /** Absent when this resource is fetched via `append_to_response` rather than standalone. */id?: number | string;
263
+ translations: Translation<T>[];
264
+ };
265
+ /**
266
+ * Translation data for a specific language
267
+ */
268
+ type Translation<T = unknown> = {
269
+ /** ISO 3166-1 alpha-2 country code */iso_3166_1: string; /** ISO 639-1 language code */
270
+ iso_639_1: string; /** Native name of the language */
271
+ name: string; /** English name of the language */
272
+ english_name: string; /** Translated media (tv/movie) information */
273
+ data: T;
274
+ };
275
+ /**
276
+ * Watch provider availability by country
277
+ */
278
+ type MediaWatchProviders = {
279
+ /** Movie/TV show identifier. Absent when fetched via `append_to_response` rather than standalone. */id?: number; /** Watch providers grouped by country code */
280
+ results: Record<CountryISO3166_1, WatchProvider>;
281
+ };
282
+ /**
283
+ * Watch provider options for a specific country
284
+ */
285
+ type WatchProvider = {
286
+ /** URL to watch/purchase the movie */link: string; /** Ad-supported (free with ads) providers */
287
+ ads?: WatchProviderItem[]; /** Streaming providers (subscription required) */
288
+ flatrate?: WatchProviderItem[]; /** Free (no ads, no subscription) providers */
289
+ free?: WatchProviderItem[]; /** Rental providers */
290
+ rent?: WatchProviderItem[]; /** Purchase providers */
291
+ buy?: WatchProviderItem[];
292
+ };
293
+ /**
294
+ * Individual watch provider details
295
+ */
296
+ type WatchProviderItem = {
297
+ /** Path to provider logo image */logo_path: string; /** Unique provider identifier */
298
+ provider_id: number; /** Provider name (e.g., "Netflix", "Amazon Prime Video") */
299
+ provider_name: string; /** Display priority order (lower numbers = higher priority) */
300
+ display_priority: number;
301
+ };
302
+ //#endregion
303
+ //#region src/types/utility.d.ts
304
+ /**
305
+ * Forces TypeScript to resolve and display the final shape of a type.
306
+ * Useful for seeing the actual properties when hovering in the IDE.
307
+ */
308
+ type Prettify<T> = T extends object ? (T extends infer O ? { [K in keyof O]: Prettify<O[K]> } : never) : T;
309
+ /** Keep literal suggestions but allow any string */
310
+ type LiteralUnion<T extends string> = T | (string & {});
311
+ /** Keep literal suggestions but allow any number */
312
+ type LiteralUnionNumber<T extends number> = T | (number & {});
313
+ /**
314
+ * Type guard checks for KnowForItems (tv or movie)
315
+ * @returns
316
+ */
317
+ declare function isKnownForMovie(item: KnownForItem): item is KnownForMovie;
318
+ declare function isKnownForTV(item: KnownForItem): item is KnownForTV;
319
+ //#endregion
320
+ //#region src/types/common/images.d.ts
321
+ /**
322
+ * Defines the possible image collection keys returned by TMDB image endpoints.
323
+ */
324
+ type ImageCollectionKey = "backdrops" | "logos" | "posters" | "profiles" | "stills";
325
+ /**
326
+ * Image metadata and details
327
+ */
328
+ type ImageItem = {
329
+ /** Aspect ratio of the image (width/height) */aspect_ratio: number; /** Image height in pixels */
330
+ height: number; /** ISO 639-1 language code if image contains text, null otherwise */
331
+ iso_639_1?: string; /** ISO 3166-1 country code the image is tagged for, if any */
332
+ iso_3166_1?: string; /** Relative path to the image file (append to base URL) */
333
+ file_path: string; /** Average user rating for this image */
334
+ vote_average: number; /** Total number of votes for this image */
335
+ vote_count: number; /** Image width in pixels */
336
+ width: number;
337
+ };
338
+ /**
339
+ * Represents a single company or network logo (slightly different from ImageItem)
340
+ *
341
+ * Note on FileType from TMDB:
342
+ * There are two image formats that are supported for companies, PNG's and SVG's.
343
+ * You can see which type the original file is by looking at the file_type field.
344
+ * We prefer SVG's as they are resolution independent and as such, the width and height are only
345
+ * there to reflect the original asset that was uploaded.
346
+ * An SVG can be scaled properly beyond those dimensions if you call them as a PNG.
347
+ */
348
+ type OrganizationImage = Omit<ImageItem, "iso_639_1"> & {
349
+ id: string;
350
+ file_type: FileType;
351
+ };
352
+ /**
353
+ * Represents the response from a TMDB image endpoint.
354
+ * Use the generic parameter to specify which image collections are present.
355
+ *
356
+ * @template K - The image collection keys available for the given entity type.
357
+ *
358
+ * @example
359
+ * // Company or Network (logos only)
360
+ * type OrganizationImagesResult = ImagesResult<"logos">;
361
+ *
362
+ * @example
363
+ * // Movie or TV Show (backdrops, logos and posters)
364
+ * type MovieImagesResult = ImagesResult<"backdrops" | "logos" | "posters">;
365
+ *
366
+ * @example
367
+ * // Person (profiles only)
368
+ * type PersonImagesResult = ImagesResult<"profiles">;
369
+ */
370
+ type ImagesResult<T, K extends ImageCollectionKey> = {
371
+ /** The unique TMDB identifier of the entity. Absent when fetched via `append_to_response` rather than standalone. */id?: number;
372
+ } & { [P in K]: T[] };
373
+ /** Available file type on svg (for images) */
374
+ type FileType = LiteralUnion<".png" | ".svg">;
375
+ //#endregion
376
+ //#region src/types/config/images.d.ts
377
+ declare const IMAGE_BASE_URL = "http://image.tmdb.org/t/p/";
378
+ declare const IMAGE_SECURE_BASE_URL = "https://image.tmdb.org/t/p/";
379
+ declare const BACKDROP_SIZES: readonly ["w300", "w780", "w1280", "original"];
380
+ type BackdropSize = (typeof BACKDROP_SIZES)[number];
381
+ declare const LOGO_SIZES: readonly ["w45", "w92", "w154", "w185", "w300", "w500", "original"];
382
+ type LogoSize = (typeof LOGO_SIZES)[number];
383
+ declare const POSTER_SIZES: readonly ["w92", "w154", "w185", "w342", "w500", "w780", "original"];
384
+ type PosterSize = (typeof POSTER_SIZES)[number];
385
+ declare const PROFILE_SIZES: readonly ["w45", "w185", "h632", "original"];
386
+ type ProfileSize = (typeof PROFILE_SIZES)[number];
387
+ declare const STILL_SIZES: readonly ["w92", "w185", "w300", "original"];
388
+ type StillSize = (typeof STILL_SIZES)[number];
389
+ type ImageSize = BackdropSize | LogoSize | PosterSize | ProfileSize | StillSize;
390
+ /**
391
+ * Image size type definitions
392
+ */
393
+ type ImageSizeTypes = {
394
+ /** Size options for backdrop images: "w300", "w780", "w1280", "original" */BackdropSize: BackdropSize; /** Size options for logo images: "w45", "w92", "w154", "w185", "w300", "w500", "original" */
395
+ LogoSize: LogoSize; /** Size options for poster images: "w92", "w154", "w185", "w342", "w500", "w780", "original" */
396
+ PosterSize: PosterSize; /** Size options for profile images: "w45", "w185", "h632", "original" */
397
+ ProfileSize: ProfileSize; /** Size options for still images: "w92", "w185", "w300", "original" */
398
+ StillSize: StillSize; /** Union of all available image sizes */
399
+ ImageSize: ImageSize;
400
+ };
401
+ type DefaultImageSizesConfig = {
402
+ posters?: PosterSize;
403
+ backdrops?: BackdropSize;
404
+ logos?: LogoSize;
405
+ profiles?: ProfileSize;
406
+ still?: StillSize;
407
+ };
408
+ /**
409
+ * Per-collection language priority order used by `autocomplete_paths`.
410
+ *
411
+ * When set, image items in the matching collection array are reordered so that
412
+ * images whose `iso_639_1` matches earlier priority entries appear first.
413
+ * No items are ever dropped — only their order is affected.
414
+ *
415
+ * Special values:
416
+ * - `"null"` — matches untagged images (where `iso_639_1` is `null` or absent)
417
+ * - `"*"` — catch-all: consumes all remaining items at that position
418
+ *
419
+ * Items not matched by any entry are appended at the end.
420
+ *
421
+ * @example
422
+ * // Prefer textless posters → English → any fallback
423
+ * { posters: ["null", "en", "*"] }
424
+ */
425
+ type ImageLanguagePriorityConfig = Partial<Record<"backdrops" | "logos" | "posters" | "profiles" | "stills", string[]>>;
426
+ /**
427
+ * Fallback URL(s) used when an image path field is absent (`null` / `undefined`) in a TMDB
428
+ * API response and `autocompleteImagePaths` is applied.
429
+ *
430
+ * - **string** — one URL used for every image type
431
+ * - **object** — per-type URLs; any unspecified type keeps the original `null` / `undefined`
432
+ *
433
+ * @example
434
+ * // Single fallback for everything
435
+ * fallback_url: "/placeholder.png"
436
+ *
437
+ * @example
438
+ * // Different placeholders per type
439
+ * fallback_url: {
440
+ * posters: "/poster-placeholder.png",
441
+ * backdrops: "/backdrop-placeholder.png",
442
+ * }
443
+ */
444
+ type FallbackUrlConfig = string | Partial<Record<ImageCollectionKey, string>>;
445
+ type ImagesConfig = {
446
+ /**
447
+ * Whether to use the secure (HTTPS) image base URL.
448
+ * Defaults to true. Set to false only if working in an environment where HTTPS is not supported
449
+ * or where you explicitly need non-secure image URLs.
450
+ */
451
+ secure_images_url?: boolean;
452
+ /**
453
+ * Provide default image size configuration for each type of images.
454
+ */
455
+ default_image_sizes?: Partial<DefaultImageSizesConfig>;
456
+ /**
457
+ * Automatically expand TMDB image paths found in API responses into full URLs
458
+ * using the configured default image sizes.
459
+ *
460
+ * This is disabled by default to preserve the existing response shape semantics,
461
+ * where fields like `poster_path` contain the original relative TMDB path.
462
+ */
463
+ autocomplete_paths?: boolean;
464
+ /**
465
+ * Controls the order of image items inside collection arrays (e.g. `posters`, `backdrops`)
466
+ * when `autocomplete_paths` is enabled.
467
+ *
468
+ * Use `"null"` to match untagged images, ISO-639-1 codes (e.g. `"en"`) to match
469
+ * language-specific images, and `"*"` as a catch-all fallback.
470
+ *
471
+ * Items not matched by any entry are appended at the end. No items are dropped.
472
+ *
473
+ * @example
474
+ * image_language_priority: {
475
+ * posters: ["null", "en", "*"],
476
+ * }
477
+ */
478
+ image_language_priority?: ImageLanguagePriorityConfig;
479
+ /**
480
+ * When `true`, automatically derives `include_image_language` from the language
481
+ * codes declared in `image_language_priority` and injects it into every `.images()`
482
+ * request — so TMDB returns the language variants that the priority config expects
483
+ * to sort.
484
+ *
485
+ * The injected value is the union of all language codes across all configured
486
+ * collections, with `"*"` excluded (it has no meaning as an HTTP parameter).
487
+ * An explicit `include_image_language` on the call site always takes precedence.
488
+ *
489
+ * Requires `image_language_priority` to be set; has no effect without it.
490
+ *
491
+ * @default false
492
+ *
493
+ * @example
494
+ * // Config: automatically fetch Italian + textless posters on every images() call
495
+ * images: {
496
+ * autocomplete_paths: true,
497
+ * image_language_priority: { posters: ["it", "null", "*"] },
498
+ * auto_include_image_language: true,
499
+ * }
500
+ * // Equivalent to always passing: include_image_language: ["it", "null"]
501
+ */
502
+ auto_include_image_language?: boolean;
503
+ /**
504
+ * Fallback URL returned for image path fields that are absent (`null` / `undefined`) in the
505
+ * API response.
506
+ *
507
+ * Works independently of `autocomplete_paths`. When set, the response traversal is activated
508
+ * even if `autocomplete_paths` is `false`, but only null/undefined image paths are replaced —
509
+ * existing relative paths are left as-is unless `autocomplete_paths` is also `true`.
510
+ *
511
+ * @example
512
+ * fallback_url: "/placeholder.png"
513
+ *
514
+ * @example
515
+ * fallback_url: { posters: "/poster-ph.png", backdrops: "/backdrop-ph.png" }
516
+ */
517
+ fallback_url?: FallbackUrlConfig;
518
+ };
519
+ //#endregion
520
+ //#region src/images/images.d.ts
521
+ declare class ImageAPI {
522
+ private options;
523
+ constructor(options?: ImagesConfig);
524
+ private buildUrl;
525
+ backdrop(path: string, size?: BackdropSize): string;
526
+ logo(path: string, size?: LogoSize): string;
527
+ poster(path: string, size?: PosterSize): string;
528
+ profile(path: string, size?: ProfileSize): string;
529
+ still(path: string, size?: StillSize): string;
530
+ /**
531
+ * Recursively processes an object or array to autocomplete image paths by transforming string values
532
+ * and tracking the current image collection context.
533
+ *
534
+ * @template T - The type of the value being processed
535
+ * @param value - The value to process (can be an object, array, string, or primitive)
536
+ * @param collectionKey - Optional image collection key to maintain context during recursion
537
+ * @returns The processed value with autocompleted image paths, maintaining the original type
538
+ *
539
+ * @remarks
540
+ * - Arrays are recursively mapped over each entry
541
+ * - String values are transformed using {@link transformPathValue}
542
+ * - Object keys that match image collection keys update the collection context
543
+ * - Non-plain objects (e.g. Date/class instances) are returned unchanged
544
+ */
545
+ autocompleteImagePaths<T>(value: T, collectionKey?: ImageCollectionKey): T;
546
+ /**
547
+ * Traverses a response object substituting `null` / `undefined` image path fields with the
548
+ * configured `fallback_url` without expanding existing relative paths to full URLs.
549
+ *
550
+ * Used internally by the client when `fallback_url` is set but `autocomplete_paths` is `false`.
551
+ */
552
+ applyFallbacksOnly<T>(value: T): T;
553
+ private traverse;
554
+ /**
555
+ * Reorders an image-item array according to a language priority list.
556
+ *
557
+ * Iterates through each priority entry in order:
558
+ * - `"null"` matches items where `iso_639_1` is `null` or `undefined` (untagged)
559
+ * - `"*"` consumes all remaining items as a catch-all and stops processing
560
+ * - Any other string is matched against `iso_639_1` directly
561
+ *
562
+ * Items not matched by any entry are appended at the end.
563
+ * No items are dropped — only their order changes.
564
+ */
565
+ private sortByLanguagePriority;
566
+ private isImageCollectionKey;
567
+ private getFallbackForCollection;
568
+ private isFullUrl;
569
+ private buildImageUrl;
570
+ private transformPathValue;
571
+ }
572
+ //#endregion
573
+ export { VideoItem as $, AlternativeName as A, KnownForItem as B, ImagesResult as C, Prettify as D, LiteralUnionNumber as E, Credit as F, MovieCollection as G, KnownForTV as H, Crew as I, Review as J, ProductionCompany as K, Genre as L, AlternativeTitle as M, Cast as N, isKnownForMovie as O, ContentRating as P, TranslationResults as Q, GenresResponse as R, ImageItem as S, LiteralUnion as T, MediaType as U, KnownForMovie as V, MediaWatchProviders as W, SpokenLanguage as X, ReviewAuthorDetails as Y, Translation as Z, ProfileSize as _, FallbackUrlConfig as a, TMDBCountries as at, FileType as b, ImageLanguagePriorityConfig as c, ConfigurationJob as ct, ImagesConfig as d, ConfigurationTimezone as dt, VideoResults as et, LOGO_SIZES as f, ImageConfiguration as ft, PosterSize as g, PROFILE_SIZES as h, PrimaryTranslations as ht, DefaultImageSizesConfig as i, CountryISO3166_1 as it, AlternativeNamesResult as j, isKnownForTV as k, ImageSize as l, ConfigurationLanguage as lt, POSTER_SIZES as m, LanguageISO6391 as mt, BACKDROP_SIZES as n, WatchProvider as nt, IMAGE_BASE_URL as o, ConfigurationCountriesParams as ot, LogoSize as p, Language as pt, ProductionCountry as q, BackdropSize as r, WatchProviderItem as rt, IMAGE_SECURE_BASE_URL as s, ConfigurationCountry as st, ImageAPI as t, WatchMonetizationType as tt, ImageSizeTypes as u, ConfigurationResponse as ut, STILL_SIZES as v, OrganizationImage as w, ImageCollectionKey as x, StillSize as y, Keyword as z };
@@ -0,0 +1 @@
1
+ const e=`http://image.tmdb.org/t/p/`,t=`https://image.tmdb.org/t/p/`,n=[`w300`,`w780`,`w1280`,`original`],r=[`w45`,`w92`,`w154`,`w185`,`w300`,`w500`,`original`],i=[`w92`,`w154`,`w185`,`w342`,`w500`,`w780`,`original`],a=[`w45`,`w185`,`h632`,`original`],o=[`w92`,`w185`,`w300`,`original`];function s(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function c(e){if(!s(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function l(e){return typeof e==`object`&&!!e&&`poster_path`in e&&typeof e.poster_path==`string`}function u(e){return typeof e==`object`&&!!e&&`backdrop_path`in e&&typeof e.backdrop_path==`string`}function d(e){return typeof e==`object`&&!!e&&`profile_path`in e&&typeof e.profile_path==`string`}function f(e){return typeof e==`object`&&!!e&&`still_path`in e&&typeof e.still_path==`string`}function p(e){return typeof e==`object`&&!!e&&`logo_path`in e&&typeof e.logo_path==`string`}const m={backdrop_path:`backdrop`,logo_path:`logo`,poster_path:`poster`,profile_path:`profile`,still_path:`still`},h={backdrop_path:`backdrops`,logo_path:`logos`,poster_path:`posters`,profile_path:`profiles`,still_path:`stills`},g={backdrops:`backdrop_path`,logos:`logo_path`,posters:`poster_path`,profiles:`profile_path`,stills:`still_path`};var _=class{options;constructor(e={}){this.options={secure_images_url:!0,...e}}buildUrl(n,r){return`${this.options.secure_images_url?t:e}${r}${n}`}backdrop(e,t=this.options.default_image_sizes?.backdrops||`w780`){return this.buildUrl(e,t)}logo(e,t=this.options.default_image_sizes?.logos||`w185`){return this.buildUrl(e,t)}poster(e,t=this.options.default_image_sizes?.posters||`w500`){return this.buildUrl(e,t)}profile(e,t=this.options.default_image_sizes?.profiles||`w185`){return this.buildUrl(e,t)}still(e,t=this.options.default_image_sizes?.still||`w300`){return this.buildUrl(e,t)}autocompleteImagePaths(e,t){return this.traverse(e,t,!0)}applyFallbacksOnly(e){return this.traverse(e,void 0,!1)}traverse(e,t,n){if(Array.isArray(e)){let r=n&&t&&this.options.image_language_priority?.[t];return(r?this.sortByLanguagePriority(e,r):e).map(e=>this.traverse(e,t,n))}if(!c(e))return e;let r=Object.create(null);for(let[i,a]of Object.entries(e)){if(i===`__proto__`||i===`constructor`||i===`prototype`){r[i]=a;continue}if(a==null){if(Object.hasOwn(m,i)){let e=h[i];r[i]=this.getFallbackForCollection(e)??a;continue}if(i===`file_path`&&t){r[i]=this.getFallbackForCollection(t)??a;continue}r[i]=a;continue}if(typeof a==`string`){r[i]=n?this.transformPathValue(i,a,t):a;continue}let e=this.isImageCollectionKey(i)?i:t;r[i]=this.traverse(a,e,n)}return r}sortByLanguagePriority(e,t){let n=[],r=[...e];for(let e of t){if(e===`*`){n.push(...r.splice(0,r.length));break}let t=[];for(let i of r){let r=i?.iso_639_1;(e===`null`?r==null:r===e)?n.push(i):t.push(i)}r.length=0,r.push(...t)}return n.push(...r),n}isImageCollectionKey(e){return Object.hasOwn(g,e)}getFallbackForCollection(e){let t=this.options.fallback_url;if(t!=null)return typeof t==`string`?t:t[e]}isFullUrl(e){return/^https?:\/\//.test(e)}buildImageUrl(e,t){let n=m[e];return Object.hasOwn(this,n)||this[n],this[n](t)}transformPathValue(e,t,n){return!t.startsWith(`/`)||this.isFullUrl(t)?t:Object.hasOwn(m,e)?this.buildImageUrl(e,t):e===`file_path`&&n?this.buildImageUrl(g[n],t):t}};export{d as a,s as c,t as d,r as f,o as h,l as i,n as l,a as m,u as n,f as o,i as p,p as r,c as s,_ as t,e as u};