ani-client 1.4.4 → 1.5.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 +2 -2
- package/dist/index.d.mts +118 -24
- package/dist/index.d.ts +118 -24
- package/dist/index.js +177 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +176 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
> A simple, typed client to fetch anime, manga, character, staff and user data from [AniList](https://anilist.co).
|
|
8
8
|
|
|
9
|
-
✨ **Showcase**: [Check here](https://
|
|
9
|
+
✨ **Showcase**: [Check here](https://docs-aniclient.gonzyuidev.xyz/showcase) to see which projects use this package!
|
|
10
10
|
|
|
11
11
|
- **Zero dependencies** — uses the native `fetch` API
|
|
12
12
|
- **Universal** — Node.js ≥ 20, Bun, Deno and modern browsers
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
The full API reference, usage guide, and configuration examples are available on our official documentation website!
|
|
19
19
|
|
|
20
|
-
**[👉 View the full documentation here](https://
|
|
20
|
+
**[👉 View the full documentation here](https://docs-aniclient.gonzyuidev.xyz/)**
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
package/dist/index.d.mts
CHANGED
|
@@ -348,27 +348,36 @@ interface Studio {
|
|
|
348
348
|
name: string;
|
|
349
349
|
isAnimationStudio: boolean;
|
|
350
350
|
siteUrl: string | null;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
nodes: Studio[];
|
|
354
|
-
}
|
|
355
|
-
interface StudioDetail {
|
|
356
|
-
id: number;
|
|
357
|
-
name: string;
|
|
358
|
-
isAnimationStudio: boolean;
|
|
359
|
-
siteUrl: string | null;
|
|
360
|
-
favourites: number | null;
|
|
361
|
-
media: {
|
|
351
|
+
favourites?: number | null;
|
|
352
|
+
media?: {
|
|
362
353
|
pageInfo: PageInfo;
|
|
363
354
|
nodes: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "siteUrl">[];
|
|
364
355
|
} | null;
|
|
365
356
|
}
|
|
357
|
+
interface StudioConnection {
|
|
358
|
+
nodes: Studio[];
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* @deprecated Use `Studio` instead. `StudioDetail` is an alias kept for backward compatibility.
|
|
362
|
+
*/
|
|
363
|
+
type StudioDetail = Studio;
|
|
366
364
|
interface SearchStudioOptions {
|
|
367
365
|
query?: string;
|
|
368
366
|
page?: number;
|
|
369
367
|
perPage?: number;
|
|
370
368
|
}
|
|
371
369
|
|
|
370
|
+
declare enum UserSort {
|
|
371
|
+
ID = "ID",
|
|
372
|
+
ID_DESC = "ID_DESC",
|
|
373
|
+
USERNAME = "USERNAME",
|
|
374
|
+
USERNAME_DESC = "USERNAME_DESC",
|
|
375
|
+
WATCHED_TIME = "WATCHED_TIME",
|
|
376
|
+
WATCHED_TIME_DESC = "WATCHED_TIME_DESC",
|
|
377
|
+
CHAPTERS_READ = "CHAPTERS_READ",
|
|
378
|
+
CHAPTERS_READ_DESC = "CHAPTERS_READ_DESC",
|
|
379
|
+
SEARCH_MATCH = "SEARCH_MATCH"
|
|
380
|
+
}
|
|
372
381
|
interface UserAvatar {
|
|
373
382
|
large: string | null;
|
|
374
383
|
medium: string | null;
|
|
@@ -398,11 +407,34 @@ interface User {
|
|
|
398
407
|
manga: UserStatistics;
|
|
399
408
|
} | null;
|
|
400
409
|
}
|
|
410
|
+
interface SearchUserOptions {
|
|
411
|
+
query?: string;
|
|
412
|
+
sort?: UserSort[];
|
|
413
|
+
page?: number;
|
|
414
|
+
perPage?: number;
|
|
415
|
+
}
|
|
401
416
|
|
|
402
417
|
declare enum MediaType {
|
|
403
418
|
ANIME = "ANIME",
|
|
404
419
|
MANGA = "MANGA"
|
|
405
420
|
}
|
|
421
|
+
declare enum MediaSource {
|
|
422
|
+
ORIGINAL = "ORIGINAL",
|
|
423
|
+
MANGA = "MANGA",
|
|
424
|
+
LIGHT_NOVEL = "LIGHT_NOVEL",
|
|
425
|
+
VISUAL_NOVEL = "VISUAL_NOVEL",
|
|
426
|
+
VIDEO_GAME = "VIDEO_GAME",
|
|
427
|
+
OTHER = "OTHER",
|
|
428
|
+
NOVEL = "NOVEL",
|
|
429
|
+
DOUJINSHI = "DOUJINSHI",
|
|
430
|
+
ANIME = "ANIME",
|
|
431
|
+
WEB_NOVEL = "WEB_NOVEL",
|
|
432
|
+
LIVE_ACTION = "LIVE_ACTION",
|
|
433
|
+
GAME = "GAME",
|
|
434
|
+
COMIC = "COMIC",
|
|
435
|
+
MULTIMEDIA_PROJECT = "MULTIMEDIA_PROJECT",
|
|
436
|
+
PICTURE_BOOK = "PICTURE_BOOK"
|
|
437
|
+
}
|
|
406
438
|
declare enum MediaFormat {
|
|
407
439
|
TV = "TV",
|
|
408
440
|
TV_SHORT = "TV_SHORT",
|
|
@@ -558,6 +590,13 @@ interface MediaRecommendationNode {
|
|
|
558
590
|
rating: number | null;
|
|
559
591
|
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "siteUrl">;
|
|
560
592
|
}
|
|
593
|
+
interface NextAiringEpisode {
|
|
594
|
+
id: number;
|
|
595
|
+
airingAt: number;
|
|
596
|
+
episode: number;
|
|
597
|
+
mediaId: number;
|
|
598
|
+
timeUntilAiring: number;
|
|
599
|
+
}
|
|
561
600
|
interface Media {
|
|
562
601
|
id: number;
|
|
563
602
|
idMal: number | null;
|
|
@@ -576,7 +615,7 @@ interface Media {
|
|
|
576
615
|
volumes: number | null;
|
|
577
616
|
countryOfOrigin: string | null;
|
|
578
617
|
isLicensed: boolean | null;
|
|
579
|
-
source:
|
|
618
|
+
source: MediaSource | null;
|
|
580
619
|
hashtag: string | null;
|
|
581
620
|
trailer: MediaTrailer | null;
|
|
582
621
|
coverImage: MediaCoverImage;
|
|
@@ -599,6 +638,7 @@ interface Media {
|
|
|
599
638
|
recommendations?: {
|
|
600
639
|
nodes: MediaRecommendationNode[];
|
|
601
640
|
};
|
|
641
|
+
nextAiringEpisode: NextAiringEpisode | null;
|
|
602
642
|
isAdult: boolean | null;
|
|
603
643
|
siteUrl: string | null;
|
|
604
644
|
}
|
|
@@ -609,8 +649,18 @@ interface SearchMediaOptions {
|
|
|
609
649
|
status?: MediaStatus;
|
|
610
650
|
season?: MediaSeason;
|
|
611
651
|
seasonYear?: number;
|
|
652
|
+
/** Single genre filter (kept for backward compat) */
|
|
612
653
|
genre?: string;
|
|
654
|
+
/** Single tag filter (kept for backward compat) */
|
|
613
655
|
tag?: string;
|
|
656
|
+
/** Filter by multiple genres (media must match ALL) */
|
|
657
|
+
genres?: string[];
|
|
658
|
+
/** Filter by multiple tags (media must match ALL) */
|
|
659
|
+
tags?: string[];
|
|
660
|
+
/** Exclude media with any of these genres */
|
|
661
|
+
genresExclude?: string[];
|
|
662
|
+
/** Exclude media with any of these tags */
|
|
663
|
+
tagsExclude?: string[];
|
|
614
664
|
isAdult?: boolean;
|
|
615
665
|
sort?: MediaSort[];
|
|
616
666
|
page?: number;
|
|
@@ -814,6 +864,26 @@ declare class AniListClient {
|
|
|
814
864
|
* @param perPage - Results per page (default 20, max 50)
|
|
815
865
|
*/
|
|
816
866
|
getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
867
|
+
/**
|
|
868
|
+
* Get the most popular anime or manga.
|
|
869
|
+
*
|
|
870
|
+
* Convenience wrapper around `searchMedia` with `sort: POPULARITY_DESC`.
|
|
871
|
+
*
|
|
872
|
+
* @param type - `MediaType.ANIME` or `MediaType.MANGA` (defaults to ANIME)
|
|
873
|
+
* @param page - Page number (default 1)
|
|
874
|
+
* @param perPage - Results per page (default 20, max 50)
|
|
875
|
+
*/
|
|
876
|
+
getPopular(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
877
|
+
/**
|
|
878
|
+
* Get the highest-rated anime or manga.
|
|
879
|
+
*
|
|
880
|
+
* Convenience wrapper around `searchMedia` with `sort: SCORE_DESC`.
|
|
881
|
+
*
|
|
882
|
+
* @param type - `MediaType.ANIME` or `MediaType.MANGA` (defaults to ANIME)
|
|
883
|
+
* @param page - Page number (default 1)
|
|
884
|
+
* @param perPage - Results per page (default 20, max 50)
|
|
885
|
+
*/
|
|
886
|
+
getTopRated(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
817
887
|
/**
|
|
818
888
|
* Fetch a character by AniList ID.
|
|
819
889
|
*
|
|
@@ -881,31 +951,39 @@ declare class AniListClient {
|
|
|
881
951
|
*/
|
|
882
952
|
searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
|
|
883
953
|
/**
|
|
884
|
-
* Fetch a user by AniList ID.
|
|
954
|
+
* Fetch a user by AniList ID or username.
|
|
885
955
|
*
|
|
886
|
-
* @param
|
|
956
|
+
* @param idOrName - The AniList user ID (number) or username (string)
|
|
887
957
|
* @returns The user object
|
|
888
958
|
*
|
|
889
959
|
* @example
|
|
890
960
|
* ```ts
|
|
891
961
|
* const user = await client.getUser(1);
|
|
962
|
+
* const user2 = await client.getUser("AniList");
|
|
892
963
|
* console.log(user.name);
|
|
893
964
|
* ```
|
|
894
965
|
*/
|
|
895
|
-
getUser(
|
|
966
|
+
getUser(idOrName: number | string): Promise<User>;
|
|
896
967
|
/**
|
|
897
968
|
* Fetch a user by username.
|
|
898
969
|
*
|
|
970
|
+
* @deprecated Use `getUser(name)` instead.
|
|
899
971
|
* @param name - The AniList username
|
|
900
972
|
* @returns The user object
|
|
973
|
+
*/
|
|
974
|
+
getUserByName(name: string): Promise<User>;
|
|
975
|
+
/**
|
|
976
|
+
* Search for users by name.
|
|
977
|
+
*
|
|
978
|
+
* @param options - Search / pagination parameters
|
|
979
|
+
* @returns Paginated results with matching users
|
|
901
980
|
*
|
|
902
981
|
* @example
|
|
903
982
|
* ```ts
|
|
904
|
-
* const
|
|
905
|
-
* console.log(user.statistics);
|
|
983
|
+
* const result = await client.searchUsers({ query: "AniList", perPage: 5 });
|
|
906
984
|
* ```
|
|
907
985
|
*/
|
|
908
|
-
|
|
986
|
+
searchUsers(options?: SearchUserOptions): Promise<PagedResult<User>>;
|
|
909
987
|
/**
|
|
910
988
|
* Execute an arbitrary GraphQL query against the AniList API.
|
|
911
989
|
* Useful for advanced use-cases not covered by the built-in methods.
|
|
@@ -1030,7 +1108,7 @@ declare class AniListClient {
|
|
|
1030
1108
|
*
|
|
1031
1109
|
* @param id - The AniList studio ID
|
|
1032
1110
|
*/
|
|
1033
|
-
getStudio(id: number): Promise<
|
|
1111
|
+
getStudio(id: number): Promise<Studio>;
|
|
1034
1112
|
/**
|
|
1035
1113
|
* Search for studios by name.
|
|
1036
1114
|
*
|
|
@@ -1042,7 +1120,7 @@ declare class AniListClient {
|
|
|
1042
1120
|
* const studios = await client.searchStudios({ query: "MAPPA" });
|
|
1043
1121
|
* ```
|
|
1044
1122
|
*/
|
|
1045
|
-
searchStudios(options?: SearchStudioOptions): Promise<PagedResult<
|
|
1123
|
+
searchStudios(options?: SearchStudioOptions): Promise<PagedResult<Studio>>;
|
|
1046
1124
|
/**
|
|
1047
1125
|
* Get all available genres on AniList.
|
|
1048
1126
|
*
|
|
@@ -1124,6 +1202,14 @@ declare class AniListClient {
|
|
|
1124
1202
|
* @returns Number of entries removed
|
|
1125
1203
|
*/
|
|
1126
1204
|
invalidateCache(pattern: string | RegExp): Promise<number>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Clean up resources held by the client.
|
|
1207
|
+
*
|
|
1208
|
+
* Clears the in-memory cache and aborts any pending in-flight requests.
|
|
1209
|
+
* If using a custom cache adapter (e.g. Redis), call its close/disconnect
|
|
1210
|
+
* method separately.
|
|
1211
|
+
*/
|
|
1212
|
+
destroy(): Promise<void>;
|
|
1127
1213
|
}
|
|
1128
1214
|
|
|
1129
1215
|
/**
|
|
@@ -1160,7 +1246,10 @@ declare class MemoryCache implements CacheAdapter {
|
|
|
1160
1246
|
/**
|
|
1161
1247
|
* Remove all entries whose key matches the given pattern.
|
|
1162
1248
|
*
|
|
1163
|
-
*
|
|
1249
|
+
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
1250
|
+
* - **RegExp**: tested against each key directly.
|
|
1251
|
+
*
|
|
1252
|
+
* @param pattern — A string (substring match) or RegExp.
|
|
1164
1253
|
* @returns Number of entries removed.
|
|
1165
1254
|
*/
|
|
1166
1255
|
invalidate(pattern: string | RegExp): number;
|
|
@@ -1253,8 +1342,10 @@ declare class RateLimiter {
|
|
|
1253
1342
|
private readonly enabled;
|
|
1254
1343
|
private readonly timeoutMs;
|
|
1255
1344
|
private readonly retryOnNetworkError;
|
|
1256
|
-
/** @internal */
|
|
1257
|
-
private timestamps;
|
|
1345
|
+
/** @internal — sliding window: circular buffer of timestamps */
|
|
1346
|
+
private readonly timestamps;
|
|
1347
|
+
private head;
|
|
1348
|
+
private count;
|
|
1258
1349
|
constructor(options?: RateLimitOptions);
|
|
1259
1350
|
/**
|
|
1260
1351
|
* Wait until it's safe to make a request (respects rate limit window).
|
|
@@ -1262,14 +1353,17 @@ declare class RateLimiter {
|
|
|
1262
1353
|
acquire(): Promise<void>;
|
|
1263
1354
|
/**
|
|
1264
1355
|
* Execute a fetch with automatic retry on 429 responses and network errors.
|
|
1356
|
+
* Uses exponential backoff with jitter for retry delays.
|
|
1265
1357
|
*/
|
|
1266
1358
|
fetchWithRetry(url: string, init: RequestInit, hooks?: {
|
|
1267
1359
|
onRetry?: (attempt: number, reason: string, delayMs: number) => void;
|
|
1268
1360
|
onRateLimit?: (retryAfterMs: number) => void;
|
|
1269
1361
|
}): Promise<Response>;
|
|
1362
|
+
/** @internal — Exponential backoff with jitter, capped at 30s */
|
|
1363
|
+
private exponentialDelay;
|
|
1270
1364
|
/** @internal */
|
|
1271
1365
|
private fetchWithTimeout;
|
|
1272
1366
|
private sleep;
|
|
1273
1367
|
}
|
|
1274
1368
|
|
|
1275
|
-
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics, type VoiceActor };
|
|
1369
|
+
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, 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 RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, UserSort, type UserStatistics, type VoiceActor };
|
package/dist/index.d.ts
CHANGED
|
@@ -348,27 +348,36 @@ interface Studio {
|
|
|
348
348
|
name: string;
|
|
349
349
|
isAnimationStudio: boolean;
|
|
350
350
|
siteUrl: string | null;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
nodes: Studio[];
|
|
354
|
-
}
|
|
355
|
-
interface StudioDetail {
|
|
356
|
-
id: number;
|
|
357
|
-
name: string;
|
|
358
|
-
isAnimationStudio: boolean;
|
|
359
|
-
siteUrl: string | null;
|
|
360
|
-
favourites: number | null;
|
|
361
|
-
media: {
|
|
351
|
+
favourites?: number | null;
|
|
352
|
+
media?: {
|
|
362
353
|
pageInfo: PageInfo;
|
|
363
354
|
nodes: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "siteUrl">[];
|
|
364
355
|
} | null;
|
|
365
356
|
}
|
|
357
|
+
interface StudioConnection {
|
|
358
|
+
nodes: Studio[];
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* @deprecated Use `Studio` instead. `StudioDetail` is an alias kept for backward compatibility.
|
|
362
|
+
*/
|
|
363
|
+
type StudioDetail = Studio;
|
|
366
364
|
interface SearchStudioOptions {
|
|
367
365
|
query?: string;
|
|
368
366
|
page?: number;
|
|
369
367
|
perPage?: number;
|
|
370
368
|
}
|
|
371
369
|
|
|
370
|
+
declare enum UserSort {
|
|
371
|
+
ID = "ID",
|
|
372
|
+
ID_DESC = "ID_DESC",
|
|
373
|
+
USERNAME = "USERNAME",
|
|
374
|
+
USERNAME_DESC = "USERNAME_DESC",
|
|
375
|
+
WATCHED_TIME = "WATCHED_TIME",
|
|
376
|
+
WATCHED_TIME_DESC = "WATCHED_TIME_DESC",
|
|
377
|
+
CHAPTERS_READ = "CHAPTERS_READ",
|
|
378
|
+
CHAPTERS_READ_DESC = "CHAPTERS_READ_DESC",
|
|
379
|
+
SEARCH_MATCH = "SEARCH_MATCH"
|
|
380
|
+
}
|
|
372
381
|
interface UserAvatar {
|
|
373
382
|
large: string | null;
|
|
374
383
|
medium: string | null;
|
|
@@ -398,11 +407,34 @@ interface User {
|
|
|
398
407
|
manga: UserStatistics;
|
|
399
408
|
} | null;
|
|
400
409
|
}
|
|
410
|
+
interface SearchUserOptions {
|
|
411
|
+
query?: string;
|
|
412
|
+
sort?: UserSort[];
|
|
413
|
+
page?: number;
|
|
414
|
+
perPage?: number;
|
|
415
|
+
}
|
|
401
416
|
|
|
402
417
|
declare enum MediaType {
|
|
403
418
|
ANIME = "ANIME",
|
|
404
419
|
MANGA = "MANGA"
|
|
405
420
|
}
|
|
421
|
+
declare enum MediaSource {
|
|
422
|
+
ORIGINAL = "ORIGINAL",
|
|
423
|
+
MANGA = "MANGA",
|
|
424
|
+
LIGHT_NOVEL = "LIGHT_NOVEL",
|
|
425
|
+
VISUAL_NOVEL = "VISUAL_NOVEL",
|
|
426
|
+
VIDEO_GAME = "VIDEO_GAME",
|
|
427
|
+
OTHER = "OTHER",
|
|
428
|
+
NOVEL = "NOVEL",
|
|
429
|
+
DOUJINSHI = "DOUJINSHI",
|
|
430
|
+
ANIME = "ANIME",
|
|
431
|
+
WEB_NOVEL = "WEB_NOVEL",
|
|
432
|
+
LIVE_ACTION = "LIVE_ACTION",
|
|
433
|
+
GAME = "GAME",
|
|
434
|
+
COMIC = "COMIC",
|
|
435
|
+
MULTIMEDIA_PROJECT = "MULTIMEDIA_PROJECT",
|
|
436
|
+
PICTURE_BOOK = "PICTURE_BOOK"
|
|
437
|
+
}
|
|
406
438
|
declare enum MediaFormat {
|
|
407
439
|
TV = "TV",
|
|
408
440
|
TV_SHORT = "TV_SHORT",
|
|
@@ -558,6 +590,13 @@ interface MediaRecommendationNode {
|
|
|
558
590
|
rating: number | null;
|
|
559
591
|
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "siteUrl">;
|
|
560
592
|
}
|
|
593
|
+
interface NextAiringEpisode {
|
|
594
|
+
id: number;
|
|
595
|
+
airingAt: number;
|
|
596
|
+
episode: number;
|
|
597
|
+
mediaId: number;
|
|
598
|
+
timeUntilAiring: number;
|
|
599
|
+
}
|
|
561
600
|
interface Media {
|
|
562
601
|
id: number;
|
|
563
602
|
idMal: number | null;
|
|
@@ -576,7 +615,7 @@ interface Media {
|
|
|
576
615
|
volumes: number | null;
|
|
577
616
|
countryOfOrigin: string | null;
|
|
578
617
|
isLicensed: boolean | null;
|
|
579
|
-
source:
|
|
618
|
+
source: MediaSource | null;
|
|
580
619
|
hashtag: string | null;
|
|
581
620
|
trailer: MediaTrailer | null;
|
|
582
621
|
coverImage: MediaCoverImage;
|
|
@@ -599,6 +638,7 @@ interface Media {
|
|
|
599
638
|
recommendations?: {
|
|
600
639
|
nodes: MediaRecommendationNode[];
|
|
601
640
|
};
|
|
641
|
+
nextAiringEpisode: NextAiringEpisode | null;
|
|
602
642
|
isAdult: boolean | null;
|
|
603
643
|
siteUrl: string | null;
|
|
604
644
|
}
|
|
@@ -609,8 +649,18 @@ interface SearchMediaOptions {
|
|
|
609
649
|
status?: MediaStatus;
|
|
610
650
|
season?: MediaSeason;
|
|
611
651
|
seasonYear?: number;
|
|
652
|
+
/** Single genre filter (kept for backward compat) */
|
|
612
653
|
genre?: string;
|
|
654
|
+
/** Single tag filter (kept for backward compat) */
|
|
613
655
|
tag?: string;
|
|
656
|
+
/** Filter by multiple genres (media must match ALL) */
|
|
657
|
+
genres?: string[];
|
|
658
|
+
/** Filter by multiple tags (media must match ALL) */
|
|
659
|
+
tags?: string[];
|
|
660
|
+
/** Exclude media with any of these genres */
|
|
661
|
+
genresExclude?: string[];
|
|
662
|
+
/** Exclude media with any of these tags */
|
|
663
|
+
tagsExclude?: string[];
|
|
614
664
|
isAdult?: boolean;
|
|
615
665
|
sort?: MediaSort[];
|
|
616
666
|
page?: number;
|
|
@@ -814,6 +864,26 @@ declare class AniListClient {
|
|
|
814
864
|
* @param perPage - Results per page (default 20, max 50)
|
|
815
865
|
*/
|
|
816
866
|
getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
867
|
+
/**
|
|
868
|
+
* Get the most popular anime or manga.
|
|
869
|
+
*
|
|
870
|
+
* Convenience wrapper around `searchMedia` with `sort: POPULARITY_DESC`.
|
|
871
|
+
*
|
|
872
|
+
* @param type - `MediaType.ANIME` or `MediaType.MANGA` (defaults to ANIME)
|
|
873
|
+
* @param page - Page number (default 1)
|
|
874
|
+
* @param perPage - Results per page (default 20, max 50)
|
|
875
|
+
*/
|
|
876
|
+
getPopular(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
877
|
+
/**
|
|
878
|
+
* Get the highest-rated anime or manga.
|
|
879
|
+
*
|
|
880
|
+
* Convenience wrapper around `searchMedia` with `sort: SCORE_DESC`.
|
|
881
|
+
*
|
|
882
|
+
* @param type - `MediaType.ANIME` or `MediaType.MANGA` (defaults to ANIME)
|
|
883
|
+
* @param page - Page number (default 1)
|
|
884
|
+
* @param perPage - Results per page (default 20, max 50)
|
|
885
|
+
*/
|
|
886
|
+
getTopRated(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
|
|
817
887
|
/**
|
|
818
888
|
* Fetch a character by AniList ID.
|
|
819
889
|
*
|
|
@@ -881,31 +951,39 @@ declare class AniListClient {
|
|
|
881
951
|
*/
|
|
882
952
|
searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
|
|
883
953
|
/**
|
|
884
|
-
* Fetch a user by AniList ID.
|
|
954
|
+
* Fetch a user by AniList ID or username.
|
|
885
955
|
*
|
|
886
|
-
* @param
|
|
956
|
+
* @param idOrName - The AniList user ID (number) or username (string)
|
|
887
957
|
* @returns The user object
|
|
888
958
|
*
|
|
889
959
|
* @example
|
|
890
960
|
* ```ts
|
|
891
961
|
* const user = await client.getUser(1);
|
|
962
|
+
* const user2 = await client.getUser("AniList");
|
|
892
963
|
* console.log(user.name);
|
|
893
964
|
* ```
|
|
894
965
|
*/
|
|
895
|
-
getUser(
|
|
966
|
+
getUser(idOrName: number | string): Promise<User>;
|
|
896
967
|
/**
|
|
897
968
|
* Fetch a user by username.
|
|
898
969
|
*
|
|
970
|
+
* @deprecated Use `getUser(name)` instead.
|
|
899
971
|
* @param name - The AniList username
|
|
900
972
|
* @returns The user object
|
|
973
|
+
*/
|
|
974
|
+
getUserByName(name: string): Promise<User>;
|
|
975
|
+
/**
|
|
976
|
+
* Search for users by name.
|
|
977
|
+
*
|
|
978
|
+
* @param options - Search / pagination parameters
|
|
979
|
+
* @returns Paginated results with matching users
|
|
901
980
|
*
|
|
902
981
|
* @example
|
|
903
982
|
* ```ts
|
|
904
|
-
* const
|
|
905
|
-
* console.log(user.statistics);
|
|
983
|
+
* const result = await client.searchUsers({ query: "AniList", perPage: 5 });
|
|
906
984
|
* ```
|
|
907
985
|
*/
|
|
908
|
-
|
|
986
|
+
searchUsers(options?: SearchUserOptions): Promise<PagedResult<User>>;
|
|
909
987
|
/**
|
|
910
988
|
* Execute an arbitrary GraphQL query against the AniList API.
|
|
911
989
|
* Useful for advanced use-cases not covered by the built-in methods.
|
|
@@ -1030,7 +1108,7 @@ declare class AniListClient {
|
|
|
1030
1108
|
*
|
|
1031
1109
|
* @param id - The AniList studio ID
|
|
1032
1110
|
*/
|
|
1033
|
-
getStudio(id: number): Promise<
|
|
1111
|
+
getStudio(id: number): Promise<Studio>;
|
|
1034
1112
|
/**
|
|
1035
1113
|
* Search for studios by name.
|
|
1036
1114
|
*
|
|
@@ -1042,7 +1120,7 @@ declare class AniListClient {
|
|
|
1042
1120
|
* const studios = await client.searchStudios({ query: "MAPPA" });
|
|
1043
1121
|
* ```
|
|
1044
1122
|
*/
|
|
1045
|
-
searchStudios(options?: SearchStudioOptions): Promise<PagedResult<
|
|
1123
|
+
searchStudios(options?: SearchStudioOptions): Promise<PagedResult<Studio>>;
|
|
1046
1124
|
/**
|
|
1047
1125
|
* Get all available genres on AniList.
|
|
1048
1126
|
*
|
|
@@ -1124,6 +1202,14 @@ declare class AniListClient {
|
|
|
1124
1202
|
* @returns Number of entries removed
|
|
1125
1203
|
*/
|
|
1126
1204
|
invalidateCache(pattern: string | RegExp): Promise<number>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Clean up resources held by the client.
|
|
1207
|
+
*
|
|
1208
|
+
* Clears the in-memory cache and aborts any pending in-flight requests.
|
|
1209
|
+
* If using a custom cache adapter (e.g. Redis), call its close/disconnect
|
|
1210
|
+
* method separately.
|
|
1211
|
+
*/
|
|
1212
|
+
destroy(): Promise<void>;
|
|
1127
1213
|
}
|
|
1128
1214
|
|
|
1129
1215
|
/**
|
|
@@ -1160,7 +1246,10 @@ declare class MemoryCache implements CacheAdapter {
|
|
|
1160
1246
|
/**
|
|
1161
1247
|
* Remove all entries whose key matches the given pattern.
|
|
1162
1248
|
*
|
|
1163
|
-
*
|
|
1249
|
+
* - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
|
|
1250
|
+
* - **RegExp**: tested against each key directly.
|
|
1251
|
+
*
|
|
1252
|
+
* @param pattern — A string (substring match) or RegExp.
|
|
1164
1253
|
* @returns Number of entries removed.
|
|
1165
1254
|
*/
|
|
1166
1255
|
invalidate(pattern: string | RegExp): number;
|
|
@@ -1253,8 +1342,10 @@ declare class RateLimiter {
|
|
|
1253
1342
|
private readonly enabled;
|
|
1254
1343
|
private readonly timeoutMs;
|
|
1255
1344
|
private readonly retryOnNetworkError;
|
|
1256
|
-
/** @internal */
|
|
1257
|
-
private timestamps;
|
|
1345
|
+
/** @internal — sliding window: circular buffer of timestamps */
|
|
1346
|
+
private readonly timestamps;
|
|
1347
|
+
private head;
|
|
1348
|
+
private count;
|
|
1258
1349
|
constructor(options?: RateLimitOptions);
|
|
1259
1350
|
/**
|
|
1260
1351
|
* Wait until it's safe to make a request (respects rate limit window).
|
|
@@ -1262,14 +1353,17 @@ declare class RateLimiter {
|
|
|
1262
1353
|
acquire(): Promise<void>;
|
|
1263
1354
|
/**
|
|
1264
1355
|
* Execute a fetch with automatic retry on 429 responses and network errors.
|
|
1356
|
+
* Uses exponential backoff with jitter for retry delays.
|
|
1265
1357
|
*/
|
|
1266
1358
|
fetchWithRetry(url: string, init: RequestInit, hooks?: {
|
|
1267
1359
|
onRetry?: (attempt: number, reason: string, delayMs: number) => void;
|
|
1268
1360
|
onRateLimit?: (retryAfterMs: number) => void;
|
|
1269
1361
|
}): Promise<Response>;
|
|
1362
|
+
/** @internal — Exponential backoff with jitter, capped at 30s */
|
|
1363
|
+
private exponentialDelay;
|
|
1270
1364
|
/** @internal */
|
|
1271
1365
|
private fetchWithTimeout;
|
|
1272
1366
|
private sleep;
|
|
1273
1367
|
}
|
|
1274
1368
|
|
|
1275
|
-
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics, type VoiceActor };
|
|
1369
|
+
export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, 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 RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, UserSort, type UserStatistics, type VoiceActor };
|