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/dist/index.mjs
CHANGED
|
@@ -133,6 +133,7 @@ var NormalizedCache = class {
|
|
|
133
133
|
_hits = 0;
|
|
134
134
|
_misses = 0;
|
|
135
135
|
_stales = 0;
|
|
136
|
+
gcTimeout;
|
|
136
137
|
constructor(options = {}) {
|
|
137
138
|
this.ttl = options.ttl ?? 24 * 60 * 60 * 1e3;
|
|
138
139
|
this.maxSize = options.maxSize ?? 500;
|
|
@@ -244,8 +245,10 @@ var NormalizedCache = class {
|
|
|
244
245
|
this.queryStore.delete(key);
|
|
245
246
|
if (this.maxSize > 0 && this.queryStore.size >= this.maxSize) {
|
|
246
247
|
const firstKey = this.queryStore.keys().next().value;
|
|
247
|
-
if (firstKey !== void 0)
|
|
248
|
-
|
|
248
|
+
if (firstKey !== void 0) {
|
|
249
|
+
this.queryStore.delete(firstKey);
|
|
250
|
+
}
|
|
251
|
+
this.scheduleGc();
|
|
249
252
|
}
|
|
250
253
|
this.queryStore.set(key, { data: normalizedData, expiresAt: Date.now() + this.ttl });
|
|
251
254
|
}
|
|
@@ -253,6 +256,10 @@ var NormalizedCache = class {
|
|
|
253
256
|
return this.queryStore.delete(key);
|
|
254
257
|
}
|
|
255
258
|
clear() {
|
|
259
|
+
if (this.gcTimeout) {
|
|
260
|
+
clearTimeout(this.gcTimeout);
|
|
261
|
+
this.gcTimeout = void 0;
|
|
262
|
+
}
|
|
256
263
|
this.queryStore.clear();
|
|
257
264
|
this.entityStore.clear();
|
|
258
265
|
this._hits = 0;
|
|
@@ -289,6 +296,16 @@ var NormalizedCache = class {
|
|
|
289
296
|
this._misses = 0;
|
|
290
297
|
this._stales = 0;
|
|
291
298
|
}
|
|
299
|
+
scheduleGc() {
|
|
300
|
+
if (this.gcTimeout) return;
|
|
301
|
+
this.gcTimeout = setTimeout(() => {
|
|
302
|
+
this.gc();
|
|
303
|
+
this.gcTimeout = void 0;
|
|
304
|
+
}, 500);
|
|
305
|
+
if (typeof this.gcTimeout.unref === "function") {
|
|
306
|
+
this.gcTimeout.unref();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
292
309
|
/**
|
|
293
310
|
* Garbage-collect orphaned entities that are no longer referenced by any query.
|
|
294
311
|
* Called automatically on LRU eviction to prevent unbounded entity store growth.
|
|
@@ -647,6 +664,7 @@ var RELATIONS_FIELDS = `
|
|
|
647
664
|
type
|
|
648
665
|
format
|
|
649
666
|
status
|
|
667
|
+
description(asHtml: false)
|
|
650
668
|
startDate { year month day }
|
|
651
669
|
endDate { year month day }
|
|
652
670
|
season
|
|
@@ -681,6 +699,8 @@ var MEDIA_RECOMMENDATION_FIELDS = `
|
|
|
681
699
|
title { romaji english native userPreferred }
|
|
682
700
|
type
|
|
683
701
|
format
|
|
702
|
+
status
|
|
703
|
+
description(asHtml: false)
|
|
684
704
|
coverImage { extraLarge large medium color }
|
|
685
705
|
averageScore
|
|
686
706
|
meanScore
|
|
@@ -1178,8 +1198,7 @@ query ($mediaId: Int!, $page: Int, $perPage: Int, $sort: [RecommendationSort]) {
|
|
|
1178
1198
|
}`;
|
|
1179
1199
|
|
|
1180
1200
|
// src/queries/builders.ts
|
|
1181
|
-
function
|
|
1182
|
-
if (!include) return QUERY_MEDIA_BY_ID;
|
|
1201
|
+
function buildMediaIncludeQuery(include) {
|
|
1183
1202
|
const extra = [];
|
|
1184
1203
|
if (include.relations !== false) {
|
|
1185
1204
|
extra.push(RELATIONS_FIELDS);
|
|
@@ -1254,14 +1273,172 @@ function buildMediaByIdQuery(include) {
|
|
|
1254
1273
|
statusDistribution { status amount }
|
|
1255
1274
|
}`);
|
|
1256
1275
|
}
|
|
1276
|
+
return extra;
|
|
1277
|
+
}
|
|
1278
|
+
function buildMediaByIdQuery(include) {
|
|
1279
|
+
if (!include) return QUERY_MEDIA_BY_ID;
|
|
1257
1280
|
return `
|
|
1258
1281
|
query ($id: Int!) {
|
|
1259
1282
|
Media(id: $id) {
|
|
1260
1283
|
${MEDIA_FIELDS_BASE}
|
|
1261
|
-
${
|
|
1284
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1262
1285
|
}
|
|
1263
1286
|
}`;
|
|
1264
1287
|
}
|
|
1288
|
+
function buildSearchMediaQuery(include) {
|
|
1289
|
+
if (!include) return QUERY_MEDIA_SEARCH;
|
|
1290
|
+
return `
|
|
1291
|
+
query (
|
|
1292
|
+
$search: String,
|
|
1293
|
+
$countryOfOrigin: CountryCode,
|
|
1294
|
+
$type: MediaType,
|
|
1295
|
+
$format: MediaFormat,
|
|
1296
|
+
$format_in: [MediaFormat],
|
|
1297
|
+
$status: MediaStatus,
|
|
1298
|
+
$season: MediaSeason,
|
|
1299
|
+
$seasonYear: Int,
|
|
1300
|
+
$genre: String,
|
|
1301
|
+
$tag: String,
|
|
1302
|
+
$genre_in: [String],
|
|
1303
|
+
$tag_in: [String],
|
|
1304
|
+
$genre_not_in: [String],
|
|
1305
|
+
$tag_not_in: [String],
|
|
1306
|
+
$isAdult: Boolean,
|
|
1307
|
+
$idNotIn: [Int],
|
|
1308
|
+
$sort: [MediaSort],
|
|
1309
|
+
$page: Int,
|
|
1310
|
+
$perPage: Int
|
|
1311
|
+
) {
|
|
1312
|
+
Page(page: $page, perPage: $perPage) {
|
|
1313
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1314
|
+
media(
|
|
1315
|
+
search: $search,
|
|
1316
|
+
countryOfOrigin: $countryOfOrigin,
|
|
1317
|
+
type: $type,
|
|
1318
|
+
format: $format,
|
|
1319
|
+
format_in: $format_in,
|
|
1320
|
+
status: $status,
|
|
1321
|
+
season: $season,
|
|
1322
|
+
seasonYear: $seasonYear,
|
|
1323
|
+
genre: $genre,
|
|
1324
|
+
tag: $tag,
|
|
1325
|
+
genre_in: $genre_in,
|
|
1326
|
+
tag_in: $tag_in,
|
|
1327
|
+
genre_not_in: $genre_not_in,
|
|
1328
|
+
tag_not_in: $tag_not_in,
|
|
1329
|
+
isAdult: $isAdult,
|
|
1330
|
+
id_not_in: $idNotIn,
|
|
1331
|
+
sort: $sort
|
|
1332
|
+
) {
|
|
1333
|
+
${MEDIA_FIELDS_BASE}
|
|
1334
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}`;
|
|
1338
|
+
}
|
|
1339
|
+
function buildGetTrendingQuery(include) {
|
|
1340
|
+
if (!include) return QUERY_TRENDING;
|
|
1341
|
+
return `
|
|
1342
|
+
query (
|
|
1343
|
+
$type: MediaType,
|
|
1344
|
+
$isAdult: Boolean,
|
|
1345
|
+
$idNotIn: [Int],
|
|
1346
|
+
$page: Int,
|
|
1347
|
+
$perPage: Int
|
|
1348
|
+
) {
|
|
1349
|
+
Page(page: $page, perPage: $perPage) {
|
|
1350
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1351
|
+
media(
|
|
1352
|
+
type: $type,
|
|
1353
|
+
isAdult: $isAdult,
|
|
1354
|
+
id_not_in: $idNotIn,
|
|
1355
|
+
sort: TRENDING_DESC
|
|
1356
|
+
) {
|
|
1357
|
+
${MEDIA_FIELDS_BASE}
|
|
1358
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
}`;
|
|
1362
|
+
}
|
|
1363
|
+
function buildGetMediaBySeasonQuery(include) {
|
|
1364
|
+
if (!include) return QUERY_MEDIA_BY_SEASON;
|
|
1365
|
+
return `
|
|
1366
|
+
query (
|
|
1367
|
+
$season: MediaSeason!,
|
|
1368
|
+
$seasonYear: Int!,
|
|
1369
|
+
$type: MediaType,
|
|
1370
|
+
$isAdult: Boolean,
|
|
1371
|
+
$idNotIn: [Int],
|
|
1372
|
+
$sort: [MediaSort],
|
|
1373
|
+
$page: Int,
|
|
1374
|
+
$perPage: Int
|
|
1375
|
+
) {
|
|
1376
|
+
Page(page: $page, perPage: $perPage) {
|
|
1377
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1378
|
+
media(
|
|
1379
|
+
season: $season,
|
|
1380
|
+
seasonYear: $seasonYear,
|
|
1381
|
+
type: $type,
|
|
1382
|
+
isAdult: $isAdult,
|
|
1383
|
+
id_not_in: $idNotIn,
|
|
1384
|
+
sort: $sort
|
|
1385
|
+
) {
|
|
1386
|
+
${MEDIA_FIELDS_BASE}
|
|
1387
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
}`;
|
|
1391
|
+
}
|
|
1392
|
+
function buildGetRecentlyUpdatedMangaQuery(include) {
|
|
1393
|
+
if (!include) return QUERY_RECENT_CHAPTERS;
|
|
1394
|
+
return `
|
|
1395
|
+
query (
|
|
1396
|
+
$isAdult: Boolean,
|
|
1397
|
+
$idNotIn: [Int],
|
|
1398
|
+
$page: Int,
|
|
1399
|
+
$perPage: Int
|
|
1400
|
+
) {
|
|
1401
|
+
Page(page: $page, perPage: $perPage) {
|
|
1402
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1403
|
+
media(
|
|
1404
|
+
type: MANGA,
|
|
1405
|
+
isAdult: $isAdult,
|
|
1406
|
+
id_not_in: $idNotIn,
|
|
1407
|
+
status: RELEASING,
|
|
1408
|
+
sort: UPDATED_AT_DESC
|
|
1409
|
+
) {
|
|
1410
|
+
${MEDIA_FIELDS_BASE}
|
|
1411
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
}`;
|
|
1415
|
+
}
|
|
1416
|
+
function buildGetPlanningQuery(include) {
|
|
1417
|
+
if (!include) return QUERY_PLANNING;
|
|
1418
|
+
return `
|
|
1419
|
+
query (
|
|
1420
|
+
$type: MediaType,
|
|
1421
|
+
$isAdult: Boolean,
|
|
1422
|
+
$idNotIn: [Int],
|
|
1423
|
+
$sort: [MediaSort],
|
|
1424
|
+
$page: Int,
|
|
1425
|
+
$perPage: Int
|
|
1426
|
+
) {
|
|
1427
|
+
Page(page: $page, perPage: $perPage) {
|
|
1428
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
1429
|
+
media(
|
|
1430
|
+
type: $type,
|
|
1431
|
+
isAdult: $isAdult,
|
|
1432
|
+
id_not_in: $idNotIn,
|
|
1433
|
+
status: NOT_YET_RELEASED,
|
|
1434
|
+
sort: $sort
|
|
1435
|
+
) {
|
|
1436
|
+
${MEDIA_FIELDS_BASE}
|
|
1437
|
+
${buildMediaIncludeQuery(include).join("\n")}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
}`;
|
|
1441
|
+
}
|
|
1265
1442
|
function buildMediaCharactersQuery(options = {}) {
|
|
1266
1443
|
const sortClause = options.sort === false ? "" : ", sort: [ROLE, RELEVANCE, ID]";
|
|
1267
1444
|
const voiceActorBlock = options.voiceActors ? `
|
|
@@ -2063,7 +2240,7 @@ async function getMediaByMalId(client, malId, type) {
|
|
|
2063
2240
|
});
|
|
2064
2241
|
return data.Media;
|
|
2065
2242
|
}
|
|
2066
|
-
async function searchMedia(client, options = {}) {
|
|
2243
|
+
async function searchMedia(client, options = {}, include) {
|
|
2067
2244
|
const {
|
|
2068
2245
|
query: search,
|
|
2069
2246
|
page = 1,
|
|
@@ -2075,8 +2252,9 @@ async function searchMedia(client, options = {}) {
|
|
|
2075
2252
|
format,
|
|
2076
2253
|
...filters
|
|
2077
2254
|
} = options;
|
|
2255
|
+
const query = buildSearchMediaQuery(include);
|
|
2078
2256
|
return client.pagedRequest(
|
|
2079
|
-
|
|
2257
|
+
query,
|
|
2080
2258
|
{
|
|
2081
2259
|
search,
|
|
2082
2260
|
...filters,
|
|
@@ -2092,21 +2270,18 @@ async function searchMedia(client, options = {}) {
|
|
|
2092
2270
|
"media"
|
|
2093
2271
|
);
|
|
2094
2272
|
}
|
|
2095
|
-
async function getTrending(client, options) {
|
|
2273
|
+
async function getTrending(client, options, include) {
|
|
2096
2274
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
{ type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) },
|
|
2100
|
-
"media"
|
|
2101
|
-
);
|
|
2275
|
+
const query = buildGetTrendingQuery(include);
|
|
2276
|
+
return client.pagedRequest(query, { type, isAdult, idNotIn, page, perPage: clampPerPage(perPage) }, "media");
|
|
2102
2277
|
}
|
|
2103
|
-
async function getPopular(client, options) {
|
|
2278
|
+
async function getPopular(client, options, include) {
|
|
2104
2279
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2105
|
-
return searchMedia(client, { type, isAdult, idNotIn, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage });
|
|
2280
|
+
return searchMedia(client, { type, isAdult, idNotIn, sort: ["POPULARITY_DESC" /* POPULARITY_DESC */], page, perPage }, include);
|
|
2106
2281
|
}
|
|
2107
|
-
async function getTopRated(client, options) {
|
|
2282
|
+
async function getTopRated(client, options, include) {
|
|
2108
2283
|
const { type = "ANIME" /* ANIME */, isAdult = false, idNotIn = [], page = 1, perPage = 20 } = options;
|
|
2109
|
-
return searchMedia(client, { type, isAdult, idNotIn, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage });
|
|
2284
|
+
return searchMedia(client, { type, isAdult, idNotIn, sort: ["SCORE_DESC" /* SCORE_DESC */], page, perPage }, include);
|
|
2110
2285
|
}
|
|
2111
2286
|
async function getAiredEpisodes(client, options = {}) {
|
|
2112
2287
|
const now = Math.floor(Date.now() / 1e3);
|
|
@@ -2123,9 +2298,10 @@ async function getAiredEpisodes(client, options = {}) {
|
|
|
2123
2298
|
"airingSchedules"
|
|
2124
2299
|
);
|
|
2125
2300
|
}
|
|
2126
|
-
async function getRecentlyUpdatedManga(client, options = {}) {
|
|
2301
|
+
async function getRecentlyUpdatedManga(client, options = {}, include) {
|
|
2302
|
+
const query = buildGetRecentlyUpdatedMangaQuery(include);
|
|
2127
2303
|
return client.pagedRequest(
|
|
2128
|
-
|
|
2304
|
+
query,
|
|
2129
2305
|
{
|
|
2130
2306
|
isAdult: options.isAdult ?? false,
|
|
2131
2307
|
idNotIn: options.idNotIn ?? [],
|
|
@@ -2135,9 +2311,10 @@ async function getRecentlyUpdatedManga(client, options = {}) {
|
|
|
2135
2311
|
"media"
|
|
2136
2312
|
);
|
|
2137
2313
|
}
|
|
2138
|
-
async function getPlanning(client, options = {}) {
|
|
2314
|
+
async function getPlanning(client, options = {}, include) {
|
|
2315
|
+
const query = buildGetPlanningQuery(include);
|
|
2139
2316
|
return client.pagedRequest(
|
|
2140
|
-
|
|
2317
|
+
query,
|
|
2141
2318
|
{
|
|
2142
2319
|
type: options.type,
|
|
2143
2320
|
isAdult: options.isAdult ?? false,
|
|
@@ -2162,9 +2339,10 @@ async function getRecommendations(client, mediaId, options = {}) {
|
|
|
2162
2339
|
results: data.Media.recommendations.nodes
|
|
2163
2340
|
};
|
|
2164
2341
|
}
|
|
2165
|
-
async function getMediaBySeason(client, options) {
|
|
2342
|
+
async function getMediaBySeason(client, options, include) {
|
|
2343
|
+
const query = buildGetMediaBySeasonQuery(include);
|
|
2166
2344
|
return client.pagedRequest(
|
|
2167
|
-
|
|
2345
|
+
query,
|
|
2168
2346
|
{
|
|
2169
2347
|
season: options.season,
|
|
2170
2348
|
seasonYear: options.seasonYear,
|
|
@@ -2361,7 +2539,7 @@ function mapFavorites(fav) {
|
|
|
2361
2539
|
|
|
2362
2540
|
// src/client/index.ts
|
|
2363
2541
|
var DEFAULT_API_URL = "https://graphql.anilist.co";
|
|
2364
|
-
var LIB_VERSION = "2.
|
|
2542
|
+
var LIB_VERSION = "2.2.0" ;
|
|
2365
2543
|
var AniListClient = class {
|
|
2366
2544
|
apiUrl;
|
|
2367
2545
|
headers;
|
|
@@ -2531,20 +2709,20 @@ var AniListClient = class {
|
|
|
2531
2709
|
* @param options - Search / filter parameters
|
|
2532
2710
|
* @returns Paginated results with matching media
|
|
2533
2711
|
*/
|
|
2534
|
-
async searchMedia(options = {}) {
|
|
2535
|
-
return searchMedia(this, options);
|
|
2712
|
+
async searchMedia(options = {}, include) {
|
|
2713
|
+
return searchMedia(this, options, include);
|
|
2536
2714
|
}
|
|
2537
2715
|
/** Get currently trending anime or manga. */
|
|
2538
|
-
async getTrending(options = {}) {
|
|
2539
|
-
return getTrending(this, options);
|
|
2716
|
+
async getTrending(options = {}, include) {
|
|
2717
|
+
return getTrending(this, options, include);
|
|
2540
2718
|
}
|
|
2541
2719
|
/** Get the most popular anime or manga. */
|
|
2542
|
-
async getPopular(options = {}) {
|
|
2543
|
-
return getPopular(this, options);
|
|
2720
|
+
async getPopular(options = {}, include) {
|
|
2721
|
+
return getPopular(this, options, include);
|
|
2544
2722
|
}
|
|
2545
2723
|
/** Get the highest-rated anime or manga. */
|
|
2546
|
-
async getTopRated(options = {}) {
|
|
2547
|
-
return getTopRated(this, options);
|
|
2724
|
+
async getTopRated(options = {}, include) {
|
|
2725
|
+
return getTopRated(this, options, include);
|
|
2548
2726
|
}
|
|
2549
2727
|
/** Get recently aired anime episodes. */
|
|
2550
2728
|
async getAiredEpisodes(options = {}) {
|
|
@@ -2555,14 +2733,8 @@ var AniListClient = class {
|
|
|
2555
2733
|
*
|
|
2556
2734
|
* @param options - Pagination parameters
|
|
2557
2735
|
*/
|
|
2558
|
-
async getRecentlyUpdatedManga(options = {}) {
|
|
2559
|
-
return getRecentlyUpdatedManga(this, options);
|
|
2560
|
-
}
|
|
2561
|
-
/**
|
|
2562
|
-
* @deprecated Use `getRecentlyUpdatedManga()` instead. This alias will be removed in v3.
|
|
2563
|
-
*/
|
|
2564
|
-
async getAiredChapters(options = {}) {
|
|
2565
|
-
return this.getRecentlyUpdatedManga(options);
|
|
2736
|
+
async getRecentlyUpdatedManga(options = {}, include) {
|
|
2737
|
+
return getRecentlyUpdatedManga(this, options, include);
|
|
2566
2738
|
}
|
|
2567
2739
|
/**
|
|
2568
2740
|
* Fetch a media entry by its MyAnimeList (MAL) ID.
|
|
@@ -2578,16 +2750,16 @@ var AniListClient = class {
|
|
|
2578
2750
|
return getWeeklySchedule(this, date, idNotIn);
|
|
2579
2751
|
}
|
|
2580
2752
|
/** Get upcoming (not yet released) media. */
|
|
2581
|
-
async getPlanning(options = {}) {
|
|
2582
|
-
return getPlanning(this, options);
|
|
2753
|
+
async getPlanning(options = {}, include) {
|
|
2754
|
+
return getPlanning(this, options, include);
|
|
2583
2755
|
}
|
|
2584
2756
|
/** Get recommendations for a specific media. */
|
|
2585
2757
|
async getRecommendations(mediaId, options = {}) {
|
|
2586
2758
|
return getRecommendations(this, mediaId, options);
|
|
2587
2759
|
}
|
|
2588
2760
|
/** Get anime (or manga) for a specific season and year. */
|
|
2589
|
-
async getMediaBySeason(options) {
|
|
2590
|
-
return getMediaBySeason(this, options);
|
|
2761
|
+
async getMediaBySeason(options, include) {
|
|
2762
|
+
return getMediaBySeason(this, options, include);
|
|
2591
2763
|
}
|
|
2592
2764
|
/** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
|
|
2593
2765
|
async getCharacter(id, include) {
|