ani-client 1.1.0 → 1.2.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/dist/index.d.ts CHANGED
@@ -101,6 +101,28 @@ interface Studio {
101
101
  interface StudioConnection {
102
102
  nodes: Studio[];
103
103
  }
104
+ declare enum MediaRelationType {
105
+ ADAPTATION = "ADAPTATION",
106
+ PREQUEL = "PREQUEL",
107
+ SEQUEL = "SEQUEL",
108
+ PARENT = "PARENT",
109
+ SIDE_STORY = "SIDE_STORY",
110
+ CHARACTER = "CHARACTER",
111
+ SUMMARY = "SUMMARY",
112
+ ALTERNATIVE = "ALTERNATIVE",
113
+ SPIN_OFF = "SPIN_OFF",
114
+ OTHER = "OTHER",
115
+ SOURCE = "SOURCE",
116
+ COMPILATION = "COMPILATION",
117
+ CONTAINS = "CONTAINS"
118
+ }
119
+ interface MediaEdge {
120
+ relationType: MediaRelationType;
121
+ node: Pick<Media, "id" | "title" | "type" | "format" | "status" | "coverImage" | "siteUrl">;
122
+ }
123
+ interface MediaConnection {
124
+ edges: MediaEdge[];
125
+ }
104
126
  interface CharacterName {
105
127
  first: string | null;
106
128
  middle: string | null;
@@ -145,6 +167,7 @@ interface Media {
145
167
  trending: number | null;
146
168
  tags: MediaTag[];
147
169
  studios: StudioConnection;
170
+ relations: MediaConnection | null;
148
171
  isAdult: boolean | null;
149
172
  siteUrl: string | null;
150
173
  }
@@ -260,6 +283,10 @@ interface SearchStaffOptions {
260
283
  page?: number;
261
284
  perPage?: number;
262
285
  }
286
+ interface PaginatedOptions {
287
+ page?: number;
288
+ perPage?: number;
289
+ }
263
290
  interface PagedResult<T> {
264
291
  pageInfo: PageInfo;
265
292
  results: T[];
@@ -288,6 +315,130 @@ interface GetPlanningOptions {
288
315
  page?: number;
289
316
  perPage?: number;
290
317
  }
318
+ declare enum RecommendationSort {
319
+ ID = "ID",
320
+ ID_DESC = "ID_DESC",
321
+ RATING = "RATING",
322
+ RATING_DESC = "RATING_DESC"
323
+ }
324
+ interface Recommendation {
325
+ id: number;
326
+ rating: number | null;
327
+ userRating: string | null;
328
+ mediaRecommendation: Media;
329
+ user: {
330
+ id: number;
331
+ name: string;
332
+ avatar: UserAvatar;
333
+ } | null;
334
+ }
335
+ interface GetRecommendationsOptions {
336
+ /** The AniList media ID to get recommendations for */
337
+ mediaId: number;
338
+ /** Sort order (default: RATING_DESC) */
339
+ sort?: RecommendationSort[];
340
+ page?: number;
341
+ perPage?: number;
342
+ }
343
+ declare enum MediaListStatus {
344
+ CURRENT = "CURRENT",
345
+ PLANNING = "PLANNING",
346
+ COMPLETED = "COMPLETED",
347
+ DROPPED = "DROPPED",
348
+ PAUSED = "PAUSED",
349
+ REPEATING = "REPEATING"
350
+ }
351
+ declare enum MediaListSort {
352
+ MEDIA_ID = "MEDIA_ID",
353
+ MEDIA_ID_DESC = "MEDIA_ID_DESC",
354
+ SCORE = "SCORE",
355
+ SCORE_DESC = "SCORE_DESC",
356
+ STATUS = "STATUS",
357
+ STATUS_DESC = "STATUS_DESC",
358
+ PROGRESS = "PROGRESS",
359
+ PROGRESS_DESC = "PROGRESS_DESC",
360
+ PROGRESS_VOLUMES = "PROGRESS_VOLUMES",
361
+ PROGRESS_VOLUMES_DESC = "PROGRESS_VOLUMES_DESC",
362
+ REPEAT = "REPEAT",
363
+ REPEAT_DESC = "REPEAT_DESC",
364
+ PRIORITY = "PRIORITY",
365
+ PRIORITY_DESC = "PRIORITY_DESC",
366
+ STARTED_ON = "STARTED_ON",
367
+ STARTED_ON_DESC = "STARTED_ON_DESC",
368
+ FINISHED_ON = "FINISHED_ON",
369
+ FINISHED_ON_DESC = "FINISHED_ON_DESC",
370
+ ADDED_TIME = "ADDED_TIME",
371
+ ADDED_TIME_DESC = "ADDED_TIME_DESC",
372
+ UPDATED_TIME = "UPDATED_TIME",
373
+ UPDATED_TIME_DESC = "UPDATED_TIME_DESC",
374
+ MEDIA_TITLE_ROMAJI = "MEDIA_TITLE_ROMAJI",
375
+ MEDIA_TITLE_ROMAJI_DESC = "MEDIA_TITLE_ROMAJI_DESC",
376
+ MEDIA_TITLE_ENGLISH = "MEDIA_TITLE_ENGLISH",
377
+ MEDIA_TITLE_ENGLISH_DESC = "MEDIA_TITLE_ENGLISH_DESC",
378
+ MEDIA_TITLE_NATIVE = "MEDIA_TITLE_NATIVE",
379
+ MEDIA_TITLE_NATIVE_DESC = "MEDIA_TITLE_NATIVE_DESC",
380
+ MEDIA_POPULARITY = "MEDIA_POPULARITY",
381
+ MEDIA_POPULARITY_DESC = "MEDIA_POPULARITY_DESC"
382
+ }
383
+ interface MediaListEntry {
384
+ id: number;
385
+ mediaId: number;
386
+ status: MediaListStatus;
387
+ score: number | null;
388
+ progress: number | null;
389
+ progressVolumes: number | null;
390
+ repeat: number | null;
391
+ priority: number | null;
392
+ private: boolean | null;
393
+ notes: string | null;
394
+ startedAt: FuzzyDate | null;
395
+ completedAt: FuzzyDate | null;
396
+ updatedAt: number | null;
397
+ createdAt: number | null;
398
+ media: Media;
399
+ }
400
+ interface GetSeasonOptions {
401
+ /** The season (WINTER, SPRING, SUMMER, FALL) */
402
+ season: MediaSeason;
403
+ /** The year */
404
+ seasonYear: number;
405
+ /** Filter by ANIME or MANGA (defaults to ANIME) */
406
+ type?: MediaType;
407
+ /** Sort order (default: POPULARITY_DESC) */
408
+ sort?: MediaSort[];
409
+ page?: number;
410
+ perPage?: number;
411
+ }
412
+ interface GetUserMediaListOptions {
413
+ /** User ID (provide either userId or userName) */
414
+ userId?: number;
415
+ /** Username (provide either userId or userName) */
416
+ userName?: string;
417
+ /** ANIME or MANGA */
418
+ type: MediaType;
419
+ /** Filter by list status (CURRENT, COMPLETED, etc.) */
420
+ status?: MediaListStatus;
421
+ /** Sort order */
422
+ sort?: MediaListSort[];
423
+ page?: number;
424
+ perPage?: number;
425
+ }
426
+ interface StudioDetail {
427
+ id: number;
428
+ name: string;
429
+ isAnimationStudio: boolean;
430
+ siteUrl: string | null;
431
+ favourites: number | null;
432
+ media: {
433
+ pageInfo: PageInfo;
434
+ nodes: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "siteUrl">[];
435
+ } | null;
436
+ }
437
+ interface SearchStudioOptions {
438
+ query?: string;
439
+ page?: number;
440
+ perPage?: number;
441
+ }
291
442
  interface AniListClientOptions {
292
443
  /** Optional AniList OAuth token for authenticated requests */
293
444
  token?: string;
@@ -455,6 +606,129 @@ declare class AniListClient {
455
606
  * ```
456
607
  */
457
608
  getPlanning(options?: GetPlanningOptions): Promise<PagedResult<Media>>;
609
+ /**
610
+ * Get recommendations for a specific media.
611
+ *
612
+ * Returns other anime/manga that users have recommended based on the given media.
613
+ *
614
+ * @param mediaId - The AniList media ID
615
+ * @param options - Optional sort / pagination parameters
616
+ * @returns Paginated list of recommendations
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * // Get recommendations for Cowboy Bebop
621
+ * const recs = await client.getRecommendations(1);
622
+ * recs.results.forEach((r) =>
623
+ * console.log(`${r.mediaRecommendation.title.romaji} (rating: ${r.rating})`)
624
+ * );
625
+ * ```
626
+ */
627
+ getRecommendations(mediaId: number, options?: Omit<GetRecommendationsOptions, "mediaId">): Promise<PagedResult<Recommendation>>;
628
+ /**
629
+ * Get anime (or manga) for a specific season and year.
630
+ *
631
+ * @param options - Season, year and optional filter / pagination parameters
632
+ * @returns Paginated list of media for the given season
633
+ *
634
+ * @example
635
+ * ```ts
636
+ * import { MediaSeason } from "ani-client";
637
+ *
638
+ * const winter2026 = await client.getMediaBySeason({
639
+ * season: MediaSeason.WINTER,
640
+ * seasonYear: 2026,
641
+ * perPage: 10,
642
+ * });
643
+ * ```
644
+ */
645
+ getMediaBySeason(options: GetSeasonOptions): Promise<PagedResult<Media>>;
646
+ /**
647
+ * Get a user's anime or manga list.
648
+ *
649
+ * Provide either `userId` or `userName` to identify the user.
650
+ * Requires `type` (ANIME or MANGA). Optionally filter by list status.
651
+ *
652
+ * @param options - User identifier, media type, and optional filters
653
+ * @returns Paginated list of media list entries
654
+ *
655
+ * @example
656
+ * ```ts
657
+ * import { MediaType, MediaListStatus } from "ani-client";
658
+ *
659
+ * // Get a user's completed anime list
660
+ * const list = await client.getUserMediaList({
661
+ * userName: "AniList",
662
+ * type: MediaType.ANIME,
663
+ * status: MediaListStatus.COMPLETED,
664
+ * });
665
+ * list.results.forEach((entry) =>
666
+ * console.log(`${entry.media.title.romaji} — ${entry.score}/100`)
667
+ * );
668
+ * ```
669
+ */
670
+ getUserMediaList(options: GetUserMediaListOptions): Promise<PagedResult<MediaListEntry>>;
671
+ /**
672
+ * Fetch a studio by its AniList ID.
673
+ *
674
+ * Returns studio details along with its most popular productions.
675
+ *
676
+ * @param id - The AniList studio ID
677
+ */
678
+ getStudio(id: number): Promise<StudioDetail>;
679
+ /**
680
+ * Search for studios by name.
681
+ *
682
+ * @param options - Search / pagination parameters
683
+ * @returns Paginated list of studios
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * const studios = await client.searchStudios({ query: "MAPPA" });
688
+ * ```
689
+ */
690
+ searchStudios(options?: SearchStudioOptions): Promise<PagedResult<StudioDetail>>;
691
+ /**
692
+ * Get all available genres on AniList.
693
+ *
694
+ * @returns Array of genre strings (e.g. "Action", "Adventure", ...)
695
+ */
696
+ getGenres(): Promise<string[]>;
697
+ /**
698
+ * Get all available media tags on AniList.
699
+ *
700
+ * @returns Array of tag objects with id, name, description, category, isAdult
701
+ */
702
+ getTags(): Promise<MediaTag[]>;
703
+ /**
704
+ * Auto-paginating async iterator.
705
+ *
706
+ * Wraps any paginated method and yields individual items across all pages.
707
+ * Stops when `hasNextPage` is `false` or `maxPages` is reached.
708
+ *
709
+ * @param fetchPage - A function that takes a page number and returns a `PagedResult<T>`
710
+ * @param maxPages - Maximum number of pages to fetch (default: Infinity)
711
+ * @returns An async iterable iterator of individual items
712
+ *
713
+ * @example
714
+ * ```ts
715
+ * // Iterate over all search results
716
+ * for await (const anime of client.paginate((page) =>
717
+ * client.searchMedia({ query: "Naruto", page, perPage: 10 })
718
+ * )) {
719
+ * console.log(anime.title.romaji);
720
+ * }
721
+ *
722
+ * // Limit to 3 pages
723
+ * for await (const anime of client.paginate(
724
+ * (page) => client.getTrending(MediaType.ANIME, page, 20),
725
+ * 3,
726
+ * )) {
727
+ * console.log(anime.title.romaji);
728
+ * }
729
+ * ```
730
+ */
731
+ paginate<T>(fetchPage: (page: number) => Promise<PagedResult<T>>, maxPages?: number): AsyncGenerator<T, void, undefined>;
458
732
  /**
459
733
  * Clear the entire response cache.
460
734
  */
@@ -547,4 +821,4 @@ declare class RateLimiter {
547
821
  private sleep;
548
822
  }
549
823
 
550
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type Media, type MediaCoverImage, MediaFormat, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type User, type UserAvatar, type UserStatistics };
824
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, 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 PaginatedOptions, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, 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 };