ani-client 1.5.1 → 1.6.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
@@ -1,12 +1,13 @@
1
- # ani-client
1
+ # ani-client
2
2
 
3
+ ![ani-client logo](docs/public/assets/logo.png)
3
4
  [![CI](https://github.com/gonzyui/ani-client/actions/workflows/ci.yml/badge.svg)](https://github.com/gonzyui/ani-client/actions/workflows/ci.yml)
4
5
  [![npm](https://img.shields.io/npm/v/ani-client)](https://www.npmjs.com/package/ani-client)
5
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
7
 
7
8
  > A simple, typed client to fetch anime, manga, character, staff and user data from [AniList](https://anilist.co).
8
9
 
9
- ✨ **Showcase**: [Check here](https://docs-aniclient.gonzyuidev.xyz/showcase) to see which projects use this package!
10
+ ✨ **Showcase**: [Check here](https://gonzyuidev.xyz/projects/aniclient/showcase) to see which projects use this package!
10
11
 
11
12
  - **Zero dependencies** — uses the native `fetch` API
12
13
  - **Universal** — Node.js ≥ 20, Bun, Deno and modern browsers
@@ -17,7 +18,7 @@
17
18
 
18
19
  The full API reference, usage guide, and configuration examples are available on our official documentation website!
19
20
 
20
- **[👉 View the full documentation here](https://docs-aniclient.gonzyuidev.xyz/)**
21
+ **[👉 View the full documentation here](https://gonzyuidev.xyz/projects/aniclient/)**
21
22
 
22
23
  ## Install
23
24
 
@@ -55,6 +56,43 @@ const results = await client.searchMedia({
55
56
  console.log(results.results.map((m) => m.title.english));
56
57
  ```
57
58
 
59
+ ### Fetch user favorites
60
+
61
+ ```ts
62
+ const favs = await client.getUserFavorites("AniList");
63
+
64
+ favs.anime.forEach((a) => console.log(a.title.romaji));
65
+ favs.characters.forEach((c) => console.log(c.name.full));
66
+ ```
67
+
68
+ ### Monitor rate limits
69
+
70
+ ```ts
71
+ const client = new AniListClient({
72
+ rateLimit: {
73
+ retryStrategy: (attempt) => (attempt + 1) * 1000, // linear backoff
74
+ },
75
+ });
76
+
77
+ await client.getMedia(1);
78
+
79
+ const info = client.rateLimitInfo;
80
+ console.log(`${info?.remaining}/${info?.limit} requests remaining`);
81
+
82
+ const meta = client.lastRequestMeta;
83
+ console.log(`${meta?.durationMs}ms, cache: ${meta?.fromCache}`);
84
+ ```
85
+
86
+ ### Cancel requests
87
+
88
+ ```ts
89
+ const controller = new AbortController();
90
+ const client = new AniListClient({ signal: controller.signal });
91
+
92
+ setTimeout(() => controller.abort(), 5_000);
93
+ await client.getMedia(1); // aborted after 5s
94
+ ```
95
+
58
96
  ## Contributing
59
97
 
60
98
  See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding standards, and how to submit changes.
package/dist/index.d.mts CHANGED
@@ -67,6 +67,16 @@ interface RateLimitOptions {
67
67
  timeoutMs?: number;
68
68
  /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
69
69
  retryOnNetworkError?: boolean;
70
+ /**
71
+ * Custom retry delay strategy. Receives the attempt number (0-based) and the base delay,
72
+ * and should return the delay in ms before retrying.
73
+ * When omitted, the default exponential backoff with jitter is used.
74
+ *
75
+ * @example
76
+ * // Linear backoff: 1s, 2s, 3s, ...
77
+ * retryStrategy: (attempt) => (attempt + 1) * 1000
78
+ */
79
+ retryStrategy?: (attempt: number, baseDelayMs: number) => number;
70
80
  }
71
81
  /** Event hooks for logging, debugging, and monitoring. */
72
82
  interface AniListHooks {
@@ -79,7 +89,25 @@ interface AniListHooks {
79
89
  /** Called when a request is retried (429 or network error). */
80
90
  onRetry?: (attempt: number, reason: string, delayMs: number) => void;
81
91
  /** Called when a request completes. */
82
- onResponse?: (query: string, durationMs: number, fromCache: boolean) => void;
92
+ onResponse?: (query: string, durationMs: number, fromCache: boolean, rateLimitInfo?: RateLimitInfo) => void;
93
+ }
94
+ /** Rate limit information parsed from AniList API response headers. */
95
+ interface RateLimitInfo {
96
+ /** Maximum number of requests allowed per window. */
97
+ limit: number;
98
+ /** Remaining requests in the current window. */
99
+ remaining: number;
100
+ /** UNIX timestamp (seconds) when the rate limit window resets. */
101
+ reset: number;
102
+ }
103
+ /** Metadata about the last request, useful for debugging and monitoring. */
104
+ interface ResponseMeta {
105
+ /** Duration of the request in milliseconds. */
106
+ durationMs: number;
107
+ /** Whether the response was served from cache. */
108
+ fromCache: boolean;
109
+ /** Rate limit information from the API response headers (not present for cached responses). */
110
+ rateLimitInfo?: RateLimitInfo;
83
111
  }
84
112
  interface AniListClientOptions {
85
113
  /** Optional AniList OAuth token for authenticated requests */
@@ -94,6 +122,8 @@ interface AniListClientOptions {
94
122
  rateLimit?: RateLimitOptions;
95
123
  /** Event hooks for logging, debugging, and monitoring */
96
124
  hooks?: AniListHooks;
125
+ /** Optional AbortSignal to cancel all requests made by this client */
126
+ signal?: AbortSignal;
97
127
  }
98
128
 
99
129
  declare enum StaffSort {
@@ -409,6 +439,58 @@ interface SearchUserOptions {
409
439
  page?: number;
410
440
  perPage?: number;
411
441
  }
442
+ interface FavoriteMediaNode {
443
+ id: number;
444
+ title: {
445
+ romaji: string | null;
446
+ english: string | null;
447
+ native: string | null;
448
+ userPreferred: string | null;
449
+ };
450
+ coverImage: {
451
+ large: string | null;
452
+ medium: string | null;
453
+ };
454
+ type: string | null;
455
+ format: string | null;
456
+ siteUrl: string | null;
457
+ }
458
+ interface FavoriteCharacterNode {
459
+ id: number;
460
+ name: {
461
+ full: string | null;
462
+ native: string | null;
463
+ };
464
+ image: {
465
+ large: string | null;
466
+ medium: string | null;
467
+ };
468
+ siteUrl: string | null;
469
+ }
470
+ interface FavoriteStaffNode {
471
+ id: number;
472
+ name: {
473
+ full: string | null;
474
+ native: string | null;
475
+ };
476
+ image: {
477
+ large: string | null;
478
+ medium: string | null;
479
+ };
480
+ siteUrl: string | null;
481
+ }
482
+ interface FavoriteStudioNode {
483
+ id: number;
484
+ name: string;
485
+ siteUrl: string | null;
486
+ }
487
+ interface UserFavorites {
488
+ anime: FavoriteMediaNode[];
489
+ manga: FavoriteMediaNode[];
490
+ characters: FavoriteCharacterNode[];
491
+ staff: FavoriteStaffNode[];
492
+ studios: FavoriteStudioNode[];
493
+ }
412
494
 
413
495
  declare enum MediaType {
414
496
  ANIME = "ANIME",
@@ -877,8 +959,21 @@ declare class AniListClient {
877
959
  private readonly cacheAdapter;
878
960
  private readonly rateLimiter;
879
961
  private readonly hooks;
962
+ private readonly signal?;
880
963
  private readonly inFlight;
964
+ private _rateLimitInfo?;
965
+ private _lastRequestMeta?;
881
966
  constructor(options?: AniListClientOptions);
967
+ /**
968
+ * The current rate limit information from the last API response.
969
+ * Updated after every non-cached request.
970
+ */
971
+ get rateLimitInfo(): RateLimitInfo | undefined;
972
+ /**
973
+ * Metadata about the last request (duration, cache status, rate limit info).
974
+ * Useful for debugging and monitoring.
975
+ */
976
+ get lastRequestMeta(): ResponseMeta | undefined;
882
977
  /** @internal */
883
978
  request<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
884
979
  /** @internal */
@@ -937,6 +1032,19 @@ declare class AniListClient {
937
1032
  searchUsers(options?: SearchUserOptions): Promise<PagedResult<User>>;
938
1033
  /** Get a user's anime or manga list. */
939
1034
  getUserMediaList(options: GetUserMediaListOptions): Promise<PagedResult<MediaListEntry>>;
1035
+ /**
1036
+ * Fetch a user's favorite anime, manga, characters, staff, and studios.
1037
+ *
1038
+ * @param idOrName - AniList user ID (number) or username (string)
1039
+ * @returns The user's favorites grouped by category
1040
+ *
1041
+ * @example
1042
+ * ```typescript
1043
+ * const favs = await client.getUserFavorites("AniList");
1044
+ * favs.anime.forEach(a => console.log(a.title.romaji));
1045
+ * ```
1046
+ */
1047
+ getUserFavorites(idOrName: number | string): Promise<UserFavorites>;
940
1048
  /** Fetch a studio by its AniList ID. */
941
1049
  getStudio(id: number): Promise<Studio>;
942
1050
  /** Search for studios by name. */
@@ -1106,6 +1214,7 @@ declare class RateLimiter {
1106
1214
  private readonly enabled;
1107
1215
  private readonly timeoutMs;
1108
1216
  private readonly retryOnNetworkError;
1217
+ private readonly retryStrategy?;
1109
1218
  /** @internal — sliding window: circular buffer of timestamps */
1110
1219
  private readonly timestamps;
1111
1220
  private head;
@@ -1123,7 +1232,7 @@ declare class RateLimiter {
1123
1232
  onRetry?: (attempt: number, reason: string, delayMs: number) => void;
1124
1233
  onRateLimit?: (retryAfterMs: number) => void;
1125
1234
  }): Promise<Response>;
1126
- /** @internal — Exponential backoff with jitter, capped at 30s */
1235
+ /** @internal — Exponential backoff with jitter, capped at 30s (or custom strategy) */
1127
1236
  private exponentialDelay;
1128
1237
  /** @internal */
1129
1238
  private fetchWithTimeout;
@@ -1139,4 +1248,4 @@ declare class RateLimiter {
1139
1248
  */
1140
1249
  declare function parseAniListMarkdown(text: string): string;
1141
1250
 
1142
- 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 DayOfWeek, 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 SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
1251
+ 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 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 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 Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
package/dist/index.d.ts CHANGED
@@ -67,6 +67,16 @@ interface RateLimitOptions {
67
67
  timeoutMs?: number;
68
68
  /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
69
69
  retryOnNetworkError?: boolean;
70
+ /**
71
+ * Custom retry delay strategy. Receives the attempt number (0-based) and the base delay,
72
+ * and should return the delay in ms before retrying.
73
+ * When omitted, the default exponential backoff with jitter is used.
74
+ *
75
+ * @example
76
+ * // Linear backoff: 1s, 2s, 3s, ...
77
+ * retryStrategy: (attempt) => (attempt + 1) * 1000
78
+ */
79
+ retryStrategy?: (attempt: number, baseDelayMs: number) => number;
70
80
  }
71
81
  /** Event hooks for logging, debugging, and monitoring. */
72
82
  interface AniListHooks {
@@ -79,7 +89,25 @@ interface AniListHooks {
79
89
  /** Called when a request is retried (429 or network error). */
80
90
  onRetry?: (attempt: number, reason: string, delayMs: number) => void;
81
91
  /** Called when a request completes. */
82
- onResponse?: (query: string, durationMs: number, fromCache: boolean) => void;
92
+ onResponse?: (query: string, durationMs: number, fromCache: boolean, rateLimitInfo?: RateLimitInfo) => void;
93
+ }
94
+ /** Rate limit information parsed from AniList API response headers. */
95
+ interface RateLimitInfo {
96
+ /** Maximum number of requests allowed per window. */
97
+ limit: number;
98
+ /** Remaining requests in the current window. */
99
+ remaining: number;
100
+ /** UNIX timestamp (seconds) when the rate limit window resets. */
101
+ reset: number;
102
+ }
103
+ /** Metadata about the last request, useful for debugging and monitoring. */
104
+ interface ResponseMeta {
105
+ /** Duration of the request in milliseconds. */
106
+ durationMs: number;
107
+ /** Whether the response was served from cache. */
108
+ fromCache: boolean;
109
+ /** Rate limit information from the API response headers (not present for cached responses). */
110
+ rateLimitInfo?: RateLimitInfo;
83
111
  }
84
112
  interface AniListClientOptions {
85
113
  /** Optional AniList OAuth token for authenticated requests */
@@ -94,6 +122,8 @@ interface AniListClientOptions {
94
122
  rateLimit?: RateLimitOptions;
95
123
  /** Event hooks for logging, debugging, and monitoring */
96
124
  hooks?: AniListHooks;
125
+ /** Optional AbortSignal to cancel all requests made by this client */
126
+ signal?: AbortSignal;
97
127
  }
98
128
 
99
129
  declare enum StaffSort {
@@ -409,6 +439,58 @@ interface SearchUserOptions {
409
439
  page?: number;
410
440
  perPage?: number;
411
441
  }
442
+ interface FavoriteMediaNode {
443
+ id: number;
444
+ title: {
445
+ romaji: string | null;
446
+ english: string | null;
447
+ native: string | null;
448
+ userPreferred: string | null;
449
+ };
450
+ coverImage: {
451
+ large: string | null;
452
+ medium: string | null;
453
+ };
454
+ type: string | null;
455
+ format: string | null;
456
+ siteUrl: string | null;
457
+ }
458
+ interface FavoriteCharacterNode {
459
+ id: number;
460
+ name: {
461
+ full: string | null;
462
+ native: string | null;
463
+ };
464
+ image: {
465
+ large: string | null;
466
+ medium: string | null;
467
+ };
468
+ siteUrl: string | null;
469
+ }
470
+ interface FavoriteStaffNode {
471
+ id: number;
472
+ name: {
473
+ full: string | null;
474
+ native: string | null;
475
+ };
476
+ image: {
477
+ large: string | null;
478
+ medium: string | null;
479
+ };
480
+ siteUrl: string | null;
481
+ }
482
+ interface FavoriteStudioNode {
483
+ id: number;
484
+ name: string;
485
+ siteUrl: string | null;
486
+ }
487
+ interface UserFavorites {
488
+ anime: FavoriteMediaNode[];
489
+ manga: FavoriteMediaNode[];
490
+ characters: FavoriteCharacterNode[];
491
+ staff: FavoriteStaffNode[];
492
+ studios: FavoriteStudioNode[];
493
+ }
412
494
 
413
495
  declare enum MediaType {
414
496
  ANIME = "ANIME",
@@ -877,8 +959,21 @@ declare class AniListClient {
877
959
  private readonly cacheAdapter;
878
960
  private readonly rateLimiter;
879
961
  private readonly hooks;
962
+ private readonly signal?;
880
963
  private readonly inFlight;
964
+ private _rateLimitInfo?;
965
+ private _lastRequestMeta?;
881
966
  constructor(options?: AniListClientOptions);
967
+ /**
968
+ * The current rate limit information from the last API response.
969
+ * Updated after every non-cached request.
970
+ */
971
+ get rateLimitInfo(): RateLimitInfo | undefined;
972
+ /**
973
+ * Metadata about the last request (duration, cache status, rate limit info).
974
+ * Useful for debugging and monitoring.
975
+ */
976
+ get lastRequestMeta(): ResponseMeta | undefined;
882
977
  /** @internal */
883
978
  request<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
884
979
  /** @internal */
@@ -937,6 +1032,19 @@ declare class AniListClient {
937
1032
  searchUsers(options?: SearchUserOptions): Promise<PagedResult<User>>;
938
1033
  /** Get a user's anime or manga list. */
939
1034
  getUserMediaList(options: GetUserMediaListOptions): Promise<PagedResult<MediaListEntry>>;
1035
+ /**
1036
+ * Fetch a user's favorite anime, manga, characters, staff, and studios.
1037
+ *
1038
+ * @param idOrName - AniList user ID (number) or username (string)
1039
+ * @returns The user's favorites grouped by category
1040
+ *
1041
+ * @example
1042
+ * ```typescript
1043
+ * const favs = await client.getUserFavorites("AniList");
1044
+ * favs.anime.forEach(a => console.log(a.title.romaji));
1045
+ * ```
1046
+ */
1047
+ getUserFavorites(idOrName: number | string): Promise<UserFavorites>;
940
1048
  /** Fetch a studio by its AniList ID. */
941
1049
  getStudio(id: number): Promise<Studio>;
942
1050
  /** Search for studios by name. */
@@ -1106,6 +1214,7 @@ declare class RateLimiter {
1106
1214
  private readonly enabled;
1107
1215
  private readonly timeoutMs;
1108
1216
  private readonly retryOnNetworkError;
1217
+ private readonly retryStrategy?;
1109
1218
  /** @internal — sliding window: circular buffer of timestamps */
1110
1219
  private readonly timestamps;
1111
1220
  private head;
@@ -1123,7 +1232,7 @@ declare class RateLimiter {
1123
1232
  onRetry?: (attempt: number, reason: string, delayMs: number) => void;
1124
1233
  onRateLimit?: (retryAfterMs: number) => void;
1125
1234
  }): Promise<Response>;
1126
- /** @internal — Exponential backoff with jitter, capped at 30s */
1235
+ /** @internal — Exponential backoff with jitter, capped at 30s (or custom strategy) */
1127
1236
  private exponentialDelay;
1128
1237
  /** @internal */
1129
1238
  private fetchWithTimeout;
@@ -1139,4 +1248,4 @@ declare class RateLimiter {
1139
1248
  */
1140
1249
  declare function parseAniListMarkdown(text: string): string;
1141
1250
 
1142
- 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 DayOfWeek, 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 SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };
1251
+ 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 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 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 Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, type UserFavorites, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };