ani-client 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -29,21 +29,37 @@ declare enum MediaSeason {
29
29
  }
30
30
  declare enum MediaSort {
31
31
  ID = "ID",
32
+ ID_DESC = "ID_DESC",
32
33
  TITLE_ROMAJI = "TITLE_ROMAJI",
34
+ TITLE_ROMAJI_DESC = "TITLE_ROMAJI_DESC",
33
35
  TITLE_ENGLISH = "TITLE_ENGLISH",
36
+ TITLE_ENGLISH_DESC = "TITLE_ENGLISH_DESC",
34
37
  TITLE_NATIVE = "TITLE_NATIVE",
38
+ TITLE_NATIVE_DESC = "TITLE_NATIVE_DESC",
35
39
  TYPE = "TYPE",
40
+ TYPE_DESC = "TYPE_DESC",
36
41
  FORMAT = "FORMAT",
42
+ FORMAT_DESC = "FORMAT_DESC",
37
43
  START_DATE = "START_DATE",
44
+ START_DATE_DESC = "START_DATE_DESC",
38
45
  END_DATE = "END_DATE",
46
+ END_DATE_DESC = "END_DATE_DESC",
39
47
  SCORE = "SCORE",
48
+ SCORE_DESC = "SCORE_DESC",
40
49
  POPULARITY = "POPULARITY",
50
+ POPULARITY_DESC = "POPULARITY_DESC",
41
51
  TRENDING = "TRENDING",
52
+ TRENDING_DESC = "TRENDING_DESC",
42
53
  EPISODES = "EPISODES",
54
+ EPISODES_DESC = "EPISODES_DESC",
43
55
  DURATION = "DURATION",
56
+ DURATION_DESC = "DURATION_DESC",
44
57
  STATUS = "STATUS",
58
+ STATUS_DESC = "STATUS_DESC",
45
59
  FAVOURITES = "FAVOURITES",
60
+ FAVOURITES_DESC = "FAVOURITES_DESC",
46
61
  UPDATED_AT = "UPDATED_AT",
62
+ UPDATED_AT_DESC = "UPDATED_AT_DESC",
47
63
  SEARCH_MATCH = "SEARCH_MATCH"
48
64
  }
49
65
  declare enum AiringSort {
@@ -58,9 +74,17 @@ declare enum AiringSort {
58
74
  }
59
75
  declare enum CharacterSort {
60
76
  ID = "ID",
77
+ ID_DESC = "ID_DESC",
61
78
  ROLE = "ROLE",
79
+ ROLE_DESC = "ROLE_DESC",
62
80
  SEARCH_MATCH = "SEARCH_MATCH",
63
- FAVOURITES = "FAVOURITES"
81
+ FAVOURITES = "FAVOURITES",
82
+ FAVOURITES_DESC = "FAVOURITES_DESC"
83
+ }
84
+ declare enum CharacterRole {
85
+ MAIN = "MAIN",
86
+ SUPPORTING = "SUPPORTING",
87
+ BACKGROUND = "BACKGROUND"
64
88
  }
65
89
  interface MediaTitle {
66
90
  romaji: string | null;
@@ -135,6 +159,69 @@ interface CharacterImage {
135
159
  large: string | null;
136
160
  medium: string | null;
137
161
  }
162
+ /** Compact voice actor data returned inside character edges. */
163
+ interface VoiceActor {
164
+ id: number;
165
+ name: {
166
+ first: string | null;
167
+ middle: string | null;
168
+ last: string | null;
169
+ full: string | null;
170
+ native: string | null;
171
+ userPreferred: string | null;
172
+ };
173
+ languageV2: string | null;
174
+ image: StaffImage;
175
+ gender: string | null;
176
+ primaryOccupations: string[];
177
+ siteUrl: string | null;
178
+ }
179
+ interface MediaCharacterEdge {
180
+ role: CharacterRole;
181
+ node: Omit<Character, "media">;
182
+ voiceActors?: VoiceActor[];
183
+ }
184
+ interface MediaCharacterConnection {
185
+ edges: MediaCharacterEdge[];
186
+ }
187
+ interface MediaStaffEdge {
188
+ role: string;
189
+ node: Staff;
190
+ }
191
+ interface MediaStaffConnection {
192
+ edges: MediaStaffEdge[];
193
+ }
194
+ interface StreamingEpisode {
195
+ title: string | null;
196
+ thumbnail: string | null;
197
+ url: string | null;
198
+ site: string | null;
199
+ }
200
+ interface ExternalLink {
201
+ id: number;
202
+ url: string | null;
203
+ site: string;
204
+ type: string | null;
205
+ icon: string | null;
206
+ color: string | null;
207
+ }
208
+ interface ScoreDistribution {
209
+ score: number;
210
+ amount: number;
211
+ }
212
+ interface StatusDistribution {
213
+ status: MediaListStatus | string;
214
+ amount: number;
215
+ }
216
+ interface MediaStats {
217
+ scoreDistribution: ScoreDistribution[];
218
+ statusDistribution: StatusDistribution[];
219
+ }
220
+ interface MediaRecommendationNode {
221
+ id: number;
222
+ rating: number | null;
223
+ mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "siteUrl">;
224
+ }
138
225
  interface Media {
139
226
  id: number;
140
227
  idMal: number | null;
@@ -168,9 +255,22 @@ interface Media {
168
255
  tags: MediaTag[];
169
256
  studios: StudioConnection;
170
257
  relations: MediaConnection | null;
258
+ characters?: MediaCharacterConnection;
259
+ staff?: MediaStaffConnection;
260
+ streamingEpisodes?: StreamingEpisode[];
261
+ externalLinks?: ExternalLink[];
262
+ stats?: MediaStats;
263
+ recommendations?: {
264
+ nodes: MediaRecommendationNode[];
265
+ };
171
266
  isAdult: boolean | null;
172
267
  siteUrl: string | null;
173
268
  }
269
+ type CharacterMediaNode = Pick<Media, "id" | "title" | "type" | "coverImage" | "siteUrl">;
270
+ interface CharacterMediaEdge {
271
+ node: CharacterMediaNode;
272
+ voiceActors?: VoiceActor[];
273
+ }
174
274
  interface Character {
175
275
  id: number;
176
276
  name: CharacterName;
@@ -183,9 +283,15 @@ interface Character {
183
283
  favourites: number | null;
184
284
  siteUrl: string | null;
185
285
  media: {
186
- nodes: Pick<Media, "id" | "title" | "type" | "coverImage" | "siteUrl">[];
286
+ nodes?: CharacterMediaNode[];
287
+ edges?: CharacterMediaEdge[];
187
288
  } | null;
188
289
  }
290
+ /** Options for including extra data when fetching a character. */
291
+ interface CharacterIncludeOptions {
292
+ /** Include voice actors for each media the character appears in. */
293
+ voiceActors?: boolean;
294
+ }
189
295
  interface StaffName {
190
296
  first: string | null;
191
297
  middle: string | null;
@@ -207,7 +313,7 @@ interface Staff {
207
313
  gender: string | null;
208
314
  dateOfBirth: FuzzyDate | null;
209
315
  dateOfDeath: FuzzyDate | null;
210
- age: number | null;
316
+ age: string | null;
211
317
  yearsActive: number[];
212
318
  homeTown: string | null;
213
319
  bloodType: string | null;
@@ -277,9 +383,12 @@ interface SearchCharacterOptions {
277
383
  sort?: CharacterSort[];
278
384
  page?: number;
279
385
  perPage?: number;
386
+ /** Include voice actors for each media the character appears in. */
387
+ voiceActors?: boolean;
280
388
  }
281
389
  interface SearchStaffOptions {
282
390
  query?: string;
391
+ sort?: CharacterSort[];
283
392
  page?: number;
284
393
  perPage?: number;
285
394
  }
@@ -435,6 +544,37 @@ interface SearchStudioOptions {
435
544
  page?: number;
436
545
  perPage?: number;
437
546
  }
547
+ /**
548
+ * Options to include additional related data when fetching a media entry.
549
+ * Pass `true` to include with defaults, or an object to customize.
550
+ */
551
+ interface MediaIncludeOptions {
552
+ /** Include characters with their roles (MAIN, SUPPORTING, BACKGROUND).
553
+ * `true` = 25 results sorted by role. Object form to customize. */
554
+ characters?: boolean | {
555
+ perPage?: number;
556
+ sort?: boolean;
557
+ voiceActors?: boolean;
558
+ };
559
+ /** Include staff members with their roles.
560
+ * `true` = 25 results sorted by relevance. Object form to customize. */
561
+ staff?: boolean | {
562
+ perPage?: number;
563
+ sort?: boolean;
564
+ };
565
+ /** Include relations (default: `true` for backward compat). Set to `false` to exclude. */
566
+ relations?: boolean;
567
+ /** Include streaming episode links (Crunchyroll, Funimation, etc.) */
568
+ streamingEpisodes?: boolean;
569
+ /** Include external links (MAL, official site, etc.) */
570
+ externalLinks?: boolean;
571
+ /** Include score & status distribution stats */
572
+ stats?: boolean;
573
+ /** Include user recommendations. `true` = 10 results, or customize with `{ perPage }`. */
574
+ recommendations?: boolean | {
575
+ perPage?: number;
576
+ };
577
+ }
438
578
  /**
439
579
  * Interface that all cache adapters must implement.
440
580
  * Methods may return sync values or Promises — the client awaits all calls.
@@ -451,10 +591,36 @@ interface CacheAdapter {
451
591
  /** Number of entries currently stored (sync). Returns -1 if unknown. */
452
592
  readonly size: number;
453
593
  /** Return all cache keys. */
454
- keys(): IterableIterator<string> | string[] | Promise<string[]>;
594
+ keys(): string[] | Promise<string[]>;
455
595
  /** Bulk-remove entries matching a pattern. Optional — the client provides a fallback. */
456
596
  invalidate?(pattern: string | RegExp): number | Promise<number>;
457
597
  }
598
+ /** Cache configuration options. */
599
+ interface CacheOptions {
600
+ /** Time-to-live in milliseconds (default: 86 400 000 = 24h) */
601
+ ttl?: number;
602
+ /** Maximum number of cached entries (default: 500, 0 = unlimited) */
603
+ maxSize?: number;
604
+ /** Set to false to disable caching entirely */
605
+ enabled?: boolean;
606
+ }
607
+ /** Rate limiter configuration options. */
608
+ interface RateLimitOptions {
609
+ /** Max requests per window (default: 85) */
610
+ maxRequests?: number;
611
+ /** Window size in ms (default: 60 000) */
612
+ windowMs?: number;
613
+ /** Max retries on 429 (default: 3) */
614
+ maxRetries?: number;
615
+ /** Retry delay in ms when Retry-After header is absent (default: 2000) */
616
+ retryDelayMs?: number;
617
+ /** Set to false to disable rate limiting entirely */
618
+ enabled?: boolean;
619
+ /** Timeout per request in ms (default: 30 000). 0 = no timeout. */
620
+ timeoutMs?: number;
621
+ /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
622
+ retryOnNetworkError?: boolean;
623
+ }
458
624
  /** Event hooks for logging, debugging, and monitoring. */
459
625
  interface AniListHooks {
460
626
  /** Called before every API request. */
@@ -474,33 +640,11 @@ interface AniListClientOptions {
474
640
  /** Custom API endpoint (defaults to https://graphql.anilist.co) */
475
641
  apiUrl?: string;
476
642
  /** Cache configuration (enabled by default, 24h TTL) */
477
- cache?: {
478
- /** Time-to-live in milliseconds (default: 86 400 000 = 24h) */
479
- ttl?: number;
480
- /** Maximum number of cached entries (default: 500, 0 = unlimited) */
481
- maxSize?: number;
482
- /** Set to false to disable caching entirely */
483
- enabled?: boolean;
484
- };
643
+ cache?: CacheOptions;
485
644
  /** Custom cache adapter (e.g. RedisCache). Takes precedence over `cache`. */
486
645
  cacheAdapter?: CacheAdapter;
487
646
  /** Rate limiter configuration (enabled by default, 85 req/min) */
488
- rateLimit?: {
489
- /** Max requests per window (default: 85) */
490
- maxRequests?: number;
491
- /** Window size in ms (default: 60 000) */
492
- windowMs?: number;
493
- /** Max retries on 429 (default: 3) */
494
- maxRetries?: number;
495
- /** Retry delay in ms when Retry-After header is absent (default: 2000) */
496
- retryDelayMs?: number;
497
- /** Set to false to disable rate limiting entirely */
498
- enabled?: boolean;
499
- /** Timeout per request in ms (default: 30 000). 0 = no timeout. */
500
- timeoutMs?: number;
501
- /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
502
- retryOnNetworkError?: boolean;
503
- };
647
+ rateLimit?: RateLimitOptions;
504
648
  /** Event hooks for logging, debugging, and monitoring */
505
649
  hooks?: AniListHooks;
506
650
  }
@@ -542,13 +686,47 @@ declare class AniListClient {
542
686
  * Shorthand for paginated queries that follow the `Page { pageInfo, <field>[] }` pattern.
543
687
  */
544
688
  private pagedRequest;
689
+ /**
690
+ * @internal
691
+ * Clamp perPage to AniList's maximum of 50.
692
+ */
693
+ private clampPerPage;
545
694
  /**
546
695
  * Fetch a single media entry by its AniList ID.
547
696
  *
697
+ * Optionally include related data (characters, staff, relations, etc.) via the `include` parameter.
698
+ *
548
699
  * @param id - The AniList media ID
700
+ * @param include - Optional related data to include
549
701
  * @returns The media object
702
+ *
703
+ * @example
704
+ * ```ts
705
+ * // Basic usage — same as before (includes relations by default)
706
+ * const anime = await client.getMedia(1);
707
+ *
708
+ * // Include characters sorted by role, 25 results
709
+ * const anime = await client.getMedia(1, { characters: true });
710
+ *
711
+ * // Include characters with voice actors
712
+ * const anime = await client.getMedia(1, { characters: { voiceActors: true } });
713
+ *
714
+ * // Full control
715
+ * const anime = await client.getMedia(1, {
716
+ * characters: { perPage: 50, sort: true },
717
+ * staff: true,
718
+ * relations: true,
719
+ * streamingEpisodes: true,
720
+ * externalLinks: true,
721
+ * stats: true,
722
+ * recommendations: { perPage: 5 },
723
+ * });
724
+ *
725
+ * // Exclude relations for a lighter response
726
+ * const anime = await client.getMedia(1, { characters: true, relations: false });
727
+ * ```
550
728
  */
551
- getMedia(id: number): Promise<Media>;
729
+ getMedia(id: number, include?: MediaIncludeOptions): Promise<Media>;
552
730
  /**
553
731
  * Search for anime or manga.
554
732
  *
@@ -575,26 +753,89 @@ declare class AniListClient {
575
753
  getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
576
754
  /**
577
755
  * Fetch a character by AniList ID.
756
+ *
757
+ * @param id - The AniList character ID
758
+ * @param include - Optional include options (e.g. voice actors)
759
+ * @returns The character object
760
+ *
761
+ * @example
762
+ * ```ts
763
+ * const spike = await client.getCharacter(1);
764
+ * console.log(spike.name.full); // "Spike Spiegel"
765
+ *
766
+ * // With voice actors
767
+ * const spike = await client.getCharacter(1, { voiceActors: true });
768
+ * spike.media?.edges?.forEach((e) => {
769
+ * console.log(e.node.title.romaji);
770
+ * e.voiceActors?.forEach((va) => console.log(` VA: ${va.name.full}`));
771
+ * });
772
+ * ```
578
773
  */
579
- getCharacter(id: number): Promise<Character>;
774
+ getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character>;
580
775
  /**
581
776
  * Search for characters by name.
777
+ *
778
+ * @param options - Search / pagination parameters (includes optional `voiceActors`)
779
+ * @returns Paginated results with matching characters
780
+ *
781
+ * @example
782
+ * ```ts
783
+ * const result = await client.searchCharacters({ query: "Luffy", perPage: 5 });
784
+ *
785
+ * // With voice actors
786
+ * const result = await client.searchCharacters({ query: "Luffy", voiceActors: true });
787
+ * ```
582
788
  */
583
789
  searchCharacters(options?: SearchCharacterOptions): Promise<PagedResult<Character>>;
584
790
  /**
585
791
  * Fetch a staff member by AniList ID.
792
+ *
793
+ * @param id - The AniList staff ID
794
+ * @returns The staff object
795
+ *
796
+ * @example
797
+ * ```ts
798
+ * const staff = await client.getStaff(95001);
799
+ * console.log(staff.name.full);
800
+ * ```
586
801
  */
587
802
  getStaff(id: number): Promise<Staff>;
588
803
  /**
589
804
  * Search for staff (voice actors, directors, etc.).
805
+ *
806
+ * @param options - Search / pagination parameters
807
+ * @returns Paginated results with matching staff
808
+ *
809
+ * @example
810
+ * ```ts
811
+ * const result = await client.searchStaff({ query: "Miyazaki", perPage: 5 });
812
+ * ```
590
813
  */
591
814
  searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
592
815
  /**
593
816
  * Fetch a user by AniList ID.
817
+ *
818
+ * @param id - The AniList user ID
819
+ * @returns The user object
820
+ *
821
+ * @example
822
+ * ```ts
823
+ * const user = await client.getUser(1);
824
+ * console.log(user.name);
825
+ * ```
594
826
  */
595
827
  getUser(id: number): Promise<User>;
596
828
  /**
597
829
  * Fetch a user by username.
830
+ *
831
+ * @param name - The AniList username
832
+ * @returns The user object
833
+ *
834
+ * @example
835
+ * ```ts
836
+ * const user = await client.getUserByName("AniList");
837
+ * console.log(user.statistics);
838
+ * ```
598
839
  */
599
840
  getUserByName(name: string): Promise<User>;
600
841
  /**
@@ -830,18 +1071,6 @@ declare class AniListError extends Error {
830
1071
  constructor(message: string, status: number, errors?: unknown[]);
831
1072
  }
832
1073
 
833
- /**
834
- * Simple in-memory cache with configurable TTL.
835
- * Used internally by AniListClient to avoid redundant API calls.
836
- */
837
- interface CacheOptions {
838
- /** Time-to-live in milliseconds (default: 24 hours) */
839
- ttl?: number;
840
- /** Maximum number of entries to keep (default: 500, 0 = unlimited) */
841
- maxSize?: number;
842
- /** Disable caching entirely (default: false) */
843
- enabled?: boolean;
844
- }
845
1074
  declare class MemoryCache implements CacheAdapter {
846
1075
  private readonly ttl;
847
1076
  private readonly maxSize;
@@ -860,8 +1089,8 @@ declare class MemoryCache implements CacheAdapter {
860
1089
  clear(): void;
861
1090
  /** Number of entries currently stored. */
862
1091
  get size(): number;
863
- /** Return an iterator over all cache keys. */
864
- keys(): IterableIterator<string>;
1092
+ /** Return all cache keys. */
1093
+ keys(): string[];
865
1094
  /**
866
1095
  * Remove all entries whose key matches the given pattern.
867
1096
  *
@@ -880,6 +1109,11 @@ interface RedisLikeClient {
880
1109
  set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
881
1110
  del(...keys: (string | string[])[]): Promise<number>;
882
1111
  keys(pattern: string): Promise<string[]>;
1112
+ /** Optional SCAN-based iteration — used when available to avoid blocking the server. */
1113
+ scanIterator?(options: {
1114
+ MATCH: string;
1115
+ COUNT?: number;
1116
+ }): AsyncIterable<string>;
883
1117
  }
884
1118
  interface RedisCacheOptions {
885
1119
  /** A Redis client instance (ioredis or node-redis). */
@@ -912,6 +1146,14 @@ declare class RedisCache implements CacheAdapter {
912
1146
  get<T>(key: string): Promise<T | undefined>;
913
1147
  set<T>(key: string, data: T): Promise<void>;
914
1148
  delete(key: string): Promise<boolean>;
1149
+ /**
1150
+ * Collect keys matching a pattern. Uses SCAN when available, falls back to KEYS.
1151
+ *
1152
+ * **Warning:** The `KEYS` fallback is O(N) and blocks the Redis server.
1153
+ * Provide a client with `scanIterator` support for production use.
1154
+ * @internal
1155
+ */
1156
+ private collectKeys;
915
1157
  clear(): Promise<void>;
916
1158
  /**
917
1159
  * Returns -1 because Redis keys can expire silently via TTL.
@@ -927,7 +1169,7 @@ declare class RedisCache implements CacheAdapter {
927
1169
  * @param pattern — A glob pattern (e.g. `"*Media*"`)
928
1170
  * @returns Number of entries removed.
929
1171
  */
930
- invalidate(pattern: string): Promise<number>;
1172
+ invalidate(pattern: string | RegExp): Promise<number>;
931
1173
  }
932
1174
 
933
1175
  /**
@@ -937,22 +1179,7 @@ declare class RedisCache implements CacheAdapter {
937
1179
  * When a 429 (Too Many Requests) is received, the client
938
1180
  * waits for the Retry-After header and retries automatically.
939
1181
  */
940
- interface RateLimitOptions {
941
- /** Max requests per window (default: 85, conservative under AniList's 90/min) */
942
- maxRequests?: number;
943
- /** Window size in milliseconds (default: 60 000 = 1 minute) */
944
- windowMs?: number;
945
- /** Max number of retries on 429 responses (default: 3) */
946
- maxRetries?: number;
947
- /** Default retry delay in ms when Retry-After header is missing (default: 2000) */
948
- retryDelayMs?: number;
949
- /** Disable rate limiting entirely (default: false) */
950
- enabled?: boolean;
951
- /** Timeout per request in milliseconds (default: 30 000). 0 = no timeout. */
952
- timeoutMs?: number;
953
- /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
954
- retryOnNetworkError?: boolean;
955
- }
1182
+
956
1183
  declare class RateLimiter {
957
1184
  private readonly maxRequests;
958
1185
  private readonly windowMs;
@@ -980,4 +1207,4 @@ declare class RateLimiter {
980
1207
  private sleep;
981
1208
  }
982
1209
 
983
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, 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 SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
1210
+ 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 StaffName, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics, type VoiceActor };