@irfanshadikrishad/anilist 1.2.3 → 1.2.5
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/LICENSE +115 -124
- package/README.md +23 -20
- package/bin/helpers/auth.d.ts +35 -6
- package/bin/helpers/auth.js +49 -55
- package/bin/helpers/fetcher.d.ts +1 -1
- package/bin/helpers/lists.d.ts +5 -2
- package/bin/helpers/lists.js +181 -142
- package/bin/helpers/queries.d.ts +5 -3
- package/bin/helpers/queries.js +17 -3
- package/bin/helpers/types.d.ts +231 -8
- package/bin/helpers/workers.d.ts +6 -4
- package/bin/helpers/workers.js +60 -2
- package/bin/index.js +2 -2
- package/package.json +8 -7
package/bin/helpers/lists.js
CHANGED
|
@@ -10,14 +10,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { XMLParser } from "fast-xml-parser";
|
|
11
11
|
import { readFile, writeFile } from "fs/promises";
|
|
12
12
|
import inquirer from "inquirer";
|
|
13
|
-
import
|
|
13
|
+
import { jsonrepair } from "jsonrepair";
|
|
14
|
+
import open from "open";
|
|
14
15
|
import { join } from "path";
|
|
15
16
|
import { Auth } from "./auth.js";
|
|
16
17
|
import { fetcher } from "./fetcher.js";
|
|
17
18
|
import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
|
|
18
|
-
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, } from "./queries.js";
|
|
19
|
+
import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
|
|
19
20
|
import { AniListMediaStatus, } from "./types.js";
|
|
20
|
-
import {
|
|
21
|
+
import { anidbToanilistMapper, createAnimeListXML, createMangaListXML, formatDateObject, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, timestampToTimeAgo, } from "./workers.js";
|
|
21
22
|
class AniList {
|
|
22
23
|
static importAnime() {
|
|
23
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -122,7 +123,7 @@ class AniList {
|
|
|
122
123
|
choices: [
|
|
123
124
|
{ name: "CSV", value: 1 },
|
|
124
125
|
{ name: "JSON", value: 2 },
|
|
125
|
-
{ name: "XML (MyAnimeList)", value: 3 },
|
|
126
|
+
{ name: "XML (MyAnimeList/AniDB)", value: 3 },
|
|
126
127
|
],
|
|
127
128
|
pageSize: 10,
|
|
128
129
|
},
|
|
@@ -237,7 +238,7 @@ class AniList {
|
|
|
237
238
|
}
|
|
238
239
|
static MyAnime() {
|
|
239
240
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
-
var _a, _b, _c;
|
|
241
|
+
var _a, _b, _c, _d, _e;
|
|
241
242
|
try {
|
|
242
243
|
if (!(yield Auth.isLoggedIn())) {
|
|
243
244
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
@@ -246,22 +247,11 @@ class AniList {
|
|
|
246
247
|
if (!userId) {
|
|
247
248
|
return console.log(`\nFailed getting current user Id.`);
|
|
248
249
|
}
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
"content-type": "application/json",
|
|
253
|
-
"Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
|
|
254
|
-
},
|
|
255
|
-
body: JSON.stringify({
|
|
256
|
-
query: currentUserAnimeList,
|
|
257
|
-
variables: { id: userId },
|
|
258
|
-
}),
|
|
259
|
-
});
|
|
260
|
-
const { data, errors } = yield request.json();
|
|
261
|
-
if (request.status !== 200 || errors) {
|
|
262
|
-
return console.log(`\nSomething went wrong. ${(_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
|
|
250
|
+
const data = yield fetcher(currentUserAnimeList, { id: userId });
|
|
251
|
+
if (data === null || data === void 0 ? void 0 : data.errors) {
|
|
252
|
+
return console.log(`\nSomething went wrong. ${(_b = (_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message}`);
|
|
263
253
|
}
|
|
264
|
-
const lists = (
|
|
254
|
+
const lists = (_d = (_c = data === null || data === void 0 ? void 0 : data.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
265
255
|
if (!lists || lists.length === 0) {
|
|
266
256
|
return console.log(`\nYou seem to have no anime(s) in your lists.`);
|
|
267
257
|
}
|
|
@@ -304,11 +294,12 @@ class AniList {
|
|
|
304
294
|
],
|
|
305
295
|
},
|
|
306
296
|
]);
|
|
307
|
-
const
|
|
308
|
-
|
|
309
|
-
|
|
297
|
+
const saveResponse = yield fetcher(addAnimeToListMutation, {
|
|
298
|
+
mediaId: selectedAnime,
|
|
299
|
+
status: selectedListType,
|
|
300
|
+
});
|
|
310
301
|
if (saveResponse) {
|
|
311
|
-
const savedEntry = (
|
|
302
|
+
const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
312
303
|
console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
|
|
313
304
|
}
|
|
314
305
|
else {
|
|
@@ -322,7 +313,7 @@ class AniList {
|
|
|
322
313
|
}
|
|
323
314
|
static MyManga() {
|
|
324
315
|
return __awaiter(this, void 0, void 0, function* () {
|
|
325
|
-
var _a, _b, _c, _d, _e;
|
|
316
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
326
317
|
try {
|
|
327
318
|
if (!(yield Auth.isLoggedIn())) {
|
|
328
319
|
return console.error(`\nPlease log in first to access your lists.`);
|
|
@@ -331,23 +322,11 @@ class AniList {
|
|
|
331
322
|
if (!userId) {
|
|
332
323
|
return console.error(`\nFailed to get the current user ID.`);
|
|
333
324
|
}
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
headers: {
|
|
338
|
-
"Content-Type": "application/json",
|
|
339
|
-
"Authorization": `Bearer ${token}`,
|
|
340
|
-
},
|
|
341
|
-
body: JSON.stringify({
|
|
342
|
-
query: currentUserMangaList,
|
|
343
|
-
variables: { id: userId },
|
|
344
|
-
}),
|
|
345
|
-
});
|
|
346
|
-
const { data, errors } = yield request.json();
|
|
347
|
-
if (request.status !== 200 || errors) {
|
|
348
|
-
return console.error(`\nFailed to fetch manga lists. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
325
|
+
const response = yield fetcher(currentUserMangaList, { id: userId });
|
|
326
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
327
|
+
return console.error(`\nFailed to fetch manga lists. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
349
328
|
}
|
|
350
|
-
const lists = (
|
|
329
|
+
const lists = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
351
330
|
if (!lists || lists.length === 0) {
|
|
352
331
|
return console.log("\nYou don't seem to have any manga in your lists.");
|
|
353
332
|
}
|
|
@@ -393,24 +372,16 @@ class AniList {
|
|
|
393
372
|
],
|
|
394
373
|
},
|
|
395
374
|
]);
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
"Content-Type": "application/json",
|
|
400
|
-
"Authorization": `Bearer ${token}`,
|
|
401
|
-
},
|
|
402
|
-
body: JSON.stringify({
|
|
403
|
-
query: addMangaToListMutation,
|
|
404
|
-
variables: { mediaId: selectedManga, status: selectedListType },
|
|
405
|
-
}),
|
|
375
|
+
const saveResponse = yield fetcher(addMangaToListMutation, {
|
|
376
|
+
mediaId: selectedManga,
|
|
377
|
+
status: selectedListType,
|
|
406
378
|
});
|
|
407
|
-
const
|
|
408
|
-
const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
379
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
409
380
|
if (saved) {
|
|
410
381
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
411
382
|
}
|
|
412
383
|
else {
|
|
413
|
-
console.error(`\nFailed to save the manga. ${((
|
|
384
|
+
console.error(`\nFailed to save the manga. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
414
385
|
}
|
|
415
386
|
}
|
|
416
387
|
catch (error) {
|
|
@@ -420,27 +391,17 @@ class AniList {
|
|
|
420
391
|
}
|
|
421
392
|
static getTrendingAnime(count) {
|
|
422
393
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
|
-
var _a, _b, _c, _d, _e;
|
|
394
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
424
395
|
try {
|
|
425
396
|
let page = 1;
|
|
426
397
|
let allTrending = [];
|
|
427
398
|
while (true) {
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
"Content-Type": "application/json",
|
|
432
|
-
},
|
|
433
|
-
body: JSON.stringify({
|
|
434
|
-
query: trendingQuery,
|
|
435
|
-
variables: { page, perPage: count },
|
|
436
|
-
}),
|
|
437
|
-
});
|
|
438
|
-
const { data, errors } = yield request.json();
|
|
439
|
-
if (request.status !== 200 || errors) {
|
|
440
|
-
console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
399
|
+
const response = yield fetcher(trendingQuery, { page, perPage: count });
|
|
400
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
|
401
|
+
console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
441
402
|
return;
|
|
442
403
|
}
|
|
443
|
-
const media = (
|
|
404
|
+
const media = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.media;
|
|
444
405
|
if (!media || media.length === 0) {
|
|
445
406
|
console.log(`\nNo more trending anime available.`);
|
|
446
407
|
break;
|
|
@@ -448,7 +409,7 @@ class AniList {
|
|
|
448
409
|
allTrending = [...allTrending, ...media];
|
|
449
410
|
const choices = allTrending.map((anime, idx) => ({
|
|
450
411
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
451
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
412
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
452
413
|
}));
|
|
453
414
|
choices.push({ name: "See more", value: "see_more" });
|
|
454
415
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -485,12 +446,12 @@ class AniList {
|
|
|
485
446
|
}
|
|
486
447
|
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
487
448
|
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
488
|
-
const saved = (
|
|
449
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
489
450
|
if (saved) {
|
|
490
451
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
491
452
|
}
|
|
492
453
|
else {
|
|
493
|
-
console.error(`\nFailed to save the anime. ${((
|
|
454
|
+
console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
494
455
|
}
|
|
495
456
|
break;
|
|
496
457
|
}
|
|
@@ -503,27 +464,17 @@ class AniList {
|
|
|
503
464
|
}
|
|
504
465
|
static getPopularAnime(count) {
|
|
505
466
|
return __awaiter(this, void 0, void 0, function* () {
|
|
506
|
-
var _a, _b, _c, _d, _e;
|
|
467
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
507
468
|
try {
|
|
508
469
|
let page = 1;
|
|
509
470
|
let allMedia = [];
|
|
510
471
|
while (true) {
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
"Content-Type": "application/json",
|
|
515
|
-
},
|
|
516
|
-
body: JSON.stringify({
|
|
517
|
-
query: popularQuery,
|
|
518
|
-
variables: { page, perPage: count },
|
|
519
|
-
}),
|
|
520
|
-
});
|
|
521
|
-
const { data, errors } = yield request.json();
|
|
522
|
-
if (request.status !== 200 || errors) {
|
|
523
|
-
console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
|
|
472
|
+
const response = yield fetcher(popularQuery, { page, perPage: count });
|
|
473
|
+
if (!(response === null || response === void 0 ? void 0 : response.data)) {
|
|
474
|
+
console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
|
|
524
475
|
return;
|
|
525
476
|
}
|
|
526
|
-
const newMedia = (
|
|
477
|
+
const newMedia = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.media;
|
|
527
478
|
if (!newMedia || newMedia.length === 0) {
|
|
528
479
|
console.log(`\nNo more popular anime available.`);
|
|
529
480
|
break;
|
|
@@ -531,7 +482,7 @@ class AniList {
|
|
|
531
482
|
allMedia = [...allMedia, ...newMedia];
|
|
532
483
|
const choices = allMedia.map((anime, idx) => ({
|
|
533
484
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
534
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
485
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
535
486
|
}));
|
|
536
487
|
choices.push({ name: "See more", value: "see_more" });
|
|
537
488
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -567,12 +518,12 @@ class AniList {
|
|
|
567
518
|
}
|
|
568
519
|
const variables = { mediaId: selectedAnime, status: selectedListType };
|
|
569
520
|
const saveResponse = yield fetcher(addAnimeToListMutation, variables);
|
|
570
|
-
const saved = (
|
|
521
|
+
const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
|
|
571
522
|
if (saved) {
|
|
572
523
|
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
573
524
|
}
|
|
574
525
|
else {
|
|
575
|
-
console.error(`\nFailed to save the anime. ${((
|
|
526
|
+
console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
|
|
576
527
|
}
|
|
577
528
|
break;
|
|
578
529
|
}
|
|
@@ -609,7 +560,7 @@ class AniList {
|
|
|
609
560
|
allUpcoming = [...allUpcoming, ...newUpcoming];
|
|
610
561
|
const choices = allUpcoming.map((anime, idx) => ({
|
|
611
562
|
name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
|
|
612
|
-
value: anime === null || anime === void 0 ? void 0 : anime.id,
|
|
563
|
+
value: String(anime === null || anime === void 0 ? void 0 : anime.id),
|
|
613
564
|
}));
|
|
614
565
|
choices.push({ name: "See more", value: "see_more" });
|
|
615
566
|
const { selectedAnime } = yield inquirer.prompt([
|
|
@@ -663,22 +614,11 @@ class AniList {
|
|
|
663
614
|
}
|
|
664
615
|
static getUserByUsername(username) {
|
|
665
616
|
return __awaiter(this, void 0, void 0, function* () {
|
|
666
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
617
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
667
618
|
try {
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
if (yield Auth.isLoggedIn()) {
|
|
672
|
-
headers["Authorization"] = `Bearer ${yield Auth.RetriveAccessToken()}`;
|
|
673
|
-
}
|
|
674
|
-
const request = yield fetch(aniListEndpoint, {
|
|
675
|
-
method: "POST",
|
|
676
|
-
headers,
|
|
677
|
-
body: JSON.stringify({ query: userQuery, variables: { username } }),
|
|
678
|
-
});
|
|
679
|
-
const response = yield request.json();
|
|
680
|
-
if (request.status !== 200 || !((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
681
|
-
return console.error(`\n${request.status} ${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
|
|
619
|
+
const response = yield fetcher(userQuery, { username });
|
|
620
|
+
if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
|
|
621
|
+
return console.error(`\n${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
|
|
682
622
|
}
|
|
683
623
|
const user = response.data.User;
|
|
684
624
|
const userActivityResponse = yield fetcher(userActivityQuery, {
|
|
@@ -687,6 +627,15 @@ class AniList {
|
|
|
687
627
|
perPage: 10,
|
|
688
628
|
});
|
|
689
629
|
const activities = (_f = (_e = (_d = userActivityResponse === null || userActivityResponse === void 0 ? void 0 : userActivityResponse.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.activities) !== null && _f !== void 0 ? _f : [];
|
|
630
|
+
// Get follower/following information
|
|
631
|
+
const req_followers = yield fetcher(userFollowersQuery, {
|
|
632
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
633
|
+
});
|
|
634
|
+
const req_following = yield fetcher(userFollowingQuery, {
|
|
635
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
636
|
+
});
|
|
637
|
+
const followersCount = ((_j = (_h = (_g = req_followers === null || req_followers === void 0 ? void 0 : req_followers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.pageInfo) === null || _j === void 0 ? void 0 : _j.total) || 0;
|
|
638
|
+
const followingCount = ((_m = (_l = (_k = req_following === null || req_following === void 0 ? void 0 : req_following.data) === null || _k === void 0 ? void 0 : _k.Page) === null || _l === void 0 ? void 0 : _l.pageInfo) === null || _m === void 0 ? void 0 : _m.total) || 0;
|
|
690
639
|
console.log(`\nID:\t\t${user.id}`);
|
|
691
640
|
console.log(`Name:\t\t${user.name}`);
|
|
692
641
|
console.log(`Site URL:\t${user.siteUrl}`);
|
|
@@ -697,14 +646,16 @@ class AniList {
|
|
|
697
646
|
console.log(`Blocked:\t${user.isBlocked}`);
|
|
698
647
|
console.log(`Follower:\t${user.isFollower}`);
|
|
699
648
|
console.log(`Following:\t${user.isFollowing}`);
|
|
700
|
-
console.log(`Profile Color:\t${(
|
|
701
|
-
console.log(`Timezone:\t${(
|
|
702
|
-
console.log(`\
|
|
703
|
-
console.log(`
|
|
649
|
+
console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
|
|
650
|
+
console.log(`Timezone:\t${((_p = user.options) === null || _p === void 0 ? void 0 : _p.timezone) ? (_q = user.options) === null || _q === void 0 ? void 0 : _q.timezone : "N/A"}`);
|
|
651
|
+
console.log(`\nFollowers:\t${followersCount}`);
|
|
652
|
+
console.log(`Following:\t${followingCount}`);
|
|
653
|
+
console.log(`\nStatistics (Anime)\n\tCount: ${((_s = (_r = user.statistics) === null || _r === void 0 ? void 0 : _r.anime) === null || _s === void 0 ? void 0 : _s.count) || 0}\tEpisodes Watched: ${((_u = (_t = user.statistics) === null || _t === void 0 ? void 0 : _t.anime) === null || _u === void 0 ? void 0 : _u.episodesWatched) || 0}\tMinutes Watched: ${((_w = (_v = user.statistics) === null || _v === void 0 ? void 0 : _v.anime) === null || _w === void 0 ? void 0 : _w.minutesWatched) || 0}`);
|
|
654
|
+
console.log(`Statistics (Manga)\n\tCount: ${((_y = (_x = user.statistics) === null || _x === void 0 ? void 0 : _x.manga) === null || _y === void 0 ? void 0 : _y.count) || 0}\tChapters Read: ${((_0 = (_z = user.statistics) === null || _z === void 0 ? void 0 : _z.manga) === null || _0 === void 0 ? void 0 : _0.chaptersRead) || 0}\tVolumes Read: ${((_2 = (_1 = user.statistics) === null || _1 === void 0 ? void 0 : _1.manga) === null || _2 === void 0 ? void 0 : _2.volumesRead) || 0}`);
|
|
704
655
|
if (activities.length > 0) {
|
|
705
656
|
console.log(`\nRecent Activities:`);
|
|
706
|
-
activities.forEach(({ status, progress, media }) => {
|
|
707
|
-
console.log(`${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
657
|
+
activities.forEach(({ status, progress, media, createdAt }) => {
|
|
658
|
+
console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
|
|
708
659
|
});
|
|
709
660
|
}
|
|
710
661
|
else {
|
|
@@ -719,9 +670,9 @@ class AniList {
|
|
|
719
670
|
static getAnimeDetailsByID(anilistID) {
|
|
720
671
|
return __awaiter(this, void 0, void 0, function* () {
|
|
721
672
|
var _a;
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
673
|
+
const details = yield fetcher(animeDetailsQuery, {
|
|
674
|
+
id: anilistID,
|
|
675
|
+
});
|
|
725
676
|
if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
|
|
726
677
|
const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
|
|
727
678
|
console.log(`\nID: ${id}`);
|
|
@@ -743,9 +694,11 @@ class AniList {
|
|
|
743
694
|
static searchAnime(search, count) {
|
|
744
695
|
return __awaiter(this, void 0, void 0, function* () {
|
|
745
696
|
var _a, _b, _c;
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
|
|
697
|
+
const searchResults = yield fetcher(animeSearchQuery, {
|
|
698
|
+
search,
|
|
699
|
+
page: 1,
|
|
700
|
+
perPage: count,
|
|
701
|
+
});
|
|
749
702
|
if (searchResults) {
|
|
750
703
|
const results = (_b = (_a = searchResults === null || searchResults === void 0 ? void 0 : searchResults.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
|
|
751
704
|
if (results.length > 0) {
|
|
@@ -777,12 +730,10 @@ class AniList {
|
|
|
777
730
|
]);
|
|
778
731
|
// Save selected anime to chosen list type
|
|
779
732
|
if (yield Auth.isLoggedIn()) {
|
|
780
|
-
const
|
|
781
|
-
const saveVariables = {
|
|
733
|
+
const response = yield fetcher(addAnimeToListMutation, {
|
|
782
734
|
mediaId: selectedAnime,
|
|
783
735
|
status: selectedListType,
|
|
784
|
-
};
|
|
785
|
-
const response = yield fetcher(saveQuery, saveVariables);
|
|
736
|
+
});
|
|
786
737
|
if (response) {
|
|
787
738
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
788
739
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -804,9 +755,11 @@ class AniList {
|
|
|
804
755
|
static searchManga(search, count) {
|
|
805
756
|
return __awaiter(this, void 0, void 0, function* () {
|
|
806
757
|
var _a, _b, _c;
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
758
|
+
const mangaSearchResult = yield fetcher(mangaSearchQuery, {
|
|
759
|
+
search,
|
|
760
|
+
page: 1,
|
|
761
|
+
perPage: count,
|
|
762
|
+
});
|
|
810
763
|
if (mangaSearchResult) {
|
|
811
764
|
const results = (_b = (_a = mangaSearchResult === null || mangaSearchResult === void 0 ? void 0 : mangaSearchResult.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
|
|
812
765
|
// List of manga search results
|
|
@@ -839,9 +792,10 @@ class AniList {
|
|
|
839
792
|
]);
|
|
840
793
|
// If logged in save to the list
|
|
841
794
|
if (yield Auth.isLoggedIn()) {
|
|
842
|
-
const
|
|
843
|
-
|
|
844
|
-
|
|
795
|
+
const response = yield fetcher(addMangaToListMutation, {
|
|
796
|
+
mediaId: selectedMangaId,
|
|
797
|
+
status: selectedListType,
|
|
798
|
+
});
|
|
845
799
|
if (response) {
|
|
846
800
|
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
847
801
|
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
@@ -1041,19 +995,16 @@ class MyAnimeList {
|
|
|
1041
995
|
});
|
|
1042
996
|
if (mangaList && ((_b = (_a = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists.length) > 0) {
|
|
1043
997
|
const lists = (_d = (_c = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
|
|
1044
|
-
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1055
|
-
});
|
|
1056
|
-
}));
|
|
998
|
+
const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
|
|
999
|
+
id: entry.media.id,
|
|
1000
|
+
malId: entry.media.idMal,
|
|
1001
|
+
title: entry.media.title,
|
|
1002
|
+
private: entry.private,
|
|
1003
|
+
chapters: entry.media.chapters,
|
|
1004
|
+
progress: entry.progress,
|
|
1005
|
+
status: entry.status,
|
|
1006
|
+
hiddenFromStatusLists: entry.hiddenFromStatusLists,
|
|
1007
|
+
})));
|
|
1057
1008
|
const XMLContent = createMangaListXML(mediaWithProgress);
|
|
1058
1009
|
const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
|
|
1059
1010
|
yield writeFile(path, yield XMLContent, "utf8");
|
|
@@ -1070,4 +1021,92 @@ class MyAnimeList {
|
|
|
1070
1021
|
});
|
|
1071
1022
|
}
|
|
1072
1023
|
}
|
|
1073
|
-
|
|
1024
|
+
class AniDB {
|
|
1025
|
+
static importAnime() {
|
|
1026
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1027
|
+
var _a, _b;
|
|
1028
|
+
try {
|
|
1029
|
+
const filename = yield selectFile(".json");
|
|
1030
|
+
const filePath = join(getDownloadFolderPath(), filename);
|
|
1031
|
+
const fileContent = yield readFile(filePath, "utf8");
|
|
1032
|
+
const js0n_repaired = jsonrepair(fileContent);
|
|
1033
|
+
if (fileContent) {
|
|
1034
|
+
const obj3ct = yield JSON.parse(js0n_repaired);
|
|
1035
|
+
const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
|
|
1036
|
+
if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
|
|
1037
|
+
let count = 0;
|
|
1038
|
+
let iteration = 0;
|
|
1039
|
+
let missed = [];
|
|
1040
|
+
for (const anime of animeList) {
|
|
1041
|
+
iteration++;
|
|
1042
|
+
const anidbId = anime.id;
|
|
1043
|
+
const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
|
|
1044
|
+
const status = anime.status;
|
|
1045
|
+
// const type = anime.type
|
|
1046
|
+
const totalEpisodes = anime.totalEpisodes;
|
|
1047
|
+
const ownEpisodes = anime.ownEpisodes;
|
|
1048
|
+
const romanjiName = anime.romanjiName;
|
|
1049
|
+
const englishName = anime.englishName;
|
|
1050
|
+
function getStatus(anidbStatus, episodesSeen) {
|
|
1051
|
+
if (anidbStatus === "complete") {
|
|
1052
|
+
return AniListMediaStatus.COMPLETED;
|
|
1053
|
+
}
|
|
1054
|
+
else if (anidbStatus === "incomplete" &&
|
|
1055
|
+
Number(episodesSeen) > 0) {
|
|
1056
|
+
return AniListMediaStatus.CURRENT;
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
return AniListMediaStatus.PLANNING;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
|
|
1063
|
+
if (anilistId) {
|
|
1064
|
+
try {
|
|
1065
|
+
const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
|
|
1066
|
+
mediaId: anilistId,
|
|
1067
|
+
progress: ownEpisodes - 2,
|
|
1068
|
+
status: getStatus(status, ownEpisodes),
|
|
1069
|
+
hiddenFromStatusLists: false,
|
|
1070
|
+
private: false,
|
|
1071
|
+
});
|
|
1072
|
+
const entryId = (_b = (_a = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
|
|
1073
|
+
if (entryId) {
|
|
1074
|
+
count++;
|
|
1075
|
+
console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}→${getStatus(status, ownEpisodes)}`);
|
|
1076
|
+
}
|
|
1077
|
+
// Rate limit each API call to avoid server overload
|
|
1078
|
+
// await new Promise((resolve) => setTimeout(resolve, 1100))
|
|
1079
|
+
}
|
|
1080
|
+
catch (error) {
|
|
1081
|
+
console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
missed.push({
|
|
1086
|
+
anidbId: anidbId,
|
|
1087
|
+
englishTitle: englishName,
|
|
1088
|
+
romajiTitle: romanjiName,
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
console.log(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
|
|
1093
|
+
if (missed.length > 0) {
|
|
1094
|
+
console.log(`Exporting missed entries to JSON file, Please add them manually.`);
|
|
1095
|
+
yield saveJSONasJSON(missed, "anidb-missed");
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
else {
|
|
1099
|
+
console.log(`\nNo anime list found in the file.`);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
console.log(`\nNo content found in the file or unable to read.`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
catch (error) {
|
|
1107
|
+
console.error(`\nError in AniDB import process: ${error.message}`);
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
export { AniDB, AniList, MyAnimeList };
|
package/bin/helpers/queries.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const currentUserQuery = "{\n Viewer {\n id name about bans siteUrl options { profileColor timezone activityMergeTime }\n donatorTier donatorBadge createdAt updatedAt unreadNotificationCount previousNames { name createdAt updatedAt }\n moderatorRoles favourites { anime { nodes { id title { romaji english } } } manga { nodes { id title { romaji english } } } }\n statistics { anime { count meanScore minutesWatched } manga { count chaptersRead volumesRead } }\n mediaListOptions { scoreFormat rowOrder animeList { sectionOrder } mangaList { sectionOrder } }\n }\n}";
|
|
1
|
+
declare const currentUserQuery = "{\n Viewer {\n id name about bans siteUrl options { profileColor timezone activityMergeTime }\n donatorTier donatorBadge createdAt updatedAt unreadNotificationCount previousNames { name createdAt updatedAt }\n moderatorRoles favourites { anime { nodes { id title { romaji english } } } manga { nodes { id title { romaji english } } } }\n statistics { anime { count meanScore minutesWatched episodesWatched } manga { count chaptersRead volumesRead meanScore } }\n mediaListOptions { scoreFormat rowOrder animeList { sectionOrder } mangaList { sectionOrder } }\n }\n}";
|
|
2
2
|
declare const trendingQuery = "query ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n media(sort: TRENDING_DESC, type: ANIME) { id title { romaji english } }\n }\n}";
|
|
3
3
|
declare const popularQuery = "query ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n media(sort: POPULARITY_DESC, type: ANIME) { id title { romaji english } }\n }\n}";
|
|
4
4
|
declare const userQuery = "query ($username: String) {\n User(name: $username) {\n id name siteUrl donatorTier donatorBadge createdAt updatedAt previousNames { name createdAt updatedAt }\n isBlocked isFollower isFollowing options { profileColor timezone activityMergeTime }\n statistics { anime { count episodesWatched minutesWatched } manga { count chaptersRead volumesRead } }\n }\n}";
|
|
@@ -9,7 +9,7 @@ declare const deleteMangaEntryMutation = "mutation($id: Int) {\n DeleteMediaLis
|
|
|
9
9
|
declare const upcomingAnimesQuery = "query GetNextSeasonAnime($nextSeason: MediaSeason, $nextYear: Int, $perPage: Int) {\n Page(perPage: $perPage) {\n media(season: $nextSeason, seasonYear: $nextYear, type: ANIME, sort: POPULARITY_DESC) {\n id title { romaji english native userPreferred } season seasonYear startDate { year month day }\n episodes description genres\n }\n }\n}";
|
|
10
10
|
declare const animeDetailsQuery = "query ($id: Int) {\n Media(id: $id) {\n id idMal title { romaji english native userPreferred } episodes nextAiringEpisode { id }\n duration startDate { year month day } endDate { year month day } countryOfOrigin description isAdult status season format genres siteUrl\n stats { scoreDistribution { score amount } statusDistribution { status amount } }\n }\n}";
|
|
11
11
|
declare const userActivityQuery = "query ($id: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $id, type_in: [ANIME_LIST, MANGA_LIST], sort: ID_DESC) {\n ... on ListActivity { id status progress createdAt media { id title { romaji english } } }\n }\n }\n}";
|
|
12
|
-
declare const animeSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: ANIME) { id title { romaji english native userPreferred } episodes status description }\n }\n}";
|
|
12
|
+
declare const animeSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: ANIME) { id title { romaji english native userPreferred } startDate { day month year } episodes status description }\n }\n}";
|
|
13
13
|
declare const mangaSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: MANGA) { id title { romaji english native userPreferred } chapters status description }\n }\n}";
|
|
14
14
|
declare const activityTextQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: TEXT, sort: ID_DESC) {\n ... on TextActivity { id type text createdAt user { id name } }\n }\n }\n}";
|
|
15
15
|
declare const activityAnimeListQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: ANIME_LIST, sort: ID_DESC) {\n ... on ListActivity { id type status progress createdAt media { id title { romaji english native } } }\n }\n }\n}";
|
|
@@ -19,4 +19,6 @@ declare const activityAllQuery = "query ($userId: Int, $page: Int, $perPage: Int
|
|
|
19
19
|
declare const activityMediaList = "query ($userId: Int, $page: Int, $perPage: Int, $type: ActivityType) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total currentPage lastPage hasNextPage perPage }\n activities(userId: $userId, type: $type, sort: ID_DESC) {\n ... on ListActivity { id type status progress media { id title { romaji english native } format } createdAt }\n }\n }\n}";
|
|
20
20
|
declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) {\n id title { romaji english } } \n}\n";
|
|
21
21
|
declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) {\n id title { romaji english } } \n}\n";
|
|
22
|
-
|
|
22
|
+
declare const userFollowingQuery = "query ($userId: Int!) {\n Page {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }\n }\n}\n";
|
|
23
|
+
declare const userFollowersQuery = "query ($userId: Int!) {\n Page {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }\n }\n}\n";
|
|
24
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|
package/bin/helpers/queries.js
CHANGED
|
@@ -3,7 +3,7 @@ const currentUserQuery = `{
|
|
|
3
3
|
id name about bans siteUrl options { profileColor timezone activityMergeTime }
|
|
4
4
|
donatorTier donatorBadge createdAt updatedAt unreadNotificationCount previousNames { name createdAt updatedAt }
|
|
5
5
|
moderatorRoles favourites { anime { nodes { id title { romaji english } } } manga { nodes { id title { romaji english } } } }
|
|
6
|
-
statistics { anime { count meanScore minutesWatched } manga { count chaptersRead volumesRead } }
|
|
6
|
+
statistics { anime { count meanScore minutesWatched episodesWatched } manga { count chaptersRead volumesRead meanScore } }
|
|
7
7
|
mediaListOptions { scoreFormat rowOrder animeList { sectionOrder } mangaList { sectionOrder } }
|
|
8
8
|
}
|
|
9
9
|
}`;
|
|
@@ -66,7 +66,7 @@ const userActivityQuery = `query ($id: Int, $page: Int, $perPage: Int) {
|
|
|
66
66
|
}`;
|
|
67
67
|
const animeSearchQuery = `query ($search: String, $perPage: Int) {
|
|
68
68
|
Page(perPage: $perPage) {
|
|
69
|
-
media(search: $search, type: ANIME) { id title { romaji english native userPreferred } episodes status description }
|
|
69
|
+
media(search: $search, type: ANIME) { id title { romaji english native userPreferred } startDate { day month year } episodes status description }
|
|
70
70
|
}
|
|
71
71
|
}`;
|
|
72
72
|
const mangaSearchQuery = `query ($search: String, $perPage: Int) {
|
|
@@ -129,4 +129,18 @@ const malIdToAnilistMangaId = `query ($malId: Int) {
|
|
|
129
129
|
id title { romaji english } }
|
|
130
130
|
}
|
|
131
131
|
`;
|
|
132
|
-
|
|
132
|
+
const userFollowingQuery = `query ($userId: Int!) {
|
|
133
|
+
Page {
|
|
134
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
135
|
+
following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
const userFollowersQuery = `query ($userId: Int!) {
|
|
140
|
+
Page {
|
|
141
|
+
pageInfo { total perPage currentPage lastPage hasNextPage }
|
|
142
|
+
followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
`;
|
|
146
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
|