ani-client 2.0.2 → 2.1.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/dist/index.mjs CHANGED
@@ -444,6 +444,7 @@ var RELATIONS_FIELDS = `
444
444
  coverImage { extraLarge large medium color }
445
445
  genres
446
446
  averageScore
447
+ meanScore
447
448
  studios { nodes { id name isAnimationStudio siteUrl } }
448
449
  siteUrl
449
450
  nextAiringEpisode {
@@ -457,6 +458,30 @@ var RELATIONS_FIELDS = `
457
458
  }
458
459
  }
459
460
  `;
461
+ var MEDIA_RECOMMENDATION_FIELDS = `
462
+ id
463
+ rating
464
+ mediaRecommendation {
465
+ id
466
+ title { romaji english native userPreferred }
467
+ type
468
+ format
469
+ coverImage { large medium }
470
+ averageScore
471
+ meanScore
472
+ episodes
473
+ chapters
474
+ volumes
475
+ nextAiringEpisode
476
+ season
477
+ seasonYear
478
+ startDate
479
+ endDate
480
+ studios
481
+ genres
482
+ siteUrl
483
+ }
484
+ `;
460
485
  var MEDIA_FIELDS = `
461
486
  ${MEDIA_FIELDS_BASE}
462
487
  ${RELATIONS_FIELDS}
@@ -742,6 +767,7 @@ query (
742
767
  $genre_not_in: [String],
743
768
  $tag_not_in: [String],
744
769
  $isAdult: Boolean,
770
+ $idNotIn: [Int],
745
771
  $sort: [MediaSort],
746
772
  $page: Int,
747
773
  $perPage: Int
@@ -764,6 +790,7 @@ query (
764
790
  genre_not_in: $genre_not_in,
765
791
  tag_not_in: $tag_not_in,
766
792
  isAdult: $isAdult,
793
+ id_not_in: $idNotIn,
767
794
  sort: $sort
768
795
  ) {
769
796
  ${MEDIA_FIELDS_BASE}
@@ -771,19 +798,42 @@ query (
771
798
  }
772
799
  }`;
773
800
  var QUERY_TRENDING = `
774
- query ($type: MediaType, $isAdult: Boolean, $page: Int, $perPage: Int) {
801
+ query (
802
+ $type: MediaType,
803
+ $isAdult: Boolean,
804
+ $idNotIn: [Int],
805
+ $page: Int,
806
+ $perPage: Int
807
+ ) {
775
808
  Page(page: $page, perPage: $perPage) {
776
809
  pageInfo { total perPage currentPage lastPage hasNextPage }
777
- media(type: $type, isAdult: $isAdult, sort: TRENDING_DESC) {
810
+ media(
811
+ type: $type,
812
+ isAdult: $isAdult,
813
+ id_not_in: $idNotIn,
814
+ sort: TRENDING_DESC
815
+ ) {
778
816
  ${MEDIA_FIELDS_BASE}
779
817
  }
780
818
  }
781
819
  }`;
782
820
  var QUERY_AIRING_SCHEDULE = `
783
- query ($airingAt_greater: Int, $airingAt_lesser: Int, $isAdult: Boolean, $sort: [AiringSort], $page: Int, $perPage: Int) {
821
+ query (
822
+ $airingAt_greater: Int,
823
+ $airingAt_lesser: Int,
824
+ $sort: [AiringSort],
825
+ $idNotIn: [Int],
826
+ $page: Int,
827
+ $perPage: Int
828
+ ) {
784
829
  Page(page: $page, perPage: $perPage) {
785
830
  pageInfo { total perPage currentPage lastPage hasNextPage }
786
- airingSchedules(airingAt_greater: $airingAt_greater, airingAt_lesser: $airingAt_lesser, sort: $sort) {
831
+ airingSchedules(
832
+ airingAt_greater: $airingAt_greater,
833
+ airingAt_lesser: $airingAt_lesser,
834
+ id_not_in: $idNotIn,
835
+ sort: $sort
836
+ ) {
787
837
  id
788
838
  airingAt
789
839
  timeUntilAiring
@@ -796,19 +846,43 @@ query ($airingAt_greater: Int, $airingAt_lesser: Int, $isAdult: Boolean, $sort:
796
846
  }
797
847
  }`;
798
848
  var QUERY_RECENT_CHAPTERS = `
799
- query ($isAdult: Boolean $page: Int, $perPage: Int) {
849
+ query (
850
+ $isAdult: Boolean,
851
+ $idNotIn: [Int],
852
+ $page: Int,
853
+ $perPage: Int
854
+ ) {
800
855
  Page(page: $page, perPage: $perPage) {
801
856
  pageInfo { total perPage currentPage lastPage hasNextPage }
802
- media(type: MANGA, isAdult: $isAdult status: RELEASING, sort: UPDATED_AT_DESC) {
857
+ media(
858
+ type: MANGA,
859
+ isAdult: $isAdult,
860
+ id_not_in: $idNotIn,
861
+ status: RELEASING,
862
+ sort: UPDATED_AT_DESC
863
+ ) {
803
864
  ${MEDIA_FIELDS_BASE}
804
865
  }
805
866
  }
806
867
  }`;
807
868
  var QUERY_PLANNING = `
808
- query ($type: MediaType, $isAdult: Boolean, $sort: [MediaSort], $page: Int, $perPage: Int) {
869
+ query (
870
+ $type: MediaType,
871
+ $isAdult: Boolean,
872
+ $idNotIn: [Int],
873
+ $sort: [MediaSort],
874
+ $page: Int,
875
+ $perPage: Int
876
+ ) {
809
877
  Page(page: $page, perPage: $perPage) {
810
878
  pageInfo { total perPage currentPage lastPage hasNextPage }
811
- media(type: $type, isAdult: $isAdult, status: NOT_YET_RELEASED, sort: $sort) {
879
+ media(
880
+ type: $type,
881
+ isAdult: $isAdult,
882
+ id_not_in: $idNotIn,
883
+ status: NOT_YET_RELEASED,
884
+ sort: $sort
885
+ ) {
812
886
  ${MEDIA_FIELDS_BASE}
813
887
  }
814
888
  }
@@ -819,6 +893,7 @@ query (
819
893
  $seasonYear: Int!,
820
894
  $type: MediaType,
821
895
  $isAdult: Boolean,
896
+ $idNotIn: [Int],
822
897
  $sort: [MediaSort],
823
898
  $page: Int,
824
899
  $perPage: Int
@@ -830,6 +905,7 @@ query (
830
905
  seasonYear: $seasonYear,
831
906
  type: $type,
832
907
  isAdult: $isAdult,
908
+ id_not_in: $idNotIn,
833
909
  sort: $sort
834
910
  ) {
835
911
  ${MEDIA_FIELDS_BASE}
@@ -848,25 +924,7 @@ query ($mediaId: Int!, $page: Int, $perPage: Int, $sort: [RecommendationSort]) {
848
924
  recommendations(page: $page, perPage: $perPage, sort: $sort) {
849
925
  pageInfo { total perPage currentPage lastPage hasNextPage }
850
926
  nodes {
851
- id
852
- rating
853
- userRating
854
- mediaRecommendation {
855
- id
856
- idMal
857
- title { romaji english native userPreferred }
858
- type
859
- format
860
- status
861
- coverImage { extraLarge large medium color }
862
- bannerImage
863
- genres
864
- averageScore
865
- meanScore
866
- popularity
867
- favourites
868
- siteUrl
869
- }
927
+ ${MEDIA_RECOMMENDATION_FIELDS}
870
928
  user {
871
929
  id
872
930
  name
@@ -923,17 +981,7 @@ function buildMediaByIdQuery(include) {
923
981
  extra.push(`
924
982
  recommendations(perPage: ${perPage}, sort: [RATING_DESC]) {
925
983
  nodes {
926
- id
927
- rating
928
- mediaRecommendation {
929
- id
930
- title { romaji english native userPreferred }
931
- type
932
- format
933
- coverImage { large medium }
934
- averageScore
935
- siteUrl
936
- }
984
+ ${MEDIA_RECOMMENDATION_FIELDS}
937
985
  }
938
986
  }`);
939
987
  }
@@ -972,6 +1020,44 @@ query ($id: Int!) {
972
1020
  }
973
1021
  }`;
974
1022
  }
1023
+ function buildMediaCharactersQuery(options = {}) {
1024
+ const sortClause = options.sort === false ? "" : ", sort: [ROLE, RELEVANCE, ID]";
1025
+ const voiceActorBlock = options.voiceActors ? `
1026
+ voiceActors {
1027
+ ${VOICE_ACTOR_FIELDS_COMPACT}
1028
+ }` : "";
1029
+ return `
1030
+ query ($mediaId: Int!, $page: Int, $perPage: Int) {
1031
+ Media(id: $mediaId) {
1032
+ characters(page: $page, perPage: $perPage${sortClause}) {
1033
+ pageInfo { total perPage currentPage lastPage hasNextPage }
1034
+ edges {
1035
+ role
1036
+ node {
1037
+ ${CHARACTER_FIELDS_COMPACT}
1038
+ }${voiceActorBlock}
1039
+ }
1040
+ }
1041
+ }
1042
+ }`;
1043
+ }
1044
+ function buildMediaStaffQuery(options = {}) {
1045
+ const sortClause = options.sort === false ? "" : ", sort: [RELEVANCE, ID]";
1046
+ return `
1047
+ query ($mediaId: Int!, $page: Int, $perPage: Int) {
1048
+ Media(id: $mediaId) {
1049
+ staff(page: $page, perPage: $perPage${sortClause}) {
1050
+ pageInfo { total perPage currentPage lastPage hasNextPage }
1051
+ edges {
1052
+ role
1053
+ node {
1054
+ ${STAFF_FIELDS}
1055
+ }
1056
+ }
1057
+ }
1058
+ }
1059
+ }`;
1060
+ }
975
1061
  function buildBatchQuery(ids, typeName, fields, prefix) {
976
1062
  const aliases = ids.map((id, i) => `${prefix}${i}: ${typeName}(id: ${id}) { ${fields} }`).join("\n ");
977
1063
  return `query {
@@ -1030,6 +1116,75 @@ query {
1030
1116
  }
1031
1117
  }`;
1032
1118
 
1119
+ // src/queries/review.ts
1120
+ var QUERY_REVIEWS = `
1121
+ query ($page: Int, $perPage: Int, $sort: [ReviewSort], $mediaId: Int, $userId: Int) {
1122
+ Page(page: $page, perPage: $perPage) {
1123
+ pageInfo {
1124
+ total
1125
+ currentPage
1126
+ lastPage
1127
+ hasNextPage
1128
+ perPage
1129
+ }
1130
+ reviews(sort: $sort, mediaId: $mediaId, userId: $userId) {
1131
+ id
1132
+ userId
1133
+ mediaId
1134
+ mediaType
1135
+ summary
1136
+ body
1137
+ rating
1138
+ ratingAmount
1139
+ userRating
1140
+ score
1141
+ private
1142
+ siteUrl
1143
+ createdAt
1144
+ updatedAt
1145
+ user {
1146
+ id
1147
+ name
1148
+ avatar { large medium }
1149
+ siteUrl
1150
+ }
1151
+ media {
1152
+ ${MEDIA_FIELDS_LIGHT}
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ `;
1158
+ var QUERY_REVIEW_BY_ID = `
1159
+ query ($id: Int) {
1160
+ Review(id: $id) {
1161
+ id
1162
+ userId
1163
+ mediaId
1164
+ mediaType
1165
+ summary
1166
+ body
1167
+ rating
1168
+ ratingAmount
1169
+ userRating
1170
+ score
1171
+ private
1172
+ siteUrl
1173
+ createdAt
1174
+ updatedAt
1175
+ user {
1176
+ id
1177
+ name
1178
+ avatar { large medium }
1179
+ siteUrl
1180
+ }
1181
+ media {
1182
+ ${MEDIA_FIELDS_BASE}
1183
+ }
1184
+ }
1185
+ }
1186
+ `;
1187
+
1033
1188
  // src/queries/staff.ts
1034
1189
  var QUERY_STAFF_BY_ID = `
1035
1190
  query ($id: Int!) {
@@ -1555,6 +1710,21 @@ var RecommendationSort = /* @__PURE__ */ ((RecommendationSort2) => {
1555
1710
  return RecommendationSort2;
1556
1711
  })(RecommendationSort || {});
1557
1712
 
1713
+ // src/types/review.ts
1714
+ var ReviewSort = /* @__PURE__ */ ((ReviewSort2) => {
1715
+ ReviewSort2["ID"] = "ID";
1716
+ ReviewSort2["ID_DESC"] = "ID_DESC";
1717
+ ReviewSort2["SCORE"] = "SCORE";
1718
+ ReviewSort2["SCORE_DESC"] = "SCORE_DESC";
1719
+ ReviewSort2["RATING"] = "RATING";
1720
+ ReviewSort2["RATING_DESC"] = "RATING_DESC";
1721
+ ReviewSort2["CREATED_AT"] = "CREATED_AT";
1722
+ ReviewSort2["CREATED_AT_DESC"] = "CREATED_AT_DESC";
1723
+ ReviewSort2["UPDATED_AT"] = "UPDATED_AT";
1724
+ ReviewSort2["UPDATED_AT_DESC"] = "UPDATED_AT_DESC";
1725
+ return ReviewSort2;
1726
+ })(ReviewSort || {});
1727
+
1558
1728
  // src/types/staff.ts
1559
1729
  var StaffSort = /* @__PURE__ */ ((StaffSort2) => {
1560
1730
  StaffSort2["ID"] = "ID";
@@ -1624,6 +1794,25 @@ async function getMedia(client, id, include) {
1624
1794
  const data = await client.request(query, { id });
1625
1795
  return data.Media;
1626
1796
  }
1797
+ async function getMediaCharacters(client, mediaId, options = {}) {
1798
+ validateId(mediaId, "mediaId");
1799
+ const query = buildMediaCharactersQuery(options);
1800
+ const data = await client.request(
1801
+ query,
1802
+ { mediaId, page: options.page ?? 1, perPage: clampPerPage(options.perPage ?? 25) }
1803
+ );
1804
+ return { pageInfo: data.Media.characters.pageInfo, results: data.Media.characters.edges };
1805
+ }
1806
+ async function getMediaStaff(client, mediaId, options = {}) {
1807
+ validateId(mediaId, "mediaId");
1808
+ const query = buildMediaStaffQuery(options);
1809
+ const data = await client.request(query, {
1810
+ mediaId,
1811
+ page: options.page ?? 1,
1812
+ perPage: clampPerPage(options.perPage ?? 25)
1813
+ });
1814
+ return { pageInfo: data.Media.staff.pageInfo, results: data.Media.staff.edges };
1815
+ }
1627
1816
  async function getMediaByMalId(client, malId, type) {
1628
1817
  validateId(malId, "malId");
1629
1818
  const data = await client.request(QUERY_MEDIA_BY_MAL_ID, {
@@ -1662,16 +1851,20 @@ async function searchMedia(client, options = {}) {
1662
1851
  );
1663
1852
  }
1664
1853
  async function getTrending(client, options) {
1665
- const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1666
- return client.pagedRequest(QUERY_TRENDING, { type, isAdult, page, perPage: clampPerPage(perPage) }, "media");
1854
+ const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
1855
+ return client.pagedRequest(
1856
+ QUERY_TRENDING,
1857
+ { type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) },
1858
+ "media"
1859
+ );
1667
1860
  }
1668
1861
  async function getPopular(client, options) {
1669
- const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1670
- return searchMedia(client, { type, isAdult, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
1862
+ const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
1863
+ return searchMedia(client, { type, isAdult, idNotIn, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
1671
1864
  }
1672
1865
  async function getTopRated(client, options) {
1673
- const { type = "ANIME" /* ANIME */, isAdult = false, page = 1, perPage = 20 } = options;
1674
- return searchMedia(client, { type, isAdult, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
1866
+ const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
1867
+ return searchMedia(client, { type, isAdult, idNotIn, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
1675
1868
  }
1676
1869
  async function getAiredEpisodes(client, options = {}) {
1677
1870
  const now = Math.floor(Date.now() / 1e3);
@@ -1680,7 +1873,7 @@ async function getAiredEpisodes(client, options = {}) {
1680
1873
  {
1681
1874
  airingAt_greater: options.airingAtGreater ?? now - 24 * 3600,
1682
1875
  airingAt_lesser: options.airingAtLesser ?? now,
1683
- isAdult: options.isAdult ?? false,
1876
+ idNotIn: options.idNotIn ?? [],
1684
1877
  sort: options.sort,
1685
1878
  page: options.page ?? 1,
1686
1879
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1693,6 +1886,7 @@ async function getRecentlyUpdatedManga(client, options = {}) {
1693
1886
  QUERY_RECENT_CHAPTERS,
1694
1887
  {
1695
1888
  isAdult: options.isAdult ?? false,
1889
+ idNotIn: options.idNotIn ?? [],
1696
1890
  page: options.page ?? 1,
1697
1891
  perPage: clampPerPage(options.perPage ?? 20)
1698
1892
  },
@@ -1705,6 +1899,7 @@ async function getPlanning(client, options = {}) {
1705
1899
  {
1706
1900
  type: options.type,
1707
1901
  isAdult: options.isAdult ?? false,
1902
+ idNotIn: options.idNotIn ?? [],
1708
1903
  sort: options.sort ?? ["POPULARITY_DESC" /* POPULARITY_DESC */],
1709
1904
  page: options.page ?? 1,
1710
1905
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1733,6 +1928,7 @@ async function getMediaBySeason(client, options) {
1733
1928
  seasonYear: options.seasonYear,
1734
1929
  type: options.type,
1735
1930
  isAdult: options.isAdult ?? false,
1931
+ idNotIn: options.idNotIn ?? [],
1736
1932
  sort: options.sort,
1737
1933
  page: options.page ?? 1,
1738
1934
  perPage: clampPerPage(options.perPage ?? 20)
@@ -1740,7 +1936,7 @@ async function getMediaBySeason(client, options) {
1740
1936
  "media"
1741
1937
  );
1742
1938
  }
1743
- async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date(), isAdult = false) {
1939
+ async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date(), idNotIn) {
1744
1940
  const schedule = {
1745
1941
  Monday: [],
1746
1942
  Tuesday: [],
@@ -1762,7 +1958,7 @@ async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date(), isAd
1762
1958
  (page) => getAiredEpisodes(client, {
1763
1959
  airingAtGreater: startTimestamp,
1764
1960
  airingAtLesser: endTimestamp,
1765
- isAdult,
1961
+ idNotIn,
1766
1962
  page,
1767
1963
  perPage: 50
1768
1964
  }),
@@ -1777,6 +1973,17 @@ async function getWeeklySchedule(client, date = /* @__PURE__ */ new Date(), isAd
1777
1973
  return schedule;
1778
1974
  }
1779
1975
 
1976
+ // src/client/review.ts
1977
+ async function getReview(client, id) {
1978
+ validateId(id, "reviewId");
1979
+ const data = await client.request(QUERY_REVIEW_BY_ID, { id });
1980
+ return data.Review;
1981
+ }
1982
+ async function searchReviews(client, options = {}) {
1983
+ const { mediaId, userId, sort, page = 1, perPage = 20 } = options;
1984
+ return client.pagedRequest(QUERY_REVIEWS, { mediaId, userId, sort, page, perPage }, "reviews");
1985
+ }
1986
+
1780
1987
  // src/client/staff.ts
1781
1988
  async function getStaff(client, id, include) {
1782
1989
  validateId(id, "staffId");
@@ -1908,7 +2115,7 @@ function mapFavorites(fav) {
1908
2115
 
1909
2116
  // src/client/index.ts
1910
2117
  var DEFAULT_API_URL = "https://graphql.anilist.co";
1911
- var LIB_VERSION = "2.0.2" ;
2118
+ var LIB_VERSION = "2.1.0" ;
1912
2119
  var AniListClient = class {
1913
2120
  apiUrl;
1914
2121
  headers;
@@ -2051,6 +2258,12 @@ var AniListClient = class {
2051
2258
  async getMedia(id, include) {
2052
2259
  return getMedia(this, id, include);
2053
2260
  }
2261
+ async getMediaCharacters(mediaId, options = {}) {
2262
+ return getMediaCharacters(this, mediaId, options);
2263
+ }
2264
+ async getMediaStaff(mediaId, options = {}) {
2265
+ return getMediaStaff(this, mediaId, options);
2266
+ }
2054
2267
  /**
2055
2268
  * Search for anime or manga.
2056
2269
  *
@@ -2085,7 +2298,7 @@ var AniListClient = class {
2085
2298
  return getRecentlyUpdatedManga(this, options);
2086
2299
  }
2087
2300
  /**
2088
- * @deprecated Use `getRecentlyUpdatedManga` instead. This alias will be removed in v2.
2301
+ * @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
2089
2302
  */
2090
2303
  async getAiredChapters(options = {}) {
2091
2304
  return this.getRecentlyUpdatedManga(options);
@@ -2166,6 +2379,23 @@ var AniListClient = class {
2166
2379
  async getUserFavorites(idOrName, options) {
2167
2380
  return getUserFavorites(this, idOrName, options);
2168
2381
  }
2382
+ /**
2383
+ * Fetch a review by its AniList ID.
2384
+ *
2385
+ * @param id - The AniList review ID
2386
+ */
2387
+ async getReview(id) {
2388
+ return getReview(this, id);
2389
+ }
2390
+ /**
2391
+ * Search for reviews with optional filters.
2392
+ *
2393
+ * @param options - Search and filter options
2394
+ * @returns Paginated results with matching reviews
2395
+ */
2396
+ async searchReviews(options = {}) {
2397
+ return searchReviews(this, options);
2398
+ }
2169
2399
  /**
2170
2400
  * Fetch a studio by its AniList ID.
2171
2401
  * Pass `include` to customise the number of media returned.
@@ -2308,6 +2538,6 @@ var AniListClient = class {
2308
2538
  }
2309
2539
  };
2310
2540
 
2311
- export { AiringSort, AniListClient, AniListError, CharacterRole, CharacterSort, MediaFormat, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaSource, MediaStatus, MediaType, MemoryCache, RateLimiter, RecommendationSort, RedisCache, StaffSort, StudioSort, ThreadSort, UserSort, parseAniListMarkdown };
2541
+ export { AiringSort, AniListClient, AniListError, CharacterRole, CharacterSort, MediaFormat, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaSource, MediaStatus, MediaType, MemoryCache, RateLimiter, RecommendationSort, RedisCache, ReviewSort, StaffSort, StudioSort, ThreadSort, UserSort, parseAniListMarkdown };
2312
2542
  //# sourceMappingURL=index.mjs.map
2313
2543
  //# sourceMappingURL=index.mjs.map