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 +7 -0
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +65 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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:
|
|
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
|
|
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:
|
|
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
|
|
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.
|
|
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
|
|
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);
|