ani-client 2.0.2 → 2.0.3

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
@@ -22,6 +22,7 @@
22
22
  - **Rate-limit protection** with exponential backoff, retries, and custom strategies
23
23
  - **Request deduplication** — concurrent identical queries share a single in-flight request
24
24
  - **Batch queries** — fetch up to 50 media/characters/staff in one API call
25
+ - **Paginated media relationships** — `getMediaCharacters()` and `getMediaStaff()` support paged results for large casts and staff listings
25
26
  - **Auto-pagination** — async iterator that yields items across pages
26
27
  - **AbortSignal support** — cancel globally or per-request with `withSignal()`
27
28
  - **Injectable logger** — plug in `console`, pino, winston, or any compatible logger
@@ -58,6 +59,10 @@ const results = await client.searchMedia({
58
59
 
59
60
  // Cross-platform lookup by MyAnimeList ID
60
61
  const fma = await client.getMediaByMalId(5114);
62
+
63
+ // Paginated media relationships
64
+ const characters = await client.getMediaCharacters(1, { page: 1, perPage: 25, voiceActors: true });
65
+ const staff = await client.getMediaStaff(1, { page: 1, perPage: 25 });
61
66
  ```
62
67
 
63
68
  ## Features at a glance
@@ -134,6 +139,8 @@ for await (const anime of client.paginate(
134
139
  const user = await client.getUser("AniList");
135
140
  const favs = await client.getUserFavorites("AniList", { perPage: 50 });
136
141
  const char = await client.getCharacter(1, { voiceActors: true });
142
+ const characters = await client.getMediaCharacters(1, { page: 1, perPage: 25, voiceActors: true });
143
+ const staff = await client.getMediaStaff(1, { page: 1, perPage: 25 });
137
144
  const studio = await client.getStudio(21, { media: { perPage: 50 } });
138
145
  const schedule = await client.getWeeklySchedule();
139
146
  ```
package/dist/index.d.mts CHANGED
@@ -59,7 +59,7 @@ interface CacheOptions {
59
59
  }
60
60
  /** Rate limiter configuration options. */
61
61
  interface RateLimitOptions {
62
- /** Max requests per window (default: 85) */
62
+ /** Max requests per window (default: 25) */
63
63
  maxRequests?: number;
64
64
  /** Window size in ms (default: 60 000) */
65
65
  windowMs?: number;
@@ -852,6 +852,24 @@ interface MediaIncludeOptions {
852
852
  perPage?: number;
853
853
  };
854
854
  }
855
+ interface GetMediaCharactersOptions {
856
+ /** Page number */
857
+ page?: number;
858
+ /** Results per page (max 50) */
859
+ perPage?: number;
860
+ /** Disable default sort order */
861
+ sort?: boolean;
862
+ /** Include voice actors for each character edge */
863
+ voiceActors?: boolean;
864
+ }
865
+ interface GetMediaStaffOptions {
866
+ /** Page number */
867
+ page?: number;
868
+ /** Results per page (max 50) */
869
+ perPage?: number;
870
+ /** Disable default sort order */
871
+ sort?: boolean;
872
+ }
855
873
  interface AiringSchedule {
856
874
  id: number;
857
875
  airingAt: number;
@@ -1198,6 +1216,8 @@ declare class AniListClient {
1198
1216
  * @param include - Optional related data to include
1199
1217
  */
1200
1218
  getMedia(id: number, include?: MediaIncludeOptions): Promise<Media>;
1219
+ getMediaCharacters(mediaId: number, options?: GetMediaCharactersOptions): Promise<PagedResult<MediaCharacterEdge>>;
1220
+ getMediaStaff(mediaId: number, options?: GetMediaStaffOptions): Promise<PagedResult<MediaStaffEdge>>;
1201
1221
  /**
1202
1222
  * Search for anime or manga.
1203
1223
  *
@@ -1220,7 +1240,7 @@ declare class AniListClient {
1220
1240
  */
1221
1241
  getRecentlyUpdatedManga(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
1222
1242
  /**
1223
- * @deprecated Use `getRecentlyUpdatedManga` instead. This alias will be removed in v2.
1243
+ * @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
1224
1244
  */
1225
1245
  getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
1226
1246
  /**
@@ -1392,4 +1412,4 @@ declare class RateLimiter {
1392
1412
 
1393
1413
  declare function parseAniListMarkdown(text: string): string;
1394
1414
 
1395
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type CacheStats, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Logger, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioIncludeOptions, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, type UserFavoritesOptions, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
1415
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type CacheStats, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, type FuzzyDate, type GetAiringOptions, type GetMediaCharactersOptions, type GetMediaStaffOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Logger, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioIncludeOptions, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, type UserFavoritesOptions, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
package/dist/index.d.ts CHANGED
@@ -59,7 +59,7 @@ interface CacheOptions {
59
59
  }
60
60
  /** Rate limiter configuration options. */
61
61
  interface RateLimitOptions {
62
- /** Max requests per window (default: 85) */
62
+ /** Max requests per window (default: 25) */
63
63
  maxRequests?: number;
64
64
  /** Window size in ms (default: 60 000) */
65
65
  windowMs?: number;
@@ -852,6 +852,24 @@ interface MediaIncludeOptions {
852
852
  perPage?: number;
853
853
  };
854
854
  }
855
+ interface GetMediaCharactersOptions {
856
+ /** Page number */
857
+ page?: number;
858
+ /** Results per page (max 50) */
859
+ perPage?: number;
860
+ /** Disable default sort order */
861
+ sort?: boolean;
862
+ /** Include voice actors for each character edge */
863
+ voiceActors?: boolean;
864
+ }
865
+ interface GetMediaStaffOptions {
866
+ /** Page number */
867
+ page?: number;
868
+ /** Results per page (max 50) */
869
+ perPage?: number;
870
+ /** Disable default sort order */
871
+ sort?: boolean;
872
+ }
855
873
  interface AiringSchedule {
856
874
  id: number;
857
875
  airingAt: number;
@@ -1198,6 +1216,8 @@ declare class AniListClient {
1198
1216
  * @param include - Optional related data to include
1199
1217
  */
1200
1218
  getMedia(id: number, include?: MediaIncludeOptions): Promise<Media>;
1219
+ getMediaCharacters(mediaId: number, options?: GetMediaCharactersOptions): Promise<PagedResult<MediaCharacterEdge>>;
1220
+ getMediaStaff(mediaId: number, options?: GetMediaStaffOptions): Promise<PagedResult<MediaStaffEdge>>;
1201
1221
  /**
1202
1222
  * Search for anime or manga.
1203
1223
  *
@@ -1220,7 +1240,7 @@ declare class AniListClient {
1220
1240
  */
1221
1241
  getRecentlyUpdatedManga(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
1222
1242
  /**
1223
- * @deprecated Use `getRecentlyUpdatedManga` instead. This alias will be removed in v2.
1243
+ * @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
1224
1244
  */
1225
1245
  getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
1226
1246
  /**
@@ -1392,4 +1412,4 @@ declare class RateLimiter {
1392
1412
 
1393
1413
  declare function parseAniListMarkdown(text: string): string;
1394
1414
 
1395
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type CacheStats, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Logger, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioIncludeOptions, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, type UserFavoritesOptions, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
1415
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type CacheStats, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FavoriteCharacterNode, type FavoriteMediaNode, type FavoriteStaffNode, type FavoriteStudioNode, type FuzzyDate, type GetAiringOptions, type GetMediaCharactersOptions, type GetMediaStaffOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Logger, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitInfo, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ResponseMeta, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioIncludeOptions, StudioSort, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, type UserFavoritesOptions, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
package/dist/index.js CHANGED
@@ -974,6 +974,44 @@ query ($id: Int!) {
974
974
  }
975
975
  }`;
976
976
  }
977
+ function buildMediaCharactersQuery(options = {}) {
978
+ const sortClause = options.sort === false ? "" : ", sort: [ROLE, RELEVANCE, ID]";
979
+ const voiceActorBlock = options.voiceActors ? `
980
+ voiceActors {
981
+ ${VOICE_ACTOR_FIELDS_COMPACT}
982
+ }` : "";
983
+ return `
984
+ query ($mediaId: Int!, $page: Int, $perPage: Int) {
985
+ Media(id: $mediaId) {
986
+ characters(page: $page, perPage: $perPage${sortClause}) {
987
+ pageInfo { total perPage currentPage lastPage hasNextPage }
988
+ edges {
989
+ role
990
+ node {
991
+ ${CHARACTER_FIELDS_COMPACT}
992
+ }${voiceActorBlock}
993
+ }
994
+ }
995
+ }
996
+ }`;
997
+ }
998
+ function buildMediaStaffQuery(options = {}) {
999
+ const sortClause = options.sort === false ? "" : ", sort: [RELEVANCE, ID]";
1000
+ return `
1001
+ query ($mediaId: Int!, $page: Int, $perPage: Int) {
1002
+ Media(id: $mediaId) {
1003
+ staff(page: $page, perPage: $perPage${sortClause}) {
1004
+ pageInfo { total perPage currentPage lastPage hasNextPage }
1005
+ edges {
1006
+ role
1007
+ node {
1008
+ ${STAFF_FIELDS}
1009
+ }
1010
+ }
1011
+ }
1012
+ }
1013
+ }`;
1014
+ }
977
1015
  function buildBatchQuery(ids, typeName, fields, prefix) {
978
1016
  const aliases = ids.map((id, i) => `${prefix}${i}: ${typeName}(id: ${id}) { ${fields} }`).join("\n ");
979
1017
  return `query {
@@ -1626,6 +1664,25 @@ async function getMedia(client, id, include) {
1626
1664
  const data = await client.request(query, { id });
1627
1665
  return data.Media;
1628
1666
  }
1667
+ async function getMediaCharacters(client, mediaId, options = {}) {
1668
+ validateId(mediaId, "mediaId");
1669
+ const query = buildMediaCharactersQuery(options);
1670
+ const data = await client.request(
1671
+ query,
1672
+ { mediaId, page: options.page ?? 1, perPage: clampPerPage(options.perPage ?? 25) }
1673
+ );
1674
+ return { pageInfo: data.Media.characters.pageInfo, results: data.Media.characters.edges };
1675
+ }
1676
+ async function getMediaStaff(client, mediaId, options = {}) {
1677
+ validateId(mediaId, "mediaId");
1678
+ const query = buildMediaStaffQuery(options);
1679
+ const data = await client.request(query, {
1680
+ mediaId,
1681
+ page: options.page ?? 1,
1682
+ perPage: clampPerPage(options.perPage ?? 25)
1683
+ });
1684
+ return { pageInfo: data.Media.staff.pageInfo, results: data.Media.staff.edges };
1685
+ }
1629
1686
  async function getMediaByMalId(client, malId, type) {
1630
1687
  validateId(malId, "malId");
1631
1688
  const data = await client.request(QUERY_MEDIA_BY_MAL_ID, {
@@ -1910,7 +1967,7 @@ function mapFavorites(fav) {
1910
1967
 
1911
1968
  // src/client/index.ts
1912
1969
  var DEFAULT_API_URL = "https://graphql.anilist.co";
1913
- var LIB_VERSION = "2.0.2" ;
1970
+ var LIB_VERSION = "2.0.3" ;
1914
1971
  var AniListClient = class {
1915
1972
  apiUrl;
1916
1973
  headers;
@@ -2053,6 +2110,12 @@ var AniListClient = class {
2053
2110
  async getMedia(id, include) {
2054
2111
  return getMedia(this, id, include);
2055
2112
  }
2113
+ async getMediaCharacters(mediaId, options = {}) {
2114
+ return getMediaCharacters(this, mediaId, options);
2115
+ }
2116
+ async getMediaStaff(mediaId, options = {}) {
2117
+ return getMediaStaff(this, mediaId, options);
2118
+ }
2056
2119
  /**
2057
2120
  * Search for anime or manga.
2058
2121
  *
@@ -2087,7 +2150,7 @@ var AniListClient = class {
2087
2150
  return getRecentlyUpdatedManga(this, options);
2088
2151
  }
2089
2152
  /**
2090
- * @deprecated Use `getRecentlyUpdatedManga` instead. This alias will be removed in v2.
2153
+ * @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
2091
2154
  */
2092
2155
  async getAiredChapters(options = {}) {
2093
2156
  return this.getRecentlyUpdatedManga(options);