ani-client 1.9.0 → 2.0.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
@@ -11,6 +11,8 @@
11
11
 
12
12
  ✨ **Showcase**: [See who's using ani-client](https://ani-client.js.org/showcase)
13
13
 
14
+ **Support server** [Discord server](https://discord.gg/3P7twDurUD)
15
+
14
16
  ## Highlights
15
17
 
16
18
  - **Zero dependencies** — uses the native `fetch` API
package/dist/index.d.mts CHANGED
@@ -699,12 +699,19 @@ interface Media {
699
699
  siteUrl: string | null;
700
700
  }
701
701
  interface SearchMediaOptions {
702
+ /** Search Term */
702
703
  query?: string;
704
+ /** Filter by country code (e.g., "JP", "KR") */
703
705
  countryOfOrigin?: string;
706
+ /** Filter by Anime or Manga */
704
707
  type?: MediaType;
708
+ /** Filter by format (For multiple formats: [MediaFormat.TV]) */
705
709
  format?: MediaFormat | MediaFormat[];
710
+ /** Filter by status of Media */
706
711
  status?: MediaStatus;
712
+ /** Filter by Season (Winter, Spring, Summer, Fall) */
707
713
  season?: MediaSeason;
714
+ /** Filter by Year */
708
715
  seasonYear?: number;
709
716
  /** Single genre filter (kept for backward compat) */
710
717
  genre?: string;
@@ -718,9 +725,23 @@ interface SearchMediaOptions {
718
725
  genresExclude?: string[];
719
726
  /** Exclude media with any of these tags */
720
727
  tagsExclude?: string[];
728
+ /** Include or Exclude explicit content (default: false) */
721
729
  isAdult?: boolean;
730
+ /** Sort order */
722
731
  sort?: MediaSort[];
732
+ /** Page number */
723
733
  page?: number;
734
+ /** Results per page (max 50) */
735
+ perPage?: number;
736
+ }
737
+ interface GeneralMediaQueryOptions {
738
+ /** Filter by Anime or Manga */
739
+ type?: MediaType;
740
+ /** Include or Exclude explicit content (default: false) */
741
+ isAdult?: boolean;
742
+ /** Page number */
743
+ page?: number;
744
+ /** Results per page (max 50) */
724
745
  perPage?: number;
725
746
  }
726
747
  interface GetAiringOptions {
@@ -728,12 +749,18 @@ interface GetAiringOptions {
728
749
  airingAtGreater?: number;
729
750
  /** Only show episodes that aired before this UNIX timestamp */
730
751
  airingAtLesser?: number;
752
+ /** Include or Exclude explicit content (default: false) */
753
+ isAdult?: boolean;
731
754
  /** Sort order (default: TIME_DESC) */
732
755
  sort?: AiringSort[];
756
+ /** Page number */
733
757
  page?: number;
758
+ /** Results per page (max 50) */
734
759
  perPage?: number;
735
760
  }
736
761
  interface GetRecentChaptersOptions {
762
+ /** Include or Exclude explicit content (default: false) */
763
+ isAdult?: boolean;
737
764
  /** Page number (default: 1) */
738
765
  page?: number;
739
766
  /** Results per page (default: 20, max 50) */
@@ -742,9 +769,13 @@ interface GetRecentChaptersOptions {
742
769
  interface GetPlanningOptions {
743
770
  /** Filter by ANIME or MANGA (returns both if omitted) */
744
771
  type?: MediaType;
772
+ /** Include or Exclude explicit content (default: false) */
773
+ isAdult?: boolean;
745
774
  /** Sort order (default: POPULARITY_DESC) */
746
775
  sort?: MediaSort[];
776
+ /** Page number */
747
777
  page?: number;
778
+ /** Results per page (max 50) */
748
779
  perPage?: number;
749
780
  }
750
781
  declare enum RecommendationSort {
@@ -769,7 +800,9 @@ interface GetRecommendationsOptions {
769
800
  mediaId: number;
770
801
  /** Sort order (default: RATING_DESC) */
771
802
  sort?: RecommendationSort[];
803
+ /** Page number */
772
804
  page?: number;
805
+ /** Results per page (max 50) */
773
806
  perPage?: number;
774
807
  }
775
808
  interface GetSeasonOptions {
@@ -779,9 +812,13 @@ interface GetSeasonOptions {
779
812
  seasonYear: number;
780
813
  /** Filter by ANIME or MANGA (defaults to ANIME) */
781
814
  type?: MediaType;
815
+ /** Allow or disallow explicit content (defaults to False) */
816
+ isAdult?: boolean;
782
817
  /** Sort order (default: POPULARITY_DESC) */
783
818
  sort?: MediaSort[];
819
+ /** Page number */
784
820
  page?: number;
821
+ /** Results per page (max 50) */
785
822
  perPage?: number;
786
823
  }
787
824
  /**
@@ -1169,11 +1206,11 @@ declare class AniListClient {
1169
1206
  */
1170
1207
  searchMedia(options?: SearchMediaOptions): Promise<PagedResult<Media>>;
1171
1208
  /** Get currently trending anime or manga. */
1172
- getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1209
+ getTrending(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1173
1210
  /** Get the most popular anime or manga. */
1174
- getPopular(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1211
+ getPopular(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1175
1212
  /** Get the highest-rated anime or manga. */
1176
- getTopRated(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1213
+ getTopRated(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1177
1214
  /** Get recently aired anime episodes. */
1178
1215
  getAiredEpisodes(options?: GetAiringOptions): Promise<PagedResult<AiringSchedule>>;
1179
1216
  /**
@@ -1311,7 +1348,7 @@ declare class AniListError extends Error {
1311
1348
  /**
1312
1349
  * Rate limiter with automatic retry for AniList API.
1313
1350
  *
1314
- * AniList allows 90 requests per minute.
1351
+ * AniList allows 30 requests per minute.
1315
1352
  * When a 429 (Too Many Requests) is received, the client
1316
1353
  * waits for the Retry-After header and retries automatically.
1317
1354
  */
package/dist/index.d.ts CHANGED
@@ -699,12 +699,19 @@ interface Media {
699
699
  siteUrl: string | null;
700
700
  }
701
701
  interface SearchMediaOptions {
702
+ /** Search Term */
702
703
  query?: string;
704
+ /** Filter by country code (e.g., "JP", "KR") */
703
705
  countryOfOrigin?: string;
706
+ /** Filter by Anime or Manga */
704
707
  type?: MediaType;
708
+ /** Filter by format (For multiple formats: [MediaFormat.TV]) */
705
709
  format?: MediaFormat | MediaFormat[];
710
+ /** Filter by status of Media */
706
711
  status?: MediaStatus;
712
+ /** Filter by Season (Winter, Spring, Summer, Fall) */
707
713
  season?: MediaSeason;
714
+ /** Filter by Year */
708
715
  seasonYear?: number;
709
716
  /** Single genre filter (kept for backward compat) */
710
717
  genre?: string;
@@ -718,9 +725,23 @@ interface SearchMediaOptions {
718
725
  genresExclude?: string[];
719
726
  /** Exclude media with any of these tags */
720
727
  tagsExclude?: string[];
728
+ /** Include or Exclude explicit content (default: false) */
721
729
  isAdult?: boolean;
730
+ /** Sort order */
722
731
  sort?: MediaSort[];
732
+ /** Page number */
723
733
  page?: number;
734
+ /** Results per page (max 50) */
735
+ perPage?: number;
736
+ }
737
+ interface GeneralMediaQueryOptions {
738
+ /** Filter by Anime or Manga */
739
+ type?: MediaType;
740
+ /** Include or Exclude explicit content (default: false) */
741
+ isAdult?: boolean;
742
+ /** Page number */
743
+ page?: number;
744
+ /** Results per page (max 50) */
724
745
  perPage?: number;
725
746
  }
726
747
  interface GetAiringOptions {
@@ -728,12 +749,18 @@ interface GetAiringOptions {
728
749
  airingAtGreater?: number;
729
750
  /** Only show episodes that aired before this UNIX timestamp */
730
751
  airingAtLesser?: number;
752
+ /** Include or Exclude explicit content (default: false) */
753
+ isAdult?: boolean;
731
754
  /** Sort order (default: TIME_DESC) */
732
755
  sort?: AiringSort[];
756
+ /** Page number */
733
757
  page?: number;
758
+ /** Results per page (max 50) */
734
759
  perPage?: number;
735
760
  }
736
761
  interface GetRecentChaptersOptions {
762
+ /** Include or Exclude explicit content (default: false) */
763
+ isAdult?: boolean;
737
764
  /** Page number (default: 1) */
738
765
  page?: number;
739
766
  /** Results per page (default: 20, max 50) */
@@ -742,9 +769,13 @@ interface GetRecentChaptersOptions {
742
769
  interface GetPlanningOptions {
743
770
  /** Filter by ANIME or MANGA (returns both if omitted) */
744
771
  type?: MediaType;
772
+ /** Include or Exclude explicit content (default: false) */
773
+ isAdult?: boolean;
745
774
  /** Sort order (default: POPULARITY_DESC) */
746
775
  sort?: MediaSort[];
776
+ /** Page number */
747
777
  page?: number;
778
+ /** Results per page (max 50) */
748
779
  perPage?: number;
749
780
  }
750
781
  declare enum RecommendationSort {
@@ -769,7 +800,9 @@ interface GetRecommendationsOptions {
769
800
  mediaId: number;
770
801
  /** Sort order (default: RATING_DESC) */
771
802
  sort?: RecommendationSort[];
803
+ /** Page number */
772
804
  page?: number;
805
+ /** Results per page (max 50) */
773
806
  perPage?: number;
774
807
  }
775
808
  interface GetSeasonOptions {
@@ -779,9 +812,13 @@ interface GetSeasonOptions {
779
812
  seasonYear: number;
780
813
  /** Filter by ANIME or MANGA (defaults to ANIME) */
781
814
  type?: MediaType;
815
+ /** Allow or disallow explicit content (defaults to False) */
816
+ isAdult?: boolean;
782
817
  /** Sort order (default: POPULARITY_DESC) */
783
818
  sort?: MediaSort[];
819
+ /** Page number */
784
820
  page?: number;
821
+ /** Results per page (max 50) */
785
822
  perPage?: number;
786
823
  }
787
824
  /**
@@ -1169,11 +1206,11 @@ declare class AniListClient {
1169
1206
  */
1170
1207
  searchMedia(options?: SearchMediaOptions): Promise<PagedResult<Media>>;
1171
1208
  /** Get currently trending anime or manga. */
1172
- getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1209
+ getTrending(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1173
1210
  /** Get the most popular anime or manga. */
1174
- getPopular(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1211
+ getPopular(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1175
1212
  /** Get the highest-rated anime or manga. */
1176
- getTopRated(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
1213
+ getTopRated(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
1177
1214
  /** Get recently aired anime episodes. */
1178
1215
  getAiredEpisodes(options?: GetAiringOptions): Promise<PagedResult<AiringSchedule>>;
1179
1216
  /**
@@ -1311,7 +1348,7 @@ declare class AniListError extends Error {
1311
1348
  /**
1312
1349
  * Rate limiter with automatic retry for AniList API.
1313
1350
  *
1314
- * AniList allows 90 requests per minute.
1351
+ * AniList allows 30 requests per minute.
1315
1352
  * When a 429 (Too Many Requests) is received, the client
1316
1353
  * waits for the Retry-After header and retries automatically.
1317
1354
  */
package/dist/index.js CHANGED
@@ -436,7 +436,17 @@ var RELATIONS_FIELDS = `
436
436
  type
437
437
  format
438
438
  status
439
- coverImage { large medium }
439
+ startDate { year month day }
440
+ endDate { year month day }
441
+ season
442
+ seasonYear
443
+ episodes
444
+ chapters
445
+ volumes
446
+ coverImage { extraLarge large medium color }
447
+ genres
448
+ averageScore
449
+ studios { nodes { id name isAnimationStudio siteUrl } }
440
450
  siteUrl
441
451
  }
442
452
  }
@@ -756,16 +766,16 @@ query (
756
766
  }
757
767
  }`;
758
768
  var QUERY_TRENDING = `
759
- query ($type: MediaType, $page: Int, $perPage: Int) {
769
+ query ($type: MediaType, $isAdult: Boolean, $page: Int, $perPage: Int) {
760
770
  Page(page: $page, perPage: $perPage) {
761
771
  pageInfo { total perPage currentPage lastPage hasNextPage }
762
- media(type: $type, sort: TRENDING_DESC) {
772
+ media(type: $type, isAdult: $isAdult, sort: TRENDING_DESC) {
763
773
  ${MEDIA_FIELDS_BASE}
764
774
  }
765
775
  }
766
776
  }`;
767
777
  var QUERY_AIRING_SCHEDULE = `
768
- query ($airingAt_greater: Int, $airingAt_lesser: Int, $sort: [AiringSort], $page: Int, $perPage: Int) {
778
+ query ($airingAt_greater: Int, $airingAt_lesser: Int, $isAdult: Boolean, $sort: [AiringSort], $page: Int, $perPage: Int) {
769
779
  Page(page: $page, perPage: $perPage) {
770
780
  pageInfo { total perPage currentPage lastPage hasNextPage }
771
781
  airingSchedules(airingAt_greater: $airingAt_greater, airingAt_lesser: $airingAt_lesser, sort: $sort) {
@@ -774,35 +784,49 @@ query ($airingAt_greater: Int, $airingAt_lesser: Int, $sort: [AiringSort], $page
774
784
  timeUntilAiring
775
785
  episode
776
786
  mediaId
777
- media {
787
+ media(isAdult: $isAdult) {
778
788
  ${MEDIA_FIELDS_BASE}
779
789
  }
780
790
  }
781
791
  }
782
792
  }`;
783
793
  var QUERY_RECENT_CHAPTERS = `
784
- query ($page: Int, $perPage: Int) {
794
+ query ($isAdult: Boolean $page: Int, $perPage: Int) {
785
795
  Page(page: $page, perPage: $perPage) {
786
796
  pageInfo { total perPage currentPage lastPage hasNextPage }
787
- media(type: MANGA, status: RELEASING, sort: UPDATED_AT_DESC) {
797
+ media(type: MANGA, isAdult: $isAdult status: RELEASING, sort: UPDATED_AT_DESC) {
788
798
  ${MEDIA_FIELDS_BASE}
789
799
  }
790
800
  }
791
801
  }`;
792
802
  var QUERY_PLANNING = `
793
- query ($type: MediaType, $sort: [MediaSort], $page: Int, $perPage: Int) {
803
+ query ($type: MediaType, $isAdult: Boolean, $sort: [MediaSort], $page: Int, $perPage: Int) {
794
804
  Page(page: $page, perPage: $perPage) {
795
805
  pageInfo { total perPage currentPage lastPage hasNextPage }
796
- media(type: $type, status: NOT_YET_RELEASED, sort: $sort) {
806
+ media(type: $type, isAdult: $isAdult, status: NOT_YET_RELEASED, sort: $sort) {
797
807
  ${MEDIA_FIELDS_BASE}
798
808
  }
799
809
  }
800
810
  }`;
801
811
  var QUERY_MEDIA_BY_SEASON = `
802
- query ($season: MediaSeason!, $seasonYear: Int!, $type: MediaType, $sort: [MediaSort], $page: Int, $perPage: Int) {
812
+ query (
813
+ $season: MediaSeason!,
814
+ $seasonYear: Int!,
815
+ $type: MediaType,
816
+ $isAdult: Boolean,
817
+ $sort: [MediaSort],
818
+ $page: Int,
819
+ $perPage: Int
820
+ ) {
803
821
  Page(page: $page, perPage: $perPage) {
804
822
  pageInfo { total perPage currentPage lastPage hasNextPage }
805
- media(season: $season, seasonYear: $seasonYear, type: $type, sort: $sort) {
823
+ media(
824
+ season: $season,
825
+ seasonYear: $seasonYear,
826
+ type: $type,
827
+ isAdult: $isAdult,
828
+ sort: $sort
829
+ ) {
806
830
  ${MEDIA_FIELDS_BASE}
807
831
  }
808
832
  }
@@ -1201,7 +1225,7 @@ var RateLimiter = class {
1201
1225
  /** @internal — active sleep timers for cleanup */
1202
1226
  activeTimers = /* @__PURE__ */ new Set();
1203
1227
  constructor(options = {}) {
1204
- this.maxRequests = options.maxRequests ?? 85;
1228
+ this.maxRequests = options.maxRequests ?? 25;
1205
1229
  this.windowMs = options.windowMs ?? 6e4;
1206
1230
  this.maxRetries = options.maxRetries ?? 3;
1207
1231
  this.retryDelayMs = options.retryDelayMs ?? 2e3;
@@ -1632,14 +1656,17 @@ async function searchMedia(client, options = {}) {
1632
1656
  "media"
1633
1657
  );
1634
1658
  }
1635
- async function getTrending(client, type = "ANIME" /* ANIME */, page = 1, perPage = 20) {
1636
- return client.pagedRequest(QUERY_TRENDING, { type, page, perPage: clampPerPage(perPage) }, "media");
1659
+ async function getTrending(client, options) {
1660
+ const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1661
+ return client.pagedRequest(QUERY_TRENDING, { type, isAdult, page, perPage: clampPerPage(perPage) }, "media");
1637
1662
  }
1638
- async function getPopular(client, type = "ANIME" /* ANIME */, page = 1, perPage = 20) {
1639
- return searchMedia(client, { type, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
1663
+ async function getPopular(client, options) {
1664
+ const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1665
+ return searchMedia(client, { type, isAdult, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
1640
1666
  }
1641
- async function getTopRated(client, type = "ANIME" /* ANIME */, page = 1, perPage = 20) {
1642
- return searchMedia(client, { type, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
1667
+ async function getTopRated(client, options) {
1668
+ const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1669
+ return searchMedia(client, { type, isAdult, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
1643
1670
  }
1644
1671
  async function getAiredEpisodes(client, options = {}) {
1645
1672
  const now = Math.floor(Date.now() / 1e3);
@@ -1648,6 +1675,7 @@ async function getAiredEpisodes(client, options = {}) {
1648
1675
  {
1649
1676
  airingAt_greater: options.airingAtGreater ?? now - 24 * 3600,
1650
1677
  airingAt_lesser: options.airingAtLesser ?? now,
1678
+ isAdult: options.isAdult ?? false,
1651
1679
  sort: options.sort,
1652
1680
  page: options.page ?? 1,
1653
1681
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1659,6 +1687,7 @@ async function getRecentlyUpdatedManga(client, options = {}) {
1659
1687
  return client.pagedRequest(
1660
1688
  QUERY_RECENT_CHAPTERS,
1661
1689
  {
1690
+ isAdult: options.isAdult ?? false,
1662
1691
  page: options.page ?? 1,
1663
1692
  perPage: clampPerPage(options.perPage ?? 20)
1664
1693
  },
@@ -1670,6 +1699,7 @@ async function getPlanning(client, options = {}) {
1670
1699
  QUERY_PLANNING,
1671
1700
  {
1672
1701
  type: options.type,
1702
+ isAdult: options.isAdult ?? false,
1673
1703
  sort: options.sort ?? ["POPULARITY_DESC" /* POPULARITY_DESC */],
1674
1704
  page: options.page ?? 1,
1675
1705
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1697,6 +1727,7 @@ async function getMediaBySeason(client, options) {
1697
1727
  season: options.season,
1698
1728
  seasonYear: options.seasonYear,
1699
1729
  type: options.type,
1730
+ isAdult: options.isAdult ?? false,
1700
1731
  sort: options.sort,
1701
1732
  page: options.page ?? 1,
1702
1733
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1704,7 +1735,7 @@ async function getMediaBySeason(client, options) {
1704
1735
  "media"
1705
1736
  );
1706
1737
  }
1707
- async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date()) {
1738
+ async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date(), isAdult = false) {
1708
1739
  const schedule = {
1709
1740
  Monday: [],
1710
1741
  Tuesday: [],
@@ -1726,6 +1757,7 @@ async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date()) {
1726
1757
  (page) => getAiredEpisodes(client, {
1727
1758
  airingAtGreater: startTimestamp,
1728
1759
  airingAtLesser: endTimestamp,
1760
+ isAdult,
1729
1761
  page,
1730
1762
  perPage: 50
1731
1763
  }),
@@ -1871,7 +1903,7 @@ function mapFavorites(fav) {
1871
1903
 
1872
1904
  // src/client/index.ts
1873
1905
  var DEFAULT_API_URL = "https://graphql.anilist.co";
1874
- var LIB_VERSION = "1.9.0" ;
1906
+ var LIB_VERSION = "2.0.0" ;
1875
1907
  var AniListClient = class {
1876
1908
  apiUrl;
1877
1909
  headers;
@@ -2024,16 +2056,16 @@ var AniListClient = class {
2024
2056
  return searchMedia(this, options);
2025
2057
  }
2026
2058
  /** Get currently trending anime or manga. */
2027
- async getTrending(type, page, perPage) {
2028
- return getTrending(this, type, page, perPage);
2059
+ async getTrending(options = {}) {
2060
+ return getTrending(this, options);
2029
2061
  }
2030
2062
  /** Get the most popular anime or manga. */
2031
- async getPopular(type, page, perPage) {
2032
- return getPopular(this, type, page, perPage);
2063
+ async getPopular(options = {}) {
2064
+ return getPopular(this, options);
2033
2065
  }
2034
2066
  /** Get the highest-rated anime or manga. */
2035
- async getTopRated(type, page, perPage) {
2036
- return getTopRated(this, type, page, perPage);
2067
+ async getTopRated(options = {}) {
2068
+ return getTopRated(this, options);
2037
2069
  }
2038
2070
  /** Get recently aired anime episodes. */
2039
2071
  async getAiredEpisodes(options = {}) {