@irfanshadikrishad/anilist 1.0.0-forbidden.0 → 1.0.0-forbidden.2

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.
@@ -14,10 +14,10 @@ import open from "open";
14
14
  import os from "os";
15
15
  import path from "path";
16
16
  import { fetcher } from "./fetcher.js";
17
- import { AniList, MyAnimeList } from "./lists.js";
17
+ import { AniDB, AniList, MyAnimeList } from "./lists.js";
18
18
  import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
19
- import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, userActivityQuery, } from "./queries.js";
20
- import { aniListEndpoint, getTitle, redirectUri } from "./workers.js";
19
+ import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
20
+ import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
21
21
  const home_dir = os.homedir();
22
22
  const save_path = path.join(home_dir, ".anilist_token");
23
23
  class Auth {
@@ -109,7 +109,7 @@ class Auth {
109
109
  }
110
110
  static Myself() {
111
111
  return __awaiter(this, void 0, void 0, function* () {
112
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
112
+ 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;
113
113
  try {
114
114
  if (yield Auth.isLoggedIn()) {
115
115
  const headers = {
@@ -130,33 +130,47 @@ class Auth {
130
130
  perPage: 10,
131
131
  });
132
132
  const activities = (_b = (_a = activiResponse === null || activiResponse === void 0 ? void 0 : activiResponse.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities;
133
- console.log(`
134
- ID: ${user === null || user === void 0 ? void 0 : user.id}
135
- Name: ${user === null || user === void 0 ? void 0 : user.name}
136
- siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
137
- profileColor: ${(_c = user === null || user === void 0 ? void 0 : user.options) === null || _c === void 0 ? void 0 : _c.profileColor}
138
- timeZone: ${(_d = user === null || user === void 0 ? void 0 : user.options) === null || _d === void 0 ? void 0 : _d.timezone}
139
- activityMergeTime: ${(_e = user === null || user === void 0 ? void 0 : user.options) === null || _e === void 0 ? void 0 : _e.activityMergeTime}
140
- donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
141
- donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
142
- unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
143
- Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
144
- Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
145
-
146
- Statistics (Anime):
147
- Count: ${(_g = (_f = user === null || user === void 0 ? void 0 : user.statistics) === null || _f === void 0 ? void 0 : _f.anime) === null || _g === void 0 ? void 0 : _g.count}
148
- Mean Score: ${(_j = (_h = user === null || user === void 0 ? void 0 : user.statistics) === null || _h === void 0 ? void 0 : _h.anime) === null || _j === void 0 ? void 0 : _j.meanScore}
149
- Minutes Watched: ${(_l = (_k = user === null || user === void 0 ? void 0 : user.statistics) === null || _k === void 0 ? void 0 : _k.anime) === null || _l === void 0 ? void 0 : _l.minutesWatched}
150
-
151
- Statistics (Manga):
152
- Count: ${(_o = (_m = user === null || user === void 0 ? void 0 : user.statistics) === null || _m === void 0 ? void 0 : _m.manga) === null || _o === void 0 ? void 0 : _o.count}
153
- Chapters Read: ${(_q = (_p = user === null || user === void 0 ? void 0 : user.statistics) === null || _p === void 0 ? void 0 : _p.manga) === null || _q === void 0 ? void 0 : _q.chaptersRead}
154
- Volumes Read: ${(_s = (_r = user === null || user === void 0 ? void 0 : user.statistics) === null || _r === void 0 ? void 0 : _r.manga) === null || _s === void 0 ? void 0 : _s.volumesRead}
133
+ // Get follower/following information
134
+ const req_followers = yield fetcher(userFollowersQuery, {
135
+ userId: user === null || user === void 0 ? void 0 : user.id,
136
+ });
137
+ const req_following = yield fetcher(userFollowingQuery, {
138
+ userId: user === null || user === void 0 ? void 0 : user.id,
139
+ });
140
+ const followersCount = ((_e = (_d = (_c = req_followers === null || req_followers === void 0 ? void 0 : req_followers.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.pageInfo) === null || _e === void 0 ? void 0 : _e.total) || 0;
141
+ const followingCount = ((_h = (_g = (_f = req_following === null || req_following === void 0 ? void 0 : req_following.data) === null || _f === void 0 ? void 0 : _f.Page) === null || _g === void 0 ? void 0 : _g.pageInfo) === null || _h === void 0 ? void 0 : _h.total) || 0;
142
+ console.log(`
143
+ ID: ${user === null || user === void 0 ? void 0 : user.id}
144
+ Name: ${user === null || user === void 0 ? void 0 : user.name}
145
+ siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
146
+ profileColor: ${(_j = user === null || user === void 0 ? void 0 : user.options) === null || _j === void 0 ? void 0 : _j.profileColor}
147
+ timeZone: ${(_k = user === null || user === void 0 ? void 0 : user.options) === null || _k === void 0 ? void 0 : _k.timezone}
148
+ activityMergeTime: ${(_l = user === null || user === void 0 ? void 0 : user.options) === null || _l === void 0 ? void 0 : _l.activityMergeTime}
149
+ donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
150
+ donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
151
+ unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
152
+ Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
153
+ Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
154
+
155
+ Followers: ${followersCount}
156
+ Following: ${followingCount}
157
+
158
+ Statistics (Anime):
159
+ Count: ${(_o = (_m = user === null || user === void 0 ? void 0 : user.statistics) === null || _m === void 0 ? void 0 : _m.anime) === null || _o === void 0 ? void 0 : _o.count}
160
+ Mean Score: ${(_q = (_p = user === null || user === void 0 ? void 0 : user.statistics) === null || _p === void 0 ? void 0 : _p.anime) === null || _q === void 0 ? void 0 : _q.meanScore}
161
+ Minutes Watched: ${(_s = (_r = user === null || user === void 0 ? void 0 : user.statistics) === null || _r === void 0 ? void 0 : _r.anime) === null || _s === void 0 ? void 0 : _s.minutesWatched}
162
+ Episodes Watched: ${(_u = (_t = user === null || user === void 0 ? void 0 : user.statistics) === null || _t === void 0 ? void 0 : _t.anime) === null || _u === void 0 ? void 0 : _u.episodesWatched}
163
+
164
+ Statistics (Manga):
165
+ Count: ${(_w = (_v = user === null || user === void 0 ? void 0 : user.statistics) === null || _v === void 0 ? void 0 : _v.manga) === null || _w === void 0 ? void 0 : _w.count}
166
+ Mean Score: ${(_y = (_x = user === null || user === void 0 ? void 0 : user.statistics) === null || _x === void 0 ? void 0 : _x.manga) === null || _y === void 0 ? void 0 : _y.meanScore}
167
+ Chapters Read: ${(_0 = (_z = user === null || user === void 0 ? void 0 : user.statistics) === null || _z === void 0 ? void 0 : _z.manga) === null || _0 === void 0 ? void 0 : _0.chaptersRead}
168
+ Volumes Read: ${(_2 = (_1 = user === null || user === void 0 ? void 0 : user.statistics) === null || _1 === void 0 ? void 0 : _1.manga) === null || _2 === void 0 ? void 0 : _2.volumesRead}
155
169
  `);
156
170
  console.log(`\nRecent Activities:`);
157
171
  if (activities.length > 0) {
158
- activities.map(({ status, progress, media }) => {
159
- console.log(`${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
172
+ activities.map(({ status, progress, media, createdAt }) => {
173
+ console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
160
174
  });
161
175
  }
162
176
  return user;
@@ -217,7 +231,7 @@ Statistics (Manga):
217
231
  return __awaiter(this, void 0, void 0, function* () {
218
232
  var _a, _b;
219
233
  if (!(yield Auth.isLoggedIn())) {
220
- console.log(`\nUser not logged in.`);
234
+ console.warn(`\nUser not logged in.`);
221
235
  return null;
222
236
  }
223
237
  const token = yield Auth.RetriveAccessToken();
@@ -281,8 +295,6 @@ Statistics (Manga):
281
295
  ],
282
296
  },
283
297
  ]);
284
- const userId = yield Auth.MyUserId();
285
- const variables = { page: 1, perPage: 100, userId };
286
298
  const queryMap = {
287
299
  0: activityAllQuery,
288
300
  1: activityTextQuery,
@@ -293,6 +305,7 @@ Statistics (Manga):
293
305
  };
294
306
  const query = queryMap[activityType];
295
307
  let hasMoreActivities = true;
308
+ let totalCount = 0;
296
309
  while (hasMoreActivities) {
297
310
  const response = yield fetcher(query, {
298
311
  page: 1,
@@ -315,7 +328,8 @@ Statistics (Manga):
315
328
  });
316
329
  const isDeleted = (_f = (_e = deleteResponse === null || deleteResponse === void 0 ? void 0 : deleteResponse.data) === null || _e === void 0 ? void 0 : _e.DeleteActivity) === null || _f === void 0 ? void 0 : _f.deleted;
317
330
  count++;
318
- console.log(`[${count}/${activities.length}] ${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "✅" : "❌"}`);
331
+ totalCount++;
332
+ console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "✅" : "❌"}`);
319
333
  // Avoiding rate-limit
320
334
  yield new Promise((resolve) => setTimeout(resolve, 1100));
321
335
  }
@@ -344,19 +358,8 @@ Statistics (Manga):
344
358
  if (yield Auth.isLoggedIn()) {
345
359
  const userID = yield Auth.MyUserId();
346
360
  if (userID) {
347
- const request = yield fetch(aniListEndpoint, {
348
- method: "POST",
349
- headers: {
350
- "content-type": "application/json",
351
- "Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
352
- },
353
- body: JSON.stringify({
354
- query: currentUserAnimeList,
355
- variables: { id: userID },
356
- }),
357
- });
358
- const response = yield request.json();
359
- if (request.status === 200) {
361
+ const response = yield fetcher(currentUserAnimeList, { id: userID });
362
+ if (response !== null) {
360
363
  const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
361
364
  if (lists.length > 0) {
362
365
  const { selectedList } = yield inquirer.prompt([
@@ -371,7 +374,7 @@ Statistics (Manga):
371
374
  const selectedEntries = lists.find((list) => list.name === selectedList);
372
375
  if (selectedEntries) {
373
376
  console.log(`\nDeleting entries of '${selectedEntries.name}':`);
374
- for (const [_, entry] of selectedEntries.entries.entries()) {
377
+ for (const [, entry] of selectedEntries.entries.entries()) {
375
378
  if (entry === null || entry === void 0 ? void 0 : entry.id) {
376
379
  yield Auth.DeleteAnimeById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
377
380
  yield new Promise((resolve) => setTimeout(resolve, 1100));
@@ -407,19 +410,8 @@ Statistics (Manga):
407
410
  return __awaiter(this, void 0, void 0, function* () {
408
411
  var _a, _b, _c;
409
412
  try {
410
- const request = yield fetch(aniListEndpoint, {
411
- method: "POST",
412
- headers: {
413
- "content-type": "application/json",
414
- "Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
415
- },
416
- body: JSON.stringify({
417
- query: deleteMediaEntryMutation,
418
- variables: { id },
419
- }),
420
- });
421
- const response = yield request.json();
422
- if (request.status === 200) {
413
+ const response = yield fetcher(deleteMediaEntryMutation, { id: id });
414
+ if (response === null || response === void 0 ? void 0 : response.data) {
423
415
  const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
424
416
  console.log(`del ${title ? getTitle(title) : ""} ${deleted ? "✅" : "❌"}`);
425
417
  }
@@ -440,19 +432,8 @@ Statistics (Manga):
440
432
  if (yield Auth.isLoggedIn()) {
441
433
  const userID = yield Auth.MyUserId();
442
434
  if (userID) {
443
- const request = yield fetch(aniListEndpoint, {
444
- method: "POST",
445
- headers: {
446
- "content-type": "application/json",
447
- "Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
448
- },
449
- body: JSON.stringify({
450
- query: currentUserMangaList,
451
- variables: { id: userID },
452
- }),
453
- });
454
- const response = yield request.json();
455
- if (request.status === 200) {
435
+ const response = yield fetcher(currentUserMangaList, { id: userID });
436
+ if (response === null || response === void 0 ? void 0 : response.data) {
456
437
  const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
457
438
  if (lists.length > 0) {
458
439
  const { selectedList } = yield inquirer.prompt([
@@ -467,7 +448,7 @@ Statistics (Manga):
467
448
  const selectedEntries = lists.find((list) => list.name === selectedList);
468
449
  if (selectedEntries) {
469
450
  console.log(`\nDeleting entries of '${selectedEntries.name}':`);
470
- for (const [_, entry] of selectedEntries.entries.entries()) {
451
+ for (const [, entry] of selectedEntries.entries.entries()) {
471
452
  if (entry === null || entry === void 0 ? void 0 : entry.id) {
472
453
  yield Auth.DeleteMangaById(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
473
454
  yield new Promise((resolve) => setTimeout(resolve, 1100));
@@ -499,33 +480,22 @@ Statistics (Manga):
499
480
  }
500
481
  }
501
482
  catch (error) {
502
- console.error(`\nError deleting manga.`);
483
+ console.error(`\nError deleting manga. ${error.message}`);
503
484
  }
504
485
  });
505
486
  }
506
487
  static DeleteMangaById(id, title) {
507
488
  return __awaiter(this, void 0, void 0, function* () {
508
- var _a, _b;
489
+ var _a, _b, _c, _d;
509
490
  try {
510
- const request = yield fetch(aniListEndpoint, {
511
- method: "POST",
512
- headers: {
513
- "Content-Type": "application/json",
514
- "Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
515
- },
516
- body: JSON.stringify({
517
- query: deleteMangaEntryMutation,
518
- variables: { id },
519
- }),
520
- });
521
- const { data, errors } = yield request.json();
491
+ const response = yield fetcher(deleteMangaEntryMutation, { id });
522
492
  const statusMessage = title ? getTitle(title) : "";
523
- if (request.ok) {
524
- const deleted = (_a = data === null || data === void 0 ? void 0 : data.DeleteMediaListEntry) === null || _a === void 0 ? void 0 : _a.deleted;
493
+ if (response === null || response === void 0 ? void 0 : response.data) {
494
+ const deleted = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.DeleteMediaListEntry) === null || _b === void 0 ? void 0 : _b.deleted;
525
495
  console.log(`del ${statusMessage} ${deleted ? "✅" : "❌"}`);
526
496
  }
527
497
  else {
528
- console.error(`Error deleting manga. ${(_b = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _b === void 0 ? void 0 : _b.message}`);
498
+ console.error(`Error deleting manga. ${(_d = (_c = response === null || response === void 0 ? void 0 : response.errors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message}`);
529
499
  }
530
500
  }
531
501
  catch (error) {
@@ -541,12 +511,9 @@ Statistics (Manga):
541
511
  console.error(`\nPlease login to use this feature.`);
542
512
  return;
543
513
  }
544
- const query = saveTextActivityMutation;
545
- const variables = {
546
- status: status +
547
- `<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
548
- };
549
- const data = yield fetcher(query, variables);
514
+ const data = yield fetcher(saveTextActivityMutation, {
515
+ status: status,
516
+ });
550
517
  if (!data) {
551
518
  console.error(`\nSomething went wrong. ${data}.`);
552
519
  return;
@@ -572,6 +539,7 @@ Statistics (Manga):
572
539
  choices: [
573
540
  { name: "Exported JSON file.", value: 1 },
574
541
  { name: "MyAnimeList (XML)", value: 2 },
542
+ { name: "AniDB (json-large)", value: 3 },
575
543
  ],
576
544
  pageSize: 10,
577
545
  },
@@ -583,6 +551,9 @@ Statistics (Manga):
583
551
  case 2:
584
552
  yield MyAnimeList.importAnime();
585
553
  break;
554
+ case 3:
555
+ yield AniDB.importAnime();
556
+ break;
586
557
  default:
587
558
  console.log(`\nInvalid Choice.`);
588
559
  break;
@@ -625,29 +596,36 @@ Statistics (Manga):
625
596
  }
626
597
  });
627
598
  }
628
- static likeFollowing() {
599
+ static LikeFollowing() {
629
600
  return __awaiter(this, void 0, void 0, function* () {
630
- var _a, _b, _c, _d, _e;
601
+ var _a, _b, _c, _d;
631
602
  try {
632
603
  let page = 1;
633
604
  let hasMoreActivities = true;
605
+ let retryCount = 0;
606
+ const maxRetries = 5;
634
607
  while (hasMoreActivities) {
635
608
  const activities = yield fetcher(followingActivitiesQuery, {
636
609
  page,
637
610
  perPage: 50,
638
611
  });
639
612
  if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
613
+ retryCount = 0; // Reset retry count on successful fetch
640
614
  const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
641
615
  for (let activ of activiti) {
642
616
  if (!activ.isLiked && activ.id) {
643
- const like = yield fetcher(likeActivityMutation, {
644
- activityId: activ.id,
645
- });
646
- const ToggleLike = (_e = like === null || like === void 0 ? void 0 : like.data) === null || _e === void 0 ? void 0 : _e.ToggleLike;
647
- console.info(`[${activ.id}] liked ${activ.user.name}`);
617
+ try {
618
+ const like = yield fetcher(likeActivityMutation, {
619
+ activityId: activ.id,
620
+ });
621
+ console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
622
+ }
623
+ catch (error) {
624
+ console.error(`Activity possibly deleted. ${error.message}`);
625
+ }
648
626
  }
649
627
  else {
650
- console.log(`[${activ === null || activ === void 0 ? void 0 : activ.id}] ${activ.user.name} already-liked`);
628
+ console.log(`${activityBy(activ)} 🔵`);
651
629
  }
652
630
  // avoiding rate-limit
653
631
  yield new Promise((resolve) => {
@@ -656,6 +634,66 @@ Statistics (Manga):
656
634
  }
657
635
  page++;
658
636
  }
637
+ else {
638
+ if (retryCount < maxRetries) {
639
+ retryCount++;
640
+ console.warn(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
641
+ yield new Promise((resolve) => setTimeout(resolve, 3000));
642
+ }
643
+ else {
644
+ console.log(`\nProbably the end of activities after ${maxRetries} retries.`);
645
+ console.info(activities);
646
+ hasMoreActivities = false;
647
+ }
648
+ }
649
+ }
650
+ }
651
+ catch (error) {
652
+ console.error(`\nError from likeFollowing. ${error.message}`);
653
+ }
654
+ });
655
+ }
656
+ static Like(type) {
657
+ return __awaiter(this, void 0, void 0, function* () {
658
+ var _a, _b, _c, _d;
659
+ try {
660
+ let page = 1;
661
+ let hasMoreActivities = true;
662
+ let activity = type === 0
663
+ ? followingActivitiesQuery
664
+ : type === 1
665
+ ? globalActivitiesQuery
666
+ : followingActivitiesQuery;
667
+ while (hasMoreActivities) {
668
+ const activities = yield fetcher(activity, {
669
+ page,
670
+ perPage: 50,
671
+ });
672
+ if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
673
+ const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
674
+ for (let activ of activiti) {
675
+ if (!activ.isLiked && activ.id) {
676
+ try {
677
+ const like = yield fetcher(likeActivityMutation, {
678
+ activityId: activ.id,
679
+ });
680
+ // const ToggleLike = like?.data?.ToggleLike
681
+ console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
682
+ }
683
+ catch (error) {
684
+ console.error(`Activity possibly deleted. ${error.message}`);
685
+ }
686
+ }
687
+ else {
688
+ console.log(`${activityBy(activ)} 🔵`);
689
+ }
690
+ // avoiding rate-limit
691
+ yield new Promise((resolve) => {
692
+ setTimeout(resolve, 1500);
693
+ });
694
+ }
695
+ page++;
696
+ }
659
697
  else {
660
698
  // No more activities to like
661
699
  console.log(`\nProbably the end of activities.`);
@@ -669,6 +707,139 @@ Statistics (Manga):
669
707
  }
670
708
  });
671
709
  }
710
+ static LikeSpecificUser() {
711
+ return __awaiter(this, void 0, void 0, function* () {
712
+ var _a, _b, _c, _d;
713
+ try {
714
+ const { username } = yield inquirer.prompt([
715
+ {
716
+ type: "input",
717
+ name: "username",
718
+ message: "Username of the user:",
719
+ },
720
+ ]);
721
+ const userDetails = yield fetcher(userQuery, { username: username });
722
+ if (userDetails) {
723
+ let page = 1;
724
+ const perPage = 50;
725
+ const userId = (_b = (_a = userDetails === null || userDetails === void 0 ? void 0 : userDetails.data) === null || _a === void 0 ? void 0 : _a.User) === null || _b === void 0 ? void 0 : _b.id;
726
+ if (userId) {
727
+ while (true) {
728
+ const activities = yield fetcher(specificUserActivitiesQuery, {
729
+ page,
730
+ perPage,
731
+ userId,
732
+ });
733
+ const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
734
+ // Break the loop if no more activities are found
735
+ if (!activiti || activiti.length === 0) {
736
+ console.log("No more activities found.");
737
+ break;
738
+ }
739
+ for (let activ of activiti) {
740
+ if (!activ.isLiked && activ.id) {
741
+ try {
742
+ const like = yield fetcher(likeActivityMutation, {
743
+ activityId: activ.id,
744
+ });
745
+ console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
746
+ }
747
+ catch (error) {
748
+ console.error(`Activity possibly deleted. ${error.message}`);
749
+ }
750
+ }
751
+ else {
752
+ console.log(`${activityBy(activ)} 🔵`);
753
+ }
754
+ // Avoiding rate limit
755
+ yield new Promise((resolve) => {
756
+ setTimeout(resolve, 1500);
757
+ });
758
+ }
759
+ // Go to the next page
760
+ page += 1;
761
+ }
762
+ }
763
+ }
764
+ }
765
+ catch (error) {
766
+ console.error(`\nError from LikeSpecificUser. ${error.message}`);
767
+ }
768
+ });
769
+ }
770
+ static LikeFollowingActivityV2(perPage) {
771
+ return __awaiter(this, void 0, void 0, function* () {
772
+ var _a, _b, _c, _d, _e;
773
+ try {
774
+ if (!(yield Auth.isLoggedIn())) {
775
+ console.error(`\nPlease log in to use this feature.`);
776
+ return;
777
+ }
778
+ const allFollowingUsers = [];
779
+ let hasNextPage = true;
780
+ let page = 1;
781
+ // Fetch all following users
782
+ while (hasNextPage) {
783
+ const followingUsers = yield fetcher(userFollowingQuery, {
784
+ userId: yield Auth.MyUserId(),
785
+ page,
786
+ });
787
+ if (!((_b = (_a = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.following)) {
788
+ console.error(`\nFailed to fetch following users.`);
789
+ return;
790
+ }
791
+ allFollowingUsers.push(...followingUsers.data.Page.following);
792
+ hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
793
+ page++;
794
+ }
795
+ // Extract the IDs of all following users
796
+ const followingUserIds = allFollowingUsers.map((user) => user.id);
797
+ console.log(`\nTotal Following: ${followingUserIds.length}\nApproximately ${followingUserIds.length * perPage} activities to like.\nWill take around ${((followingUserIds.length * perPage * 1200) /
798
+ 1000 /
799
+ 60).toFixed(2)} minutes.`);
800
+ // Traverse the array and fetch users' activities one by one
801
+ let userNumber = 0;
802
+ for (const userId of followingUserIds) {
803
+ userNumber++;
804
+ console.log(`\n[${userNumber}]\tID: ${userId}`);
805
+ // Fetch `perPage` activities for the current user
806
+ const activities = yield fetcher(specificUserActivitiesQuery, {
807
+ userId,
808
+ page: 1, // Always fetch from the first page
809
+ perPage,
810
+ });
811
+ if (!((_e = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities) === null || _e === void 0 ? void 0 : _e.length)) {
812
+ console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
813
+ continue;
814
+ }
815
+ const activiti = activities.data.Page.activities;
816
+ for (let i = 0; i < activiti.length; i++) {
817
+ const activ = activiti[i];
818
+ if (!activ.isLiked && activ.id) {
819
+ try {
820
+ const like = yield fetcher(likeActivityMutation, {
821
+ activityId: activ.id,
822
+ });
823
+ console.info(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "✅" : "❌"}`);
824
+ }
825
+ catch (error) {
826
+ console.error(`[${userNumber}/${i + 1}/${activiti.length}] Activity possibly deleted. ${error.message}`);
827
+ }
828
+ }
829
+ else {
830
+ console.log(`[${userNumber}/${i + 1}/${activiti.length}] ${activityBy(activ)} 🔵`);
831
+ }
832
+ // Avoid rate-limiting
833
+ yield new Promise((resolve) => setTimeout(resolve, 1200));
834
+ }
835
+ }
836
+ console.log(`\n✅ All activities liked successfully.`);
837
+ }
838
+ catch (error) {
839
+ console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
840
+ }
841
+ });
842
+ }
672
843
  static AutoLike() {
673
844
  return __awaiter(this, void 0, void 0, function* () {
674
845
  try {
@@ -684,16 +855,20 @@ Statistics (Manga):
684
855
  choices: [
685
856
  { name: "Following", value: 1 },
686
857
  { name: "Global", value: 2 },
858
+ { name: "Specific User", value: 3 },
687
859
  ],
688
860
  pageSize: 10,
689
861
  },
690
862
  ]);
691
863
  switch (activityType) {
692
864
  case 1:
693
- yield this.likeFollowing();
865
+ yield this.LikeFollowing();
694
866
  break;
695
867
  case 2:
696
- console.warn(`\nNot yet implemented!`);
868
+ yield this.Like(1);
869
+ break;
870
+ case 3:
871
+ yield this.LikeSpecificUser();
697
872
  break;
698
873
  default:
699
874
  console.error(`\nInvalid choice. (${activityType})`);
@@ -2,11 +2,12 @@
2
2
  * Sends a GraphQL request to the AniList API.
3
3
  *
4
4
  * This function constructs a request with the provided query and variables,
5
- * handles authorization, and processes the API response.
5
+ * handles authorization, and processes the API response. If a rate-limit error (429) is returned,
6
+ * it waits for 1 minute and retries the request.
6
7
  *
7
8
  * @param {string} query - The AniList GraphQL query to be executed.
8
9
  * @param {object} variables - An object containing the variables for the query.
9
10
  * @returns {Promise<object|null>} The response from the API as a JSON object if successful; otherwise, null.
10
11
  */
11
- declare function fetcher(query: string, variables?: object): Promise<any | null>;
12
+ declare function fetcher(query: string, variables: object): Promise<object | null>;
12
13
  export { fetcher };