@lorenzopant/tmdb 1.17.3 → 1.17.4

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
@@ -28,23 +28,23 @@ yard add @lorenzopant/tmdb
28
28
  ## Usage
29
29
 
30
30
  ```typescript
31
- import { TMDB } from '@lorenzopant/tmdb';
31
+ import { TMDB } from "@lorenzopant/tmdb";
32
32
 
33
- const tmdb = new TMDB('your_access_token');
33
+ const tmdb = new TMDB("your_access_token");
34
34
 
35
35
  async function searchMovies() {
36
- try {
37
- const movies = await tmdb.search.movies({ query: 'Fight Club' });
38
- console.log(movies);
39
- } catch (error) {
40
- if (error instanceof TMDBError) {
41
- console.error('TMDB Error:', error.message);
42
- console.error('HTTP Status:', error.http_status_code);
43
- console.error('TMDB Status Code:', error.tmdb_status_code);
44
- } else {
45
- console.error('Unknown error:', error);
46
- }
47
- }
36
+ try {
37
+ const movies = await tmdb.search.movies({ query: "Fight Club" });
38
+ console.log(movies);
39
+ } catch (error) {
40
+ if (error instanceof TMDBError) {
41
+ console.error("TMDB Error:", error.message);
42
+ console.error("HTTP Status:", error.http_status_code);
43
+ console.error("TMDB Status Code:", error.tmdb_status_code);
44
+ } else {
45
+ console.error("Unknown error:", error);
46
+ }
47
+ }
48
48
  }
49
49
 
50
50
  searchMovies();
@@ -77,11 +77,11 @@ Custom logger:
77
77
 
78
78
  ```typescript
79
79
  const tmdb = new TMDB("your_access_token", {
80
- logger: (entry) => {
81
- if (entry.type === "response") {
82
- console.log("TMDB:", entry.endpoint, entry.status, entry.durationMs);
83
- }
84
- },
80
+ logger: (entry) => {
81
+ if (entry.type === "response") {
82
+ console.log("TMDB:", entry.endpoint, entry.status, entry.durationMs);
83
+ }
84
+ },
85
85
  });
86
86
  ```
87
87
 
package/dist/index.d.ts CHANGED
@@ -580,6 +580,40 @@ type ImagesConfig = {
580
580
  default_image_sizes?: Partial<DefaultImageSizesConfig>;
581
581
  };
582
582
 
583
+ /**
584
+ * Represents a generic error or an error specific to the TMDB (The Movie Database) API.
585
+ * This error class extends the built-in `Error` class and includes additional
586
+ * properties to provide more context about the error.
587
+ */
588
+ declare class TMDBError extends Error {
589
+ /**
590
+ * The status code returned by the TMDB API.
591
+ * If the value is `-1`, it indicates a library-specific error rather than a TMDB API error.
592
+ * @reference https://developer.themoviedb.org/docs/errors - code
593
+ */
594
+ tmdb_status_code: number;
595
+ /**
596
+ * A descriptive message providing details about the error.
597
+ * If the error is specific to the TMDB API, this message will be derived from the API response
598
+ * @reference https://developer.themoviedb.org/docs/errors - message
599
+ */
600
+ message: string;
601
+ /**
602
+ * The HTTP status code associated with the error.
603
+ * If the error is specific to the TMDB API, this code will be derived from the API response.
604
+ * @reference https://developer.themoviedb.org/docs/errors - HTTP Status
605
+ */
606
+ http_status_code: number;
607
+ /**
608
+ * Creates an instance of `TMDBError`.
609
+ *
610
+ * @param message - A descriptive message providing details about the error.
611
+ * @param http_status - The HTTP status code associated with the error.
612
+ * @param tmdb_status_code - (Optional) The status code returned by the TMDB API. Defaults to `-1` for library-specific errors.
613
+ */
614
+ constructor(message: string, http_status: number, tmdb_status_code?: number);
615
+ }
616
+
583
617
  type TMDBLoggerEntry = {
584
618
  type: "request" | "response" | "error";
585
619
  method: "GET";
@@ -1350,6 +1384,81 @@ declare const TIMEZONE_DATA: readonly [{
1350
1384
  readonly zones: readonly ["Africa/Maputo"];
1351
1385
  }];
1352
1386
 
1387
+ /**
1388
+ * Context object passed to every request interceptor before a TMDB API call is made.
1389
+ * Interceptors may return a modified copy of this object to override the endpoint or params,
1390
+ * or return `void` / `undefined` to leave the request unchanged.
1391
+ */
1392
+ type RequestInterceptorContext = {
1393
+ /** The API path being requested, e.g. `"/movie/550"`. */
1394
+ endpoint: string;
1395
+ /** Query parameters that will be appended to the URL. Mutating this object has no effect — return a new context instead. */
1396
+ params: Record<string, unknown>;
1397
+ /** The HTTP method. Currently always `"GET"`. */
1398
+ method: "GET";
1399
+ };
1400
+ /**
1401
+ * A function that runs before each TMDB API request.
1402
+ *
1403
+ * - Return `void` / `undefined` to leave the request unchanged.
1404
+ * - Return a (partial) {@link RequestInterceptorContext} to override `endpoint` and/or `params`.
1405
+ * - Async interceptors are awaited in order.
1406
+ *
1407
+ * @example
1408
+ * ```ts
1409
+ * const tmdb = new TMDB(token, {
1410
+ * interceptors: {
1411
+ * request: (ctx) => {
1412
+ * console.log(`[TMDB] ${ctx.method} ${ctx.endpoint}`, ctx.params);
1413
+ * },
1414
+ * },
1415
+ * });
1416
+ * ```
1417
+ */
1418
+ type RequestInterceptor = (context: RequestInterceptorContext) => RequestInterceptorContext | void | Promise<RequestInterceptorContext | void>;
1419
+ /**
1420
+ * Called after every successful TMDB API response, before data is returned to the caller.
1421
+ *
1422
+ * - Receives the parsed response as `unknown` (the interceptor is not aware of the specific type).
1423
+ * - Return the data (same shape) to pass it through — or return `void` to fall back to the original.
1424
+ * - Designed for side effects: logging, caching, image URL enrichment.
1425
+ * - Must **not** change the shape of the returned data.
1426
+ *
1427
+ * @example
1428
+ * ```ts
1429
+ * const tmdb = new TMDB(token, {
1430
+ * interceptors: {
1431
+ * response: {
1432
+ * onSuccess: (data) => {
1433
+ * myCache.set(data);
1434
+ * },
1435
+ * },
1436
+ * },
1437
+ * });
1438
+ * ```
1439
+ */
1440
+ type ResponseSuccessInterceptor = (data: unknown) => unknown | void | Promise<unknown | void>;
1441
+ /**
1442
+ * Called after a TMDB API error has been normalised into a {@link TMDBError}.
1443
+ *
1444
+ * - Receives a typed `TMDBError` — never raw `unknown`.
1445
+ * - Return `void` — this hook is for side effects only (logging, toast notifications, Sentry).
1446
+ * - The `TMDBError` is **always re-thrown** after the interceptor runs; you cannot suppress it.
1447
+ *
1448
+ * @example
1449
+ * ```ts
1450
+ * const tmdb = new TMDB(token, {
1451
+ * interceptors: {
1452
+ * response: {
1453
+ * onError: (error) => {
1454
+ * Sentry.captureException(error);
1455
+ * },
1456
+ * },
1457
+ * },
1458
+ * });
1459
+ * ```
1460
+ */
1461
+ type ResponseErrorInterceptor = (error: TMDBError) => void | Promise<void>;
1353
1462
  type TMDBOptions = {
1354
1463
  /**
1355
1464
  * The language to use for requests (ISO 639-1 code)
@@ -1390,6 +1499,38 @@ type TMDBOptions = {
1390
1499
  * @default true
1391
1500
  */
1392
1501
  deduplication?: boolean;
1502
+ /**
1503
+ * Interceptors that run at specific points in the request lifecycle.
1504
+ *
1505
+ * `request` interceptors are called **before** every API request, in the order
1506
+ * they are provided. Each interceptor receives a {@link RequestInterceptorContext}
1507
+ * and may optionally return a modified context to change the endpoint or params.
1508
+ *
1509
+ * @example
1510
+ * ```ts
1511
+ * const tmdb = new TMDB(token, {
1512
+ * interceptors: {
1513
+ * request: [
1514
+ * (ctx) => console.log(`→ ${ctx.endpoint}`),
1515
+ * (ctx) => ({ ...ctx, params: { ...ctx.params, include_adult: false } }),
1516
+ * ],
1517
+ * },
1518
+ * });
1519
+ * ```
1520
+ */
1521
+ interceptors?: {
1522
+ request?: RequestInterceptor | RequestInterceptor[];
1523
+ /**
1524
+ * Response lifecycle hooks.
1525
+ *
1526
+ * - `onSuccess` — runs after every successful response, before data is returned.
1527
+ * - `onError` — runs after a {@link TMDBError} is created; always re-throws after.
1528
+ */
1529
+ response?: {
1530
+ onSuccess?: ResponseSuccessInterceptor;
1531
+ onError?: ResponseErrorInterceptor;
1532
+ };
1533
+ };
1393
1534
  };
1394
1535
 
1395
1536
  /**
@@ -3529,9 +3670,19 @@ declare class ApiClient {
3529
3670
  */
3530
3671
  private inflightRequests;
3531
3672
  private deduplication;
3673
+ private requestInterceptors;
3674
+ private onSuccessInterceptor?;
3675
+ private onErrorInterceptor?;
3532
3676
  constructor(accessToken: string, options?: {
3533
3677
  logger?: boolean | TMDBLoggerFn;
3534
3678
  deduplication?: boolean;
3679
+ interceptors?: {
3680
+ request?: RequestInterceptor | RequestInterceptor[];
3681
+ response?: {
3682
+ onSuccess?: ResponseSuccessInterceptor;
3683
+ onError?: ResponseErrorInterceptor;
3684
+ };
3685
+ };
3535
3686
  });
3536
3687
  /**
3537
3688
  * Builds a stable, order-independent cache key for a request.
@@ -3558,6 +3709,11 @@ declare class ApiClient {
3558
3709
  * `TMDBOptions.deduplication = false`.
3559
3710
  */
3560
3711
  request<T>(endpoint: string, params?: Record<string, unknown | undefined>): Promise<T>;
3712
+ /**
3713
+ * Runs all registered request interceptors in order, threading the context through each one.
3714
+ * If an interceptor returns a new context, it replaces the current context for the next interceptor.
3715
+ */
3716
+ private runRequestInterceptors;
3561
3717
  /**
3562
3718
  * The actual fetch + response-parsing pipeline. Called by `request()` only when no
3563
3719
  * matching in-flight promise exists. Handles URL construction, auth headers, logging,
@@ -5053,40 +5209,6 @@ declare class TMDB {
5053
5209
  constructor(accessToken: string, options?: TMDBOptions);
5054
5210
  }
5055
5211
 
5056
- /**
5057
- * Represents a generic error or an error specific to the TMDB (The Movie Database) API.
5058
- * This error class extends the built-in `Error` class and includes additional
5059
- * properties to provide more context about the error.
5060
- */
5061
- declare class TMDBError extends Error {
5062
- /**
5063
- * The status code returned by the TMDB API.
5064
- * If the value is `-1`, it indicates a library-specific error rather than a TMDB API error.
5065
- * @reference https://developer.themoviedb.org/docs/errors - code
5066
- */
5067
- tmdb_status_code: number;
5068
- /**
5069
- * A descriptive message providing details about the error.
5070
- * If the error is specific to the TMDB API, this message will be derived from the API response
5071
- * @reference https://developer.themoviedb.org/docs/errors - message
5072
- */
5073
- message: string;
5074
- /**
5075
- * The HTTP status code associated with the error.
5076
- * If the error is specific to the TMDB API, this code will be derived from the API response.
5077
- * @reference https://developer.themoviedb.org/docs/errors - HTTP Status
5078
- */
5079
- http_status_code: number;
5080
- /**
5081
- * Creates an instance of `TMDBError`.
5082
- *
5083
- * @param message - A descriptive message providing details about the error.
5084
- * @param http_status - The HTTP status code associated with the error.
5085
- * @param tmdb_status_code - (Optional) The status code returned by the TMDB API. Defaults to `-1` for library-specific errors.
5086
- */
5087
- constructor(message: string, http_status: number, tmdb_status_code?: number);
5088
- }
5089
-
5090
5212
  declare function isJwt(token: string): boolean;
5091
5213
 
5092
5214
  /** Utility type guard to check if an object has a poster_path property */
@@ -5110,4 +5232,4 @@ declare function hasLogoPath(data: unknown): data is {
5110
5232
  logo_path: string;
5111
5233
  };
5112
5234
 
5113
- export { type AlternativeName, type AlternativeNamesResult, type AlternativeTitle, BACKDROP_SIZES, type BackdropSize, type Cast, type CertificationItem, type Certifications, type Change, type ChangeItem, type ChangeResultItem, type Changes, type Collection, type CollectionBaseParam, type CollectionDetailsParams, type CollectionImages, type CollectionImagesParams, type CollectionItem, type CollectionResultItem, type CollectionTranslationData, type CollectionTranslations, type Company, type CompanyAlternativeName, type CompanyAlternativeNames, type CompanyAlternativeNamesParams, type CompanyBaseParam, type CompanyDetailsParams, type CompanyImages, type CompanyImagesParams, type CompanyResultItem, type CompanySummary, type ConfigurationCountriesParams, type ConfigurationCountry, type ConfigurationJob, type ConfigurationLanguage, type ConfigurationResponse, type ConfigurationTimezone, type ContentRating, type CountryISO3166_1, type Credit, type CreditBaseParam, type CreditDetails, type CreditDetailsMedia, type CreditDetailsMovieMedia, type CreditDetailsParams, type CreditDetailsPerson, type CreditDetailsTVEpisode, type CreditDetailsTVMedia, type CreditDetailsTVSeason, type Crew, type DateRange, type DefaultImageSizesConfig, type DiscoverFilterExpression, type DiscoverMovieParams, type DiscoverMovieSortBy, type DiscoverTVParams, type DiscoverTVResultItem, type DiscoverTVSortBy, DiscoverTVStatus, DiscoverTVType, type FileType, type FindByIDParams, type FindExternalSource, type FindMovieResultItem, type FindPersonResultItem, type FindResults, type FindTVEpisodeResultItem, type FindTVResultItem, type FindTVSeasonResultItem, type Genre, type GenresResponse, IMAGE_BASE_URL, IMAGE_SECURE_BASE_URL, type ImageCollectionKey, type ImageConfiguration, type ImageItem, type ImageSize, type ImageSizeTypes, type ImagesConfig, type ImagesResult, type Keyword, type KeywordBaseParam, type KeywordDetailsParams, type KeywordMoviesParams, type KeywordResultItem, type KnownForItem, type KnownForMovie, type KnownForTV, LOGO_SIZES, type Language, type LanguageISO6391, type LiteralUnion, type LogoSize, type MediaType, type MediaWatchProviders, type MovieAlternativeTitles, type MovieAlternativeTitlesParams, type MovieAppendToResponseNamespace, type MovieAppendableMap, type MovieChanges, type MovieChangesParams, type MovieCollection, type MovieCredits, type MovieCreditsParams, type MovieDetails, type MovieDetailsParams, type MovieDetailsWithAppends, type MovieExternalIDs, type MovieExternalIDsParams, type MovieImages, type MovieImagesParams, type MovieKeywords, type MovieKeywordsParams, type MovieListParams, type MovieRecommendations, type MovieRecommendationsParams, type MovieReleaseDate, type MovieReleaseDateResult, type MovieReleaseDates, type MovieReleaseDatesParams, type MovieResultItem, type MovieReviews, type MovieReviewsParams, type MovieSimilar, type MovieSimilarParams, type MovieTranslationData, type MovieTranslations, type MovieTranslationsParams, type MovieVideos, type MovieVideosParams, type MovieWatchProvidersParams, type MultiSearchResultItem, type Network, type NetworkBaseParams, type NetworkImages, type NetworkItem, type OrganizationImage, POSTER_SIZES, PROFILE_SIZES, type PaginatedResponse, type PeopleListParams, type PersonAppendToResponseNamespace, type PersonAppendableMap, type PersonBaseParam, type PersonChanges, type PersonChangesParams, type PersonCombinedCastCredit, type PersonCombinedCredits, type PersonCombinedCrewCredit, type PersonCreditsParams, type PersonDetails, type PersonDetailsParams, type PersonDetailsWithAppends, type PersonExternalIDs, type PersonExternalIDsParams, type PersonImages, type PersonImagesParams, type PersonMovieCastCredit, type PersonMovieCredits, type PersonMovieCrewCredit, type PersonResultItem, type PersonTVCastCredit, type PersonTVCredits, type PersonTVCrewCredit, type PersonTaggedImage, type PersonTaggedImageMedia, type PersonTaggedImages, type PersonTaggedImagesParams, type PersonTranslationData, type PersonTranslations, type PersonTranslationsParams, type PosterSize, type Prettify, type PrimaryTranslations, type ProductionCompany, type ProductionCountry, type ProfileSize, type Review, type ReviewAuthorDetails, type ReviewDetails, type ReviewDetailsParams, STILL_SIZES, type SearchCollectionsParams, type SearchCompanyParams, type SearchKeywordsParams, type SearchMoviesParams, type SearchMultiParams, type SearchPersonParams, type SearchTVSeriesParams, type SpokenLanguage, type StillSize, TMDB, TMDBCountries, TMDBError, TMDBLogger, type TMDBLoggerEntry, type TMDBLoggerFn, type TMDBOptions, type TMDBQueryParams, type TVAggregateCredits, type TVAggregateCreditsCastItem, type TVAggregateCreditsCrewItem, type TVAggregateCreditsParams, type TVAlternativeTitles, type TVAppendToResponseNamespace, type TVAppendableMap, type TVBaseParam, type TVChangeParams, type TVContentRatings, type TVCreditJob, type TVCreditRole, type TVCredits, type TVCreditsParams, type TVDetailsParams, type TVDetailsWithAppends, type TVEpisode, type TVEpisodeAppendToResponseNamespace, type TVEpisodeAppendableMap, type TVEpisodeBaseParams, type TVEpisodeCredits, type TVEpisodeCreditsParams, type TVEpisodeDetailsParams, type TVEpisodeDetailsWithAppends, type TVEpisodeExternalIDs, type TVEpisodeGroupDetails, type TVEpisodeGroupDetailsItem, type TVEpisodeGroupEpisode, type TVEpisodeGroupItem, type TVEpisodeGroupParams, TVEpisodeGroupType, type TVEpisodeGroups, type TVEpisodeId, type TVEpisodeImages, type TVEpisodeImagesParams, type TVEpisodeItem, type TVEpisodeTranslationData, type TVEpisodeTranslations, type TVEpisodeVideos, type TVExternalIDs, type TVImageItem, type TVImages, type TVImagesParams, type TVKeywords, type TVRecommendations, type TVRecommendationsParams, type TVReviews, type TVReviewsParams, type TVScreenedTheatrically, type TVScreeningItem, type TVSeason, type TVSeasonAggregateCredits, type TVSeasonAggregateCreditsParams, type TVSeasonAppendToResponseNamespace, type TVSeasonAppendableMap, type TVSeasonBaseParams, type TVSeasonChanges, type TVSeasonChangesParams, type TVSeasonCredits, type TVSeasonCreditsParams, type TVSeasonDetailsParams, type TVSeasonDetailsWithAppends, type TVSeasonEpisode, type TVSeasonExternalIDs, type TVSeasonId, type TVSeasonImages, type TVSeasonImagesParams, type TVSeasonItem, type TVSeasonTranslationData, type TVSeasonTranslations, type TVSeasonVideos, type TVSeasonVideosParams, type TVSeasonWatchProvidersParams, type TVSeriesChanges, type TVSeriesDetails, type TVSeriesListItem, type TVSeriesListParams, type TVSeriesLists, type TVSeriesListsParams, type TVSeriesResultItem, type TVSimilar, type TVSimilarParams, type TVTranslationData, type TVTranslations, type TVVideos, type Timezone, type Translation, type TranslationResults, type TrendingAllResult, type TrendingMovieResult, type TrendingParams, type TrendingPersonResult, type TrendingTVResult, type TrendingTimeWindow, type VideoItem, type VideoResults, type WatchMonetizationType, type WatchProvider, type WatchProviderDisplayPriorities, type WatchProviderItem, type WatchProviderListItem, type WatchProviderListParams, type WatchProviderListResponse, type WatchProviderRegionsParams, type WatchProviderRegionsResponse, type WithLanguage, type WithLanguagePage, type WithPage, type WithPageAndDateRange, type WithParams, type WithRegion, hasBackdropPath, hasLogoPath, hasPosterPath, hasProfilePath, hasStillPath, isJwt, isKnownForMovie, isKnownForTV };
5235
+ export { type AlternativeName, type AlternativeNamesResult, type AlternativeTitle, BACKDROP_SIZES, type BackdropSize, type Cast, type CertificationItem, type Certifications, type Change, type ChangeItem, type ChangeResultItem, type Changes, type Collection, type CollectionBaseParam, type CollectionDetailsParams, type CollectionImages, type CollectionImagesParams, type CollectionItem, type CollectionResultItem, type CollectionTranslationData, type CollectionTranslations, type Company, type CompanyAlternativeName, type CompanyAlternativeNames, type CompanyAlternativeNamesParams, type CompanyBaseParam, type CompanyDetailsParams, type CompanyImages, type CompanyImagesParams, type CompanyResultItem, type CompanySummary, type ConfigurationCountriesParams, type ConfigurationCountry, type ConfigurationJob, type ConfigurationLanguage, type ConfigurationResponse, type ConfigurationTimezone, type ContentRating, type CountryISO3166_1, type Credit, type CreditBaseParam, type CreditDetails, type CreditDetailsMedia, type CreditDetailsMovieMedia, type CreditDetailsParams, type CreditDetailsPerson, type CreditDetailsTVEpisode, type CreditDetailsTVMedia, type CreditDetailsTVSeason, type Crew, type DateRange, type DefaultImageSizesConfig, type DiscoverFilterExpression, type DiscoverMovieParams, type DiscoverMovieSortBy, type DiscoverTVParams, type DiscoverTVResultItem, type DiscoverTVSortBy, DiscoverTVStatus, DiscoverTVType, type FileType, type FindByIDParams, type FindExternalSource, type FindMovieResultItem, type FindPersonResultItem, type FindResults, type FindTVEpisodeResultItem, type FindTVResultItem, type FindTVSeasonResultItem, type Genre, type GenresResponse, IMAGE_BASE_URL, IMAGE_SECURE_BASE_URL, type ImageCollectionKey, type ImageConfiguration, type ImageItem, type ImageSize, type ImageSizeTypes, type ImagesConfig, type ImagesResult, type Keyword, type KeywordBaseParam, type KeywordDetailsParams, type KeywordMoviesParams, type KeywordResultItem, type KnownForItem, type KnownForMovie, type KnownForTV, LOGO_SIZES, type Language, type LanguageISO6391, type LiteralUnion, type LogoSize, type MediaType, type MediaWatchProviders, type MovieAlternativeTitles, type MovieAlternativeTitlesParams, type MovieAppendToResponseNamespace, type MovieAppendableMap, type MovieChanges, type MovieChangesParams, type MovieCollection, type MovieCredits, type MovieCreditsParams, type MovieDetails, type MovieDetailsParams, type MovieDetailsWithAppends, type MovieExternalIDs, type MovieExternalIDsParams, type MovieImages, type MovieImagesParams, type MovieKeywords, type MovieKeywordsParams, type MovieListParams, type MovieRecommendations, type MovieRecommendationsParams, type MovieReleaseDate, type MovieReleaseDateResult, type MovieReleaseDates, type MovieReleaseDatesParams, type MovieResultItem, type MovieReviews, type MovieReviewsParams, type MovieSimilar, type MovieSimilarParams, type MovieTranslationData, type MovieTranslations, type MovieTranslationsParams, type MovieVideos, type MovieVideosParams, type MovieWatchProvidersParams, type MultiSearchResultItem, type Network, type NetworkBaseParams, type NetworkImages, type NetworkItem, type OrganizationImage, POSTER_SIZES, PROFILE_SIZES, type PaginatedResponse, type PeopleListParams, type PersonAppendToResponseNamespace, type PersonAppendableMap, type PersonBaseParam, type PersonChanges, type PersonChangesParams, type PersonCombinedCastCredit, type PersonCombinedCredits, type PersonCombinedCrewCredit, type PersonCreditsParams, type PersonDetails, type PersonDetailsParams, type PersonDetailsWithAppends, type PersonExternalIDs, type PersonExternalIDsParams, type PersonImages, type PersonImagesParams, type PersonMovieCastCredit, type PersonMovieCredits, type PersonMovieCrewCredit, type PersonResultItem, type PersonTVCastCredit, type PersonTVCredits, type PersonTVCrewCredit, type PersonTaggedImage, type PersonTaggedImageMedia, type PersonTaggedImages, type PersonTaggedImagesParams, type PersonTranslationData, type PersonTranslations, type PersonTranslationsParams, type PosterSize, type Prettify, type PrimaryTranslations, type ProductionCompany, type ProductionCountry, type ProfileSize, type RequestInterceptor, type RequestInterceptorContext, type ResponseErrorInterceptor, type ResponseSuccessInterceptor, type Review, type ReviewAuthorDetails, type ReviewDetails, type ReviewDetailsParams, STILL_SIZES, type SearchCollectionsParams, type SearchCompanyParams, type SearchKeywordsParams, type SearchMoviesParams, type SearchMultiParams, type SearchPersonParams, type SearchTVSeriesParams, type SpokenLanguage, type StillSize, TMDB, TMDBCountries, TMDBError, TMDBLogger, type TMDBLoggerEntry, type TMDBLoggerFn, type TMDBOptions, type TMDBQueryParams, type TVAggregateCredits, type TVAggregateCreditsCastItem, type TVAggregateCreditsCrewItem, type TVAggregateCreditsParams, type TVAlternativeTitles, type TVAppendToResponseNamespace, type TVAppendableMap, type TVBaseParam, type TVChangeParams, type TVContentRatings, type TVCreditJob, type TVCreditRole, type TVCredits, type TVCreditsParams, type TVDetailsParams, type TVDetailsWithAppends, type TVEpisode, type TVEpisodeAppendToResponseNamespace, type TVEpisodeAppendableMap, type TVEpisodeBaseParams, type TVEpisodeCredits, type TVEpisodeCreditsParams, type TVEpisodeDetailsParams, type TVEpisodeDetailsWithAppends, type TVEpisodeExternalIDs, type TVEpisodeGroupDetails, type TVEpisodeGroupDetailsItem, type TVEpisodeGroupEpisode, type TVEpisodeGroupItem, type TVEpisodeGroupParams, TVEpisodeGroupType, type TVEpisodeGroups, type TVEpisodeId, type TVEpisodeImages, type TVEpisodeImagesParams, type TVEpisodeItem, type TVEpisodeTranslationData, type TVEpisodeTranslations, type TVEpisodeVideos, type TVExternalIDs, type TVImageItem, type TVImages, type TVImagesParams, type TVKeywords, type TVRecommendations, type TVRecommendationsParams, type TVReviews, type TVReviewsParams, type TVScreenedTheatrically, type TVScreeningItem, type TVSeason, type TVSeasonAggregateCredits, type TVSeasonAggregateCreditsParams, type TVSeasonAppendToResponseNamespace, type TVSeasonAppendableMap, type TVSeasonBaseParams, type TVSeasonChanges, type TVSeasonChangesParams, type TVSeasonCredits, type TVSeasonCreditsParams, type TVSeasonDetailsParams, type TVSeasonDetailsWithAppends, type TVSeasonEpisode, type TVSeasonExternalIDs, type TVSeasonId, type TVSeasonImages, type TVSeasonImagesParams, type TVSeasonItem, type TVSeasonTranslationData, type TVSeasonTranslations, type TVSeasonVideos, type TVSeasonVideosParams, type TVSeasonWatchProvidersParams, type TVSeriesChanges, type TVSeriesDetails, type TVSeriesListItem, type TVSeriesListParams, type TVSeriesLists, type TVSeriesListsParams, type TVSeriesResultItem, type TVSimilar, type TVSimilarParams, type TVTranslationData, type TVTranslations, type TVVideos, type Timezone, type Translation, type TranslationResults, type TrendingAllResult, type TrendingMovieResult, type TrendingParams, type TrendingPersonResult, type TrendingTVResult, type TrendingTimeWindow, type VideoItem, type VideoResults, type WatchMonetizationType, type WatchProvider, type WatchProviderDisplayPriorities, type WatchProviderItem, type WatchProviderListItem, type WatchProviderListParams, type WatchProviderListResponse, type WatchProviderRegionsParams, type WatchProviderRegionsResponse, type WithLanguage, type WithLanguagePage, type WithPage, type WithPageAndDateRange, type WithParams, type WithRegion, hasBackdropPath, hasLogoPath, hasPosterPath, hasProfilePath, hasStillPath, isJwt, isKnownForMovie, isKnownForTV };
package/dist/index.js CHANGED
@@ -156,10 +156,17 @@ var ApiClient = class {
156
156
  */
157
157
  inflightRequests = /* @__PURE__ */ new Map();
158
158
  deduplication;
159
+ requestInterceptors;
160
+ onSuccessInterceptor;
161
+ onErrorInterceptor;
159
162
  constructor(accessToken, options = {}) {
160
163
  this.accessToken = accessToken;
161
164
  this.logger = TMDBLogger.from(options.logger);
162
165
  this.deduplication = options.deduplication !== false;
166
+ const raw = options.interceptors?.request;
167
+ this.requestInterceptors = raw == null ? [] : Array.isArray(raw) ? raw : [raw];
168
+ this.onSuccessInterceptor = options.interceptors?.response?.onSuccess;
169
+ this.onErrorInterceptor = options.interceptors?.response?.onError;
163
170
  }
164
171
  /**
165
172
  * Builds a stable, order-independent cache key for a request.
@@ -204,12 +211,27 @@ var ApiClient = class {
204
211
  this.inflightRequests.set(key, promise);
205
212
  return promise;
206
213
  }
214
+ /**
215
+ * Runs all registered request interceptors in order, threading the context through each one.
216
+ * If an interceptor returns a new context, it replaces the current context for the next interceptor.
217
+ */
218
+ async runRequestInterceptors(context) {
219
+ let current = context;
220
+ for (const interceptor of this.requestInterceptors) {
221
+ const result = await interceptor(current);
222
+ if (result != null) current = result;
223
+ }
224
+ return current;
225
+ }
207
226
  /**
208
227
  * The actual fetch + response-parsing pipeline. Called by `request()` only when no
209
228
  * matching in-flight promise exists. Handles URL construction, auth headers, logging,
210
229
  * error mapping, and null sanitisation.
211
230
  */
212
231
  async doRequest(endpoint, params) {
232
+ const ctx = await this.runRequestInterceptors({ endpoint, params, method: "GET" });
233
+ endpoint = ctx.endpoint;
234
+ params = ctx.params;
213
235
  const url = new URL(`${this.baseUrl}${endpoint}`);
214
236
  const jwt = isJwt(this.accessToken);
215
237
  for (const [key, value] of this.serializeParams(params)) {
@@ -244,7 +266,12 @@ var ApiClient = class {
244
266
  });
245
267
  throw error;
246
268
  }
247
- if (!res.ok) await this.handleError(res, endpoint);
269
+ if (!res.ok) {
270
+ await this.handleError(res, endpoint).catch(async (err) => {
271
+ if (this.onErrorInterceptor) await this.onErrorInterceptor(err);
272
+ throw err;
273
+ });
274
+ }
248
275
  this.logger?.log({
249
276
  type: "response",
250
277
  method: "GET",
@@ -254,7 +281,12 @@ var ApiClient = class {
254
281
  durationMs: Date.now() - startedAt
255
282
  });
256
283
  const data = await res.json();
257
- return this.sanitizeNulls(data);
284
+ const sanitized = this.sanitizeNulls(data);
285
+ if (this.onSuccessInterceptor) {
286
+ const result = await this.onSuccessInterceptor(sanitized);
287
+ return result !== void 0 ? result : sanitized;
288
+ }
289
+ return sanitized;
258
290
  }
259
291
  /**
260
292
  * Recursively converts null values to undefined in API responses.
@@ -2415,7 +2447,11 @@ var TMDB = class {
2415
2447
  constructor(accessToken, options = {}) {
2416
2448
  if (!accessToken) throw new Error(Errors.NO_ACCESS_TOKEN);
2417
2449
  this.options = options;
2418
- this.client = new ApiClient(accessToken, { logger: options.logger, deduplication: options.deduplication });
2450
+ this.client = new ApiClient(accessToken, {
2451
+ logger: options.logger,
2452
+ deduplication: options.deduplication,
2453
+ interceptors: options.interceptors
2454
+ });
2419
2455
  this.movies = new MoviesAPI(this.client, this.options);
2420
2456
  this.movie_lists = new MovieListsAPI(this.client, this.options);
2421
2457
  this.search = new SearchAPI(this.client, this.options);
package/package.json CHANGED
@@ -1,25 +1,44 @@
1
1
  {
2
2
  "name": "@lorenzopant/tmdb",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "type": "module",
5
5
  "description": "A completely type-safe The Movie Database (TMDB) API wrapper for typescript applications.",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "files": [
9
- "dist",
10
- "README.md"
6
+ "keywords": [
7
+ "api",
8
+ "movies",
9
+ "tmdb",
10
+ "typescript"
11
11
  ],
12
+ "homepage": "https://lorenzopant-tmdb-docs.vercel.app",
13
+ "bugs": {
14
+ "url": "https://github.com/lorenzopant/tmdb/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Lorenzo Pantano",
12
18
  "repository": {
13
19
  "type": "git",
14
20
  "url": "git+https://github.com/lorenzopant/tmdb"
15
21
  },
16
- "homepage": "https://lorenzopant-tmdb-docs.vercel.app",
17
- "bugs": {
18
- "url": "https://github.com/lorenzopant/tmdb/issues"
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "main": "dist/index.js",
27
+ "types": "dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/index.js",
31
+ "types": "./dist/index.d.ts"
32
+ },
33
+ "./types": {
34
+ "import": "./dist/index.js",
35
+ "types": "./dist/index.d.ts"
36
+ }
19
37
  },
20
38
  "scripts": {
21
39
  "build": "tsup",
22
40
  "dev": "tsup --watch",
41
+ "format": "oxfmt .",
23
42
  "typecheck": "tsc --noEmit",
24
43
  "test": "vitest",
25
44
  "test:unit": "vitest run --exclude '**/*.integration.test.ts'",
@@ -27,34 +46,18 @@
27
46
  "test:ui": "vitest --ui",
28
47
  "test:coverage": "vitest --coverage",
29
48
  "prepare": "husky",
30
- "lint": "eslint .",
49
+ "lint": "oxlint .",
50
+ "lint:check": "oxlint --type-aware --type-check .",
31
51
  "release": "pnpm release:patch",
32
52
  "release:patch": "pnpm version patch --git-tag-version && git push --follow-tags",
33
53
  "release:minor": "pnpm version minor --git-tag-version && git push --follow-tags",
34
54
  "release:major": "pnpm version major --git-tag-version && git push --follow-tags"
35
55
  },
36
- "author": "Lorenzo Pantano",
37
- "license": "MIT",
38
- "keywords": [
39
- "tmdb",
40
- "typescript",
41
- "api",
42
- "movies"
43
- ],
44
- "packageManager": "pnpm@8.8.0",
45
56
  "devDependencies": {
46
- "@eslint/compat": "^2.0.0",
47
- "@eslint/eslintrc": "^3.3.1",
48
- "@eslint/js": "^9.30.0",
49
57
  "@types/node": "^22.19.11",
50
- "@typescript-eslint/eslint-plugin": "^8.35.0",
51
- "@typescript-eslint/parser": "^8.35.0",
52
58
  "@vitest/coverage-v8": "^4.0.9",
53
59
  "@vitest/ui": "^4.0.10",
54
60
  "dotenv": "^16.5.0",
55
- "eslint": "^9.30.0",
56
- "eslint-config-prettier": "^10.1.5",
57
- "eslint-plugin-import": "^2.32.0",
58
61
  "husky": "^9.1.7",
59
62
  "release-it": "^19.0.3",
60
63
  "release-it-pnpm": "^4.6.6",
@@ -62,23 +65,13 @@
62
65
  "tsup": "^8.5.1",
63
66
  "tsx": "^4.21.0",
64
67
  "typescript": "^5.8.3",
65
- "typescript-eslint": "^8.35.0",
66
68
  "vite": "^7.0.0",
67
69
  "vitest": "^4.0.9"
68
70
  },
71
+ "packageManager": "pnpm@8.8.0",
69
72
  "pnpm": {
70
73
  "overrides": {
71
74
  "basic-ftp": "5.2.0"
72
75
  }
73
- },
74
- "exports": {
75
- ".": {
76
- "import": "./dist/index.js",
77
- "types": "./dist/index.d.ts"
78
- },
79
- "./types": {
80
- "import": "./dist/index.js",
81
- "types": "./dist/index.d.ts"
82
- }
83
76
  }
84
77
  }