ani-client 2.1.3 → 2.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/README.md +3 -1
- package/dist/index.d.mts +30 -15
- package/dist/index.d.ts +30 -15
- package/dist/index.js +216 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +216 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
> A fully typed, zero-dependency client for the [AniList](https://anilist.co) GraphQL API.
|
|
11
11
|
> Supports Node.js, Bun, Deno, and modern browsers.
|
|
12
12
|
|
|
13
|
+
> 📌 **Note** – thanks for **1K+ downloads** this month on `npm` 🎉
|
|
14
|
+
|
|
13
15
|
## Features
|
|
14
16
|
|
|
15
17
|
- **Zero dependencies** — uses the native `fetch` API
|
|
@@ -246,4 +248,4 @@ This repository also includes GitHub issue templates and a pull request template
|
|
|
246
248
|
|
|
247
249
|
## License
|
|
248
250
|
|
|
249
|
-
[MIT](LICENSE) © [gonzyui](https://github.com/gonzyui)
|
|
251
|
+
[MIT](LICENSE) © [gonzyui](https://github.com/gonzyui)
|
package/dist/index.d.mts
CHANGED
|
@@ -449,7 +449,7 @@ declare enum MediaRelationType {
|
|
|
449
449
|
}
|
|
450
450
|
interface MediaEdge {
|
|
451
451
|
relationType: MediaRelationType;
|
|
452
|
-
node: Pick<Media, "id" | "title" | "type" | "format" | "status" | "startDate" | "endDate" | "season" | "seasonYear" | "episodes" | "chapters" | "volumes" | "coverImage" | "genres" | "averageScore" | "meanScore" | "studios" | "siteUrl" | "nextAiringEpisode">;
|
|
452
|
+
node: Pick<Media, "id" | "title" | "type" | "format" | "status" | "description" | "startDate" | "endDate" | "season" | "seasonYear" | "episodes" | "chapters" | "volumes" | "coverImage" | "genres" | "averageScore" | "meanScore" | "studios" | "siteUrl" | "nextAiringEpisode">;
|
|
453
453
|
}
|
|
454
454
|
interface MediaConnection {
|
|
455
455
|
edges: MediaEdge[];
|
|
@@ -490,7 +490,7 @@ interface MediaStats {
|
|
|
490
490
|
interface MediaRecommendationNode {
|
|
491
491
|
id: number;
|
|
492
492
|
rating: number | null;
|
|
493
|
-
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "meanScore" | "episodes" | "chapters" | "volumes" | "nextAiringEpisode" | "season" | "seasonYear" | "startDate" | "endDate" | "studios" | "genres" | "siteUrl">;
|
|
493
|
+
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "status" | "description" | "coverImage" | "averageScore" | "meanScore" | "episodes" | "chapters" | "volumes" | "nextAiringEpisode" | "season" | "seasonYear" | "startDate" | "endDate" | "studios" | "genres" | "siteUrl">;
|
|
494
494
|
}
|
|
495
495
|
interface NextAiringEpisode {
|
|
496
496
|
id: number;
|
|
@@ -934,6 +934,7 @@ declare class NormalizedCache implements CacheAdapter {
|
|
|
934
934
|
private _hits;
|
|
935
935
|
private _misses;
|
|
936
936
|
private _stales;
|
|
937
|
+
private gcTimeout?;
|
|
937
938
|
constructor(options?: CacheOptions);
|
|
938
939
|
static key(query: string, variables: Record<string, unknown>): string;
|
|
939
940
|
/** Normalizes a GraphQL response, extracting entities and returning a tree of references. */
|
|
@@ -955,6 +956,7 @@ declare class NormalizedCache implements CacheAdapter {
|
|
|
955
956
|
entitiesCount: number;
|
|
956
957
|
};
|
|
957
958
|
resetStats(): void;
|
|
959
|
+
private scheduleGc;
|
|
958
960
|
/**
|
|
959
961
|
* Garbage-collect orphaned entities that are no longer referenced by any query.
|
|
960
962
|
* Called automatically on LRU eviction to prevent unbounded entity store growth.
|
|
@@ -1106,13 +1108,13 @@ declare class AniListClient implements ClientBase {
|
|
|
1106
1108
|
* @param options - Search / filter parameters
|
|
1107
1109
|
* @returns Paginated results with matching media
|
|
1108
1110
|
*/
|
|
1109
|
-
searchMedia(options?: SearchMediaOptions): Promise<PagedResult<Media>>;
|
|
1111
|
+
searchMedia(options?: SearchMediaOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1110
1112
|
/** Get currently trending anime or manga. */
|
|
1111
|
-
getTrending(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1113
|
+
getTrending(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1112
1114
|
/** Get the most popular anime or manga. */
|
|
1113
|
-
getPopular(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1115
|
+
getPopular(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1114
1116
|
/** Get the highest-rated anime or manga. */
|
|
1115
|
-
getTopRated(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1117
|
+
getTopRated(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1116
1118
|
/** Get recently aired anime episodes. */
|
|
1117
1119
|
getAiredEpisodes(options?: GetAiringOptions): Promise<PagedResult<AiringSchedule>>;
|
|
1118
1120
|
/**
|
|
@@ -1120,11 +1122,7 @@ declare class AniListClient implements ClientBase {
|
|
|
1120
1122
|
*
|
|
1121
1123
|
* @param options - Pagination parameters
|
|
1122
1124
|
*/
|
|
1123
|
-
getRecentlyUpdatedManga(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
|
|
1124
|
-
/**
|
|
1125
|
-
* @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
|
|
1126
|
-
*/
|
|
1127
|
-
getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
|
|
1125
|
+
getRecentlyUpdatedManga(options?: GetRecentChaptersOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1128
1126
|
/**
|
|
1129
1127
|
* Fetch a media entry by its MyAnimeList (MAL) ID.
|
|
1130
1128
|
*
|
|
@@ -1135,11 +1133,11 @@ declare class AniListClient implements ClientBase {
|
|
|
1135
1133
|
/** Get the detailed schedule for the current week, sorted by day. */
|
|
1136
1134
|
getWeeklySchedule(date?: Date, idNotIn?: number[]): Promise<WeeklySchedule>;
|
|
1137
1135
|
/** Get upcoming (not yet released) media. */
|
|
1138
|
-
getPlanning(options?: GetPlanningOptions): Promise<PagedResult<Media>>;
|
|
1136
|
+
getPlanning(options?: GetPlanningOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1139
1137
|
/** Get recommendations for a specific media. */
|
|
1140
1138
|
getRecommendations(mediaId: number, options?: Omit<GetRecommendationsOptions, "mediaId">): Promise<PagedResult<Recommendation>>;
|
|
1141
1139
|
/** Get anime (or manga) for a specific season and year. */
|
|
1142
|
-
getMediaBySeason(options: GetSeasonOptions): Promise<PagedResult<Media>>;
|
|
1140
|
+
getMediaBySeason(options: GetSeasonOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1143
1141
|
/** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
|
|
1144
1142
|
getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character>;
|
|
1145
1143
|
/** Search for characters by name. */
|
|
@@ -1249,6 +1247,23 @@ declare class AniListClient implements ClientBase {
|
|
|
1249
1247
|
withSignal(signal: AbortSignal): AniListClient;
|
|
1250
1248
|
}
|
|
1251
1249
|
|
|
1250
|
+
/**
|
|
1251
|
+
* Represents a location in a GraphQL query where an error occurred.
|
|
1252
|
+
*/
|
|
1253
|
+
interface GraphQLErrorLocation {
|
|
1254
|
+
line: number;
|
|
1255
|
+
column: number;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Standard GraphQL error shape.
|
|
1259
|
+
*/
|
|
1260
|
+
interface GraphQLError {
|
|
1261
|
+
message: string;
|
|
1262
|
+
locations?: GraphQLErrorLocation[];
|
|
1263
|
+
path?: (string | number)[];
|
|
1264
|
+
extensions?: Record<string, unknown>;
|
|
1265
|
+
[key: string]: unknown;
|
|
1266
|
+
}
|
|
1252
1267
|
/**
|
|
1253
1268
|
* Custom error class for AniList API errors.
|
|
1254
1269
|
*/
|
|
@@ -1256,8 +1271,8 @@ declare class AniListError extends Error {
|
|
|
1256
1271
|
/** HTTP status code returned by the API */
|
|
1257
1272
|
readonly status: number;
|
|
1258
1273
|
/** Raw error body from the API response */
|
|
1259
|
-
readonly errors:
|
|
1260
|
-
constructor(message: string, status: number, errors?: unknown[]);
|
|
1274
|
+
readonly errors: GraphQLError[];
|
|
1275
|
+
constructor(message: string, status: number, errors?: GraphQLError[] | unknown[]);
|
|
1261
1276
|
}
|
|
1262
1277
|
|
|
1263
1278
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -449,7 +449,7 @@ declare enum MediaRelationType {
|
|
|
449
449
|
}
|
|
450
450
|
interface MediaEdge {
|
|
451
451
|
relationType: MediaRelationType;
|
|
452
|
-
node: Pick<Media, "id" | "title" | "type" | "format" | "status" | "startDate" | "endDate" | "season" | "seasonYear" | "episodes" | "chapters" | "volumes" | "coverImage" | "genres" | "averageScore" | "meanScore" | "studios" | "siteUrl" | "nextAiringEpisode">;
|
|
452
|
+
node: Pick<Media, "id" | "title" | "type" | "format" | "status" | "description" | "startDate" | "endDate" | "season" | "seasonYear" | "episodes" | "chapters" | "volumes" | "coverImage" | "genres" | "averageScore" | "meanScore" | "studios" | "siteUrl" | "nextAiringEpisode">;
|
|
453
453
|
}
|
|
454
454
|
interface MediaConnection {
|
|
455
455
|
edges: MediaEdge[];
|
|
@@ -490,7 +490,7 @@ interface MediaStats {
|
|
|
490
490
|
interface MediaRecommendationNode {
|
|
491
491
|
id: number;
|
|
492
492
|
rating: number | null;
|
|
493
|
-
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "meanScore" | "episodes" | "chapters" | "volumes" | "nextAiringEpisode" | "season" | "seasonYear" | "startDate" | "endDate" | "studios" | "genres" | "siteUrl">;
|
|
493
|
+
mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "status" | "description" | "coverImage" | "averageScore" | "meanScore" | "episodes" | "chapters" | "volumes" | "nextAiringEpisode" | "season" | "seasonYear" | "startDate" | "endDate" | "studios" | "genres" | "siteUrl">;
|
|
494
494
|
}
|
|
495
495
|
interface NextAiringEpisode {
|
|
496
496
|
id: number;
|
|
@@ -934,6 +934,7 @@ declare class NormalizedCache implements CacheAdapter {
|
|
|
934
934
|
private _hits;
|
|
935
935
|
private _misses;
|
|
936
936
|
private _stales;
|
|
937
|
+
private gcTimeout?;
|
|
937
938
|
constructor(options?: CacheOptions);
|
|
938
939
|
static key(query: string, variables: Record<string, unknown>): string;
|
|
939
940
|
/** Normalizes a GraphQL response, extracting entities and returning a tree of references. */
|
|
@@ -955,6 +956,7 @@ declare class NormalizedCache implements CacheAdapter {
|
|
|
955
956
|
entitiesCount: number;
|
|
956
957
|
};
|
|
957
958
|
resetStats(): void;
|
|
959
|
+
private scheduleGc;
|
|
958
960
|
/**
|
|
959
961
|
* Garbage-collect orphaned entities that are no longer referenced by any query.
|
|
960
962
|
* Called automatically on LRU eviction to prevent unbounded entity store growth.
|
|
@@ -1106,13 +1108,13 @@ declare class AniListClient implements ClientBase {
|
|
|
1106
1108
|
* @param options - Search / filter parameters
|
|
1107
1109
|
* @returns Paginated results with matching media
|
|
1108
1110
|
*/
|
|
1109
|
-
searchMedia(options?: SearchMediaOptions): Promise<PagedResult<Media>>;
|
|
1111
|
+
searchMedia(options?: SearchMediaOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1110
1112
|
/** Get currently trending anime or manga. */
|
|
1111
|
-
getTrending(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1113
|
+
getTrending(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1112
1114
|
/** Get the most popular anime or manga. */
|
|
1113
|
-
getPopular(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1115
|
+
getPopular(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1114
1116
|
/** Get the highest-rated anime or manga. */
|
|
1115
|
-
getTopRated(options?: GeneralMediaQueryOptions): Promise<PagedResult<Media>>;
|
|
1117
|
+
getTopRated(options?: GeneralMediaQueryOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1116
1118
|
/** Get recently aired anime episodes. */
|
|
1117
1119
|
getAiredEpisodes(options?: GetAiringOptions): Promise<PagedResult<AiringSchedule>>;
|
|
1118
1120
|
/**
|
|
@@ -1120,11 +1122,7 @@ declare class AniListClient implements ClientBase {
|
|
|
1120
1122
|
*
|
|
1121
1123
|
* @param options - Pagination parameters
|
|
1122
1124
|
*/
|
|
1123
|
-
getRecentlyUpdatedManga(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
|
|
1124
|
-
/**
|
|
1125
|
-
* @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
|
|
1126
|
-
*/
|
|
1127
|
-
getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
|
|
1125
|
+
getRecentlyUpdatedManga(options?: GetRecentChaptersOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1128
1126
|
/**
|
|
1129
1127
|
* Fetch a media entry by its MyAnimeList (MAL) ID.
|
|
1130
1128
|
*
|
|
@@ -1135,11 +1133,11 @@ declare class AniListClient implements ClientBase {
|
|
|
1135
1133
|
/** Get the detailed schedule for the current week, sorted by day. */
|
|
1136
1134
|
getWeeklySchedule(date?: Date, idNotIn?: number[]): Promise<WeeklySchedule>;
|
|
1137
1135
|
/** Get upcoming (not yet released) media. */
|
|
1138
|
-
getPlanning(options?: GetPlanningOptions): Promise<PagedResult<Media>>;
|
|
1136
|
+
getPlanning(options?: GetPlanningOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1139
1137
|
/** Get recommendations for a specific media. */
|
|
1140
1138
|
getRecommendations(mediaId: number, options?: Omit<GetRecommendationsOptions, "mediaId">): Promise<PagedResult<Recommendation>>;
|
|
1141
1139
|
/** Get anime (or manga) for a specific season and year. */
|
|
1142
|
-
getMediaBySeason(options: GetSeasonOptions): Promise<PagedResult<Media>>;
|
|
1140
|
+
getMediaBySeason(options: GetSeasonOptions, include?: MediaIncludeOptions): Promise<PagedResult<Media>>;
|
|
1143
1141
|
/** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
|
|
1144
1142
|
getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character>;
|
|
1145
1143
|
/** Search for characters by name. */
|
|
@@ -1249,6 +1247,23 @@ declare class AniListClient implements ClientBase {
|
|
|
1249
1247
|
withSignal(signal: AbortSignal): AniListClient;
|
|
1250
1248
|
}
|
|
1251
1249
|
|
|
1250
|
+
/**
|
|
1251
|
+
* Represents a location in a GraphQL query where an error occurred.
|
|
1252
|
+
*/
|
|
1253
|
+
interface GraphQLErrorLocation {
|
|
1254
|
+
line: number;
|
|
1255
|
+
column: number;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Standard GraphQL error shape.
|
|
1259
|
+
*/
|
|
1260
|
+
interface GraphQLError {
|
|
1261
|
+
message: string;
|
|
1262
|
+
locations?: GraphQLErrorLocation[];
|
|
1263
|
+
path?: (string | number)[];
|
|
1264
|
+
extensions?: Record<string, unknown>;
|
|
1265
|
+
[key: string]: unknown;
|
|
1266
|
+
}
|
|
1252
1267
|
/**
|
|
1253
1268
|
* Custom error class for AniList API errors.
|
|
1254
1269
|
*/
|
|
@@ -1256,8 +1271,8 @@ declare class AniListError extends Error {
|
|
|
1256
1271
|
/** HTTP status code returned by the API */
|
|
1257
1272
|
readonly status: number;
|
|
1258
1273
|
/** Raw error body from the API response */
|
|
1259
|
-
readonly errors:
|
|
1260
|
-
constructor(message: string, status: number, errors?: unknown[]);
|
|
1274
|
+
readonly errors: GraphQLError[];
|
|
1275
|
+
constructor(message: string, status: number, errors?: GraphQLError[] | unknown[]);
|
|
1261
1276
|
}
|
|
1262
1277
|
|
|
1263
1278
|
/**
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,7 @@ var NormalizedCache = class {
|
|
|
135
135
|
_hits = 0;
|
|
136
136
|
_misses = 0;
|
|
137
137
|
_stales = 0;
|
|
138
|
+
gcTimeout;
|
|
138
139
|
constructor(options = {}) {
|
|
139
140
|
this.ttl = options.ttl ?? 24 * 60 * 60 * 1e3;
|
|
140
141
|
this.maxSize = options.maxSize ?? 500;
|
|
@@ -246,8 +247,10 @@ var NormalizedCache = class {
|
|
|
246
247
|
this.queryStore.delete(key);
|
|
247
248
|
if (this.maxSize > 0 && this.queryStore.size >= this.maxSize) {
|
|
248
249
|
const firstKey = this.queryStore.keys().next().value;
|
|
249
|
-
if (firstKey !== void 0)
|
|
250
|
-
|
|
250
|
+
if (firstKey !== void 0) {
|
|
251
|
+
this.queryStore.delete(firstKey);
|
|
252
|
+
}
|
|
253
|
+
this.scheduleGc();
|
|
251
254
|
}
|
|
252
255
|
this.queryStore.set(key, { data: normalizedData, expiresAt: Date.now() + this.ttl });
|
|
253
256
|
}
|
|
@@ -255,6 +258,10 @@ var NormalizedCache = class {
|
|
|
255
258
|
return this.queryStore.delete(key);
|
|
256
259
|
}
|
|
257
260
|
clear() {
|
|
261
|
+
if (this.gcTimeout) {
|
|
262
|
+
clearTimeout(this.gcTimeout);
|
|
263
|
+
this.gcTimeout = void 0;
|
|
264
|
+
}
|
|
258
265
|
this.queryStore.clear();
|
|
259
266
|
this.entityStore.clear();
|
|
260
267
|
this._hits = 0;
|
|
@@ -291,6 +298,16 @@ var NormalizedCache = class {
|
|
|
291
298
|
this._misses = 0;
|
|
292
299
|
this._stales = 0;
|
|
293
300
|
}
|
|
301
|
+
scheduleGc() {
|
|
302
|
+
if (this.gcTimeout) return;
|
|
303
|
+
this.gcTimeout = setTimeout(() => {
|
|
304
|
+
this.gc();
|
|
305
|
+
this.gcTimeout = void 0;
|
|
306
|
+
}, 500);
|
|
307
|
+
if (typeof this.gcTimeout.unref === "function") {
|
|
308
|
+
this.gcTimeout.unref();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
294
311
|
/**
|
|
295
312
|
* Garbage-collect orphaned entities that are no longer referenced by any query.
|
|
296
313
|
* Called automatically on LRU eviction to prevent unbounded entity store growth.
|
|
@@ -649,6 +666,7 @@ var RELATIONS_FIELDS = `
|
|
|
649
666
|
type
|
|
650
667
|
format
|
|
651
668
|
status
|
|
669
|
+
description(asHtml: false)
|
|
652
670
|
startDate { year month day }
|
|
653
671
|
endDate { year month day }
|
|
654
672
|
season
|
|
@@ -683,6 +701,8 @@ var MEDIA_RECOMMENDATION_FIELDS = `
|
|
|
683
701
|
title { romaji english native userPreferred }
|
|
684
702
|
type
|
|
685
703
|
format
|
|
704
|
+
status
|
|
705
|
+
description(asHtml: false)
|
|
686
706
|
coverImage { extraLarge large medium color }
|
|
687
707
|
averageScore
|
|
688
708
|
meanScore
|
|
@@ -1180,8 +1200,7 @@ query ($mediaId: Int!, $page: Int, $perPage: Int, $sort: [RecommendationSort]) {
|
|
|
1180
1200
|
}`;
|
|
1181
1201
|
|
|
1182
1202
|
// src/queries/builders.ts
|
|
1183
|
-
function
|
|
1184
|
-
if (!include) return QUERY_MEDIA_BY_ID;
|
|
1203
|
+
function buildMediaIncludeQuery(include) {
|
|
1185
1204
|
const extra = [];
|
|
1186
1205
|
if (include.relations !== false) {
|
|
1187
1206
|
extra.push(RELATIONS_FIELDS);
|
|
@@ -1256,14 +1275,172 @@ function buildMediaByIdQuery(include) {
|
|
|
1256
1275
|
statusDistribution { status amount }
|
|
1257
1276
|
}`);
|
|
1258
1277
|
}
|
|
1278
|
+
return extra;
|
|
1279
|
+
}
|
|
1280
|
+
function buildMediaByIdQuery(include) {
|
|
1281
|
+
if (!include) return QUERY_MEDIA_BY_ID;
|
|
1259
1282
|
return `
|
|
1260
1283
|
query ($id: Int!) {
|
|
1261
1284
|
Media(id: $id) {
|
|
1262
1285
|
${MEDIA_FIELDS_BASE}
|
|
1263
|
-
${
|
|
1286
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1264
1287
|
}
|
|
1265
1288
|
}`;
|
|
1266
1289
|
}
|
|
1290
|
+
function buildSearchMediaQuery(include) {
|
|
1291
|
+
if (!include) return QUERY_MEDIA_SEARCH;
|
|
1292
|
+
return `
|
|
1293
|
+
query (
|
|
1294
|
+
$search: String,
|
|
1295
|
+
$countryOfOrigin: CountryCode,
|
|
1296
|
+
$type: MediaType,
|
|
1297
|
+
$format: MediaFormat,
|
|
1298
|
+
$format_in: [MediaFormat],
|
|
1299
|
+
$status: MediaStatus,
|
|
1300
|
+
$season: MediaSeason,
|
|
1301
|
+
$seasonYear: Int,
|
|
1302
|
+
$genre: String,
|
|
1303
|
+
$tag: String,
|
|
1304
|
+
$genre_in: [String],
|
|
1305
|
+
$tag_in: [String],
|
|
1306
|
+
$genre_not_in: [String],
|
|
1307
|
+
$tag_not_in: [String],
|
|
1308
|
+
$isAdult: Boolean,
|
|
1309
|
+
$idNotIn: [Int],
|
|
1310
|
+
$sort: [MediaSort],
|
|
1311
|
+
$page: Int,
|
|
1312
|
+
$perPage: Int
|
|
1313
|
+
) {
|
|
1314
|
+
Page(page: $page, perPage: $perPage) {
|
|
1315
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1316
|
+
media(
|
|
1317
|
+
search: $search,
|
|
1318
|
+
countryOfOrigin: $countryOfOrigin,
|
|
1319
|
+
type: $type,
|
|
1320
|
+
format: $format,
|
|
1321
|
+
format_in: $format_in,
|
|
1322
|
+
status: $status,
|
|
1323
|
+
season: $season,
|
|
1324
|
+
seasonYear: $seasonYear,
|
|
1325
|
+
genre: $genre,
|
|
1326
|
+
tag: $tag,
|
|
1327
|
+
genre_in: $genre_in,
|
|
1328
|
+
tag_in: $tag_in,
|
|
1329
|
+
genre_not_in: $genre_not_in,
|
|
1330
|
+
tag_not_in: $tag_not_in,
|
|
1331
|
+
isAdult: $isAdult,
|
|
1332
|
+
id_not_in: $idNotIn,
|
|
1333
|
+
sort: $sort
|
|
1334
|
+
) {
|
|
1335
|
+
${MEDIA_FIELDS_BASE}
|
|
1336
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}`;
|
|
1340
|
+
}
|
|
1341
|
+
function buildGetTrendingQuery(include) {
|
|
1342
|
+
if (!include) return QUERY_TRENDING;
|
|
1343
|
+
return `
|
|
1344
|
+
query (
|
|
1345
|
+
$type: MediaType,
|
|
1346
|
+
$isAdult: Boolean,
|
|
1347
|
+
$idNotIn: [Int],
|
|
1348
|
+
$page: Int,
|
|
1349
|
+
$perPage: Int
|
|
1350
|
+
) {
|
|
1351
|
+
Page(page: $page, perPage: $perPage) {
|
|
1352
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1353
|
+
media(
|
|
1354
|
+
type: $type,
|
|
1355
|
+
isAdult: $isAdult,
|
|
1356
|
+
id_not_in: $idNotIn,
|
|
1357
|
+
sort: TRENDING_DESC
|
|
1358
|
+
) {
|
|
1359
|
+
${MEDIA_FIELDS_BASE}
|
|
1360
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
}`;
|
|
1364
|
+
}
|
|
1365
|
+
function buildGetMediaBySeasonQuery(include) {
|
|
1366
|
+
if (!include) return QUERY_MEDIA_BY_SEASON;
|
|
1367
|
+
return `
|
|
1368
|
+
query (
|
|
1369
|
+
$season: MediaSeason!,
|
|
1370
|
+
$seasonYear: Int!,
|
|
1371
|
+
$type: MediaType,
|
|
1372
|
+
$isAdult: Boolean,
|
|
1373
|
+
$idNotIn: [Int],
|
|
1374
|
+
$sort: [MediaSort],
|
|
1375
|
+
$page: Int,
|
|
1376
|
+
$perPage: Int
|
|
1377
|
+
) {
|
|
1378
|
+
Page(page: $page, perPage: $perPage) {
|
|
1379
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1380
|
+
media(
|
|
1381
|
+
season: $season,
|
|
1382
|
+
seasonYear: $seasonYear,
|
|
1383
|
+
type: $type,
|
|
1384
|
+
isAdult: $isAdult,
|
|
1385
|
+
id_not_in: $idNotIn,
|
|
1386
|
+
sort: $sort
|
|
1387
|
+
) {
|
|
1388
|
+
${MEDIA_FIELDS_BASE}
|
|
1389
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
}`;
|
|
1393
|
+
}
|
|
1394
|
+
function buildGetRecentlyUpdatedMangaQuery(include) {
|
|
1395
|
+
if (!include) return QUERY_RECENT_CHAPTERS;
|
|
1396
|
+
return `
|
|
1397
|
+
query (
|
|
1398
|
+
$isAdult: Boolean,
|
|
1399
|
+
$idNotIn: [Int],
|
|
1400
|
+
$page: Int,
|
|
1401
|
+
$perPage: Int
|
|
1402
|
+
) {
|
|
1403
|
+
Page(page: $page, perPage: $perPage) {
|
|
1404
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1405
|
+
media(
|
|
1406
|
+
type: MANGA,
|
|
1407
|
+
isAdult: $isAdult,
|
|
1408
|
+
id_not_in: $idNotIn,
|
|
1409
|
+
status: RELEASING,
|
|
1410
|
+
sort: UPDATED_AT_DESC
|
|
1411
|
+
) {
|
|
1412
|
+
${MEDIA_FIELDS_BASE}
|
|
1413
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
}`;
|
|
1417
|
+
}
|
|
1418
|
+
function buildGetPlanningQuery(include) {
|
|
1419
|
+
if (!include) return QUERY_PLANNING;
|
|
1420
|
+
return `
|
|
1421
|
+
query (
|
|
1422
|
+
$type: MediaType,
|
|
1423
|
+
$isAdult: Boolean,
|
|
1424
|
+
$idNotIn: [Int],
|
|
1425
|
+
$sort: [MediaSort],
|
|
1426
|
+
$page: Int,
|
|
1427
|
+
$perPage: Int
|
|
1428
|
+
) {
|
|
1429
|
+
Page(page: $page, perPage: $perPage) {
|
|
1430
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1431
|
+
media(
|
|
1432
|
+
type: $type,
|
|
1433
|
+
isAdult: $isAdult,
|
|
1434
|
+
id_not_in: $idNotIn,
|
|
1435
|
+
status: NOT_YET_RELEASED,
|
|
1436
|
+
sort: $sort
|
|
1437
|
+
) {
|
|
1438
|
+
${MEDIA_FIELDS_BASE}
|
|
1439
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
}`;
|
|
1443
|
+
}
|
|
1267
1444
|
function buildMediaCharactersQuery(options = {}) {
|
|
1268
1445
|
const sortClause = options.sort === false ? "" : ", sort: [ROLE, RELEVANCE, ID]";
|
|
1269
1446
|
const voiceActorBlock = options.voiceActors ? `
|
|
@@ -2065,7 +2242,7 @@ async function getMediaByMalId(client, malId, type) {
|
|
|
2065
2242
|
});
|
|
2066
2243
|
return data.Media;
|
|
2067
2244
|
}
|
|
2068
|
-
async function searchMedia(client, options = {}) {
|
|
2245
|
+
async function searchMedia(client, options = {}, include) {
|
|
2069
2246
|
const {
|
|
2070
2247
|
query: search,
|
|
2071
2248
|
page = 1,
|
|
@@ -2077,8 +2254,9 @@ async function searchMedia(client, options = {}) {
|
|
|
2077
2254
|
format,
|
|
2078
2255
|
...filters
|
|
2079
2256
|
} = options;
|
|
2257
|
+
const query = buildSearchMediaQuery(include);
|
|
2080
2258
|
return client.pagedRequest(
|
|
2081
|
-
|
|
2259
|
+
query,
|
|
2082
2260
|
{
|
|
2083
2261
|
search,
|
|
2084
2262
|
...filters,
|
|
@@ -2094,21 +2272,18 @@ async function searchMedia(client, options = {}) {
|
|
|
2094
2272
|
"media"
|
|
2095
2273
|
);
|
|
2096
2274
|
}
|
|
2097
|
-
async function getTrending(client, options) {
|
|
2275
|
+
async function getTrending(client, options, include) {
|
|
2098
2276
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
{ type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) },
|
|
2102
|
-
"media"
|
|
2103
|
-
);
|
|
2277
|
+
const query = buildGetTrendingQuery(include);
|
|
2278
|
+
return client.pagedRequest(query, { type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) }, "media");
|
|
2104
2279
|
}
|
|
2105
|
-
async function getPopular(client, options) {
|
|
2280
|
+
async function getPopular(client, options, include) {
|
|
2106
2281
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2107
|
-
return searchMedia(client, { type, isAdult, idNotIn, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
|
|
2282
|
+
return searchMedia(client, { type, isAdult, idNotIn, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage }, include);
|
|
2108
2283
|
}
|
|
2109
|
-
async function getTopRated(client, options) {
|
|
2284
|
+
async function getTopRated(client, options, include) {
|
|
2110
2285
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2111
|
-
return searchMedia(client, { type, isAdult, idNotIn, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
|
|
2286
|
+
return searchMedia(client, { type, isAdult, idNotIn, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage }, include);
|
|
2112
2287
|
}
|
|
2113
2288
|
async function getAiredEpisodes(client, options = {}) {
|
|
2114
2289
|
const now = Math.floor(Date.now() / 1e3);
|
|
@@ -2125,9 +2300,10 @@ async function getAiredEpisodes(client, options = {}) {
|
|
|
2125
2300
|
"airingSchedules"
|
|
2126
2301
|
);
|
|
2127
2302
|
}
|
|
2128
|
-
async function getRecentlyUpdatedManga(client, options = {}) {
|
|
2303
|
+
async function getRecentlyUpdatedManga(client, options = {}, include) {
|
|
2304
|
+
const query = buildGetRecentlyUpdatedMangaQuery(include);
|
|
2129
2305
|
return client.pagedRequest(
|
|
2130
|
-
|
|
2306
|
+
query,
|
|
2131
2307
|
{
|
|
2132
2308
|
isAdult: options.isAdult ?? false,
|
|
2133
2309
|
idNotIn: options.idNotIn ?? [],
|
|
@@ -2137,9 +2313,10 @@ async function getRecentlyUpdatedManga(client, options = {}) {
|
|
|
2137
2313
|
"media"
|
|
2138
2314
|
);
|
|
2139
2315
|
}
|
|
2140
|
-
async function getPlanning(client, options = {}) {
|
|
2316
|
+
async function getPlanning(client, options = {}, include) {
|
|
2317
|
+
const query = buildGetPlanningQuery(include);
|
|
2141
2318
|
return client.pagedRequest(
|
|
2142
|
-
|
|
2319
|
+
query,
|
|
2143
2320
|
{
|
|
2144
2321
|
type: options.type,
|
|
2145
2322
|
isAdult: options.isAdult ?? false,
|
|
@@ -2164,9 +2341,10 @@ async function getRecommendations(client, mediaId, options = {}) {
|
|
|
2164
2341
|
results: data.Media.recommendations.nodes
|
|
2165
2342
|
};
|
|
2166
2343
|
}
|
|
2167
|
-
async function getMediaBySeason(client, options) {
|
|
2344
|
+
async function getMediaBySeason(client, options, include) {
|
|
2345
|
+
const query = buildGetMediaBySeasonQuery(include);
|
|
2168
2346
|
return client.pagedRequest(
|
|
2169
|
-
|
|
2347
|
+
query,
|
|
2170
2348
|
{
|
|
2171
2349
|
season: options.season,
|
|
2172
2350
|
seasonYear: options.seasonYear,
|
|
@@ -2363,7 +2541,7 @@ function mapFavorites(fav) {
|
|
|
2363
2541
|
|
|
2364
2542
|
// src/client/index.ts
|
|
2365
2543
|
var DEFAULT_API_URL = "https://graphql.anilist.co";
|
|
2366
|
-
var LIB_VERSION = "2.
|
|
2544
|
+
var LIB_VERSION = "2.2.0" ;
|
|
2367
2545
|
var AniListClient = class {
|
|
2368
2546
|
apiUrl;
|
|
2369
2547
|
headers;
|
|
@@ -2533,20 +2711,20 @@ var AniListClient = class {
|
|
|
2533
2711
|
* @param options - Search / filter parameters
|
|
2534
2712
|
* @returns Paginated results with matching media
|
|
2535
2713
|
*/
|
|
2536
|
-
async searchMedia(options = {}) {
|
|
2537
|
-
return searchMedia(this, options);
|
|
2714
|
+
async searchMedia(options = {}, include) {
|
|
2715
|
+
return searchMedia(this, options, include);
|
|
2538
2716
|
}
|
|
2539
2717
|
/** Get currently trending anime or manga. */
|
|
2540
|
-
async getTrending(options = {}) {
|
|
2541
|
-
return getTrending(this, options);
|
|
2718
|
+
async getTrending(options = {}, include) {
|
|
2719
|
+
return getTrending(this, options, include);
|
|
2542
2720
|
}
|
|
2543
2721
|
/** Get the most popular anime or manga. */
|
|
2544
|
-
async getPopular(options = {}) {
|
|
2545
|
-
return getPopular(this, options);
|
|
2722
|
+
async getPopular(options = {}, include) {
|
|
2723
|
+
return getPopular(this, options, include);
|
|
2546
2724
|
}
|
|
2547
2725
|
/** Get the highest-rated anime or manga. */
|
|
2548
|
-
async getTopRated(options = {}) {
|
|
2549
|
-
return getTopRated(this, options);
|
|
2726
|
+
async getTopRated(options = {}, include) {
|
|
2727
|
+
return getTopRated(this, options, include);
|
|
2550
2728
|
}
|
|
2551
2729
|
/** Get recently aired anime episodes. */
|
|
2552
2730
|
async getAiredEpisodes(options = {}) {
|
|
@@ -2557,14 +2735,8 @@ var AniListClient = class {
|
|
|
2557
2735
|
*
|
|
2558
2736
|
* @param options - Pagination parameters
|
|
2559
2737
|
*/
|
|
2560
|
-
async getRecentlyUpdatedManga(options = {}) {
|
|
2561
|
-
return getRecentlyUpdatedManga(this, options);
|
|
2562
|
-
}
|
|
2563
|
-
/**
|
|
2564
|
-
* @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
|
|
2565
|
-
*/
|
|
2566
|
-
async getAiredChapters(options = {}) {
|
|
2567
|
-
return this.getRecentlyUpdatedManga(options);
|
|
2738
|
+
async getRecentlyUpdatedManga(options = {}, include) {
|
|
2739
|
+
return getRecentlyUpdatedManga(this, options, include);
|
|
2568
2740
|
}
|
|
2569
2741
|
/**
|
|
2570
2742
|
* Fetch a media entry by its MyAnimeList (MAL) ID.
|
|
@@ -2580,16 +2752,16 @@ var AniListClient = class {
|
|
|
2580
2752
|
return getWeeklySchedule(this, date, idNotIn);
|
|
2581
2753
|
}
|
|
2582
2754
|
/** Get upcoming (not yet released) media. */
|
|
2583
|
-
async getPlanning(options = {}) {
|
|
2584
|
-
return getPlanning(this, options);
|
|
2755
|
+
async getPlanning(options = {}, include) {
|
|
2756
|
+
return getPlanning(this, options, include);
|
|
2585
2757
|
}
|
|
2586
2758
|
/** Get recommendations for a specific media. */
|
|
2587
2759
|
async getRecommendations(mediaId, options = {}) {
|
|
2588
2760
|
return getRecommendations(this, mediaId, options);
|
|
2589
2761
|
}
|
|
2590
2762
|
/** Get anime (or manga) for a specific season and year. */
|
|
2591
|
-
async getMediaBySeason(options) {
|
|
2592
|
-
return getMediaBySeason(this, options);
|
|
2763
|
+
async getMediaBySeason(options, include) {
|
|
2764
|
+
return getMediaBySeason(this, options, include);
|
|
2593
2765
|
}
|
|
2594
2766
|
/** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
|
|
2595
2767
|
async getCharacter(id, include) {
|