@irfanshadikrishad/anilist 1.3.2-forbidden.1 → 1.4.0-forbidden.6

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.
@@ -7,19 +7,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { Cipher } from "@irfanshadikrishad/cipher";
10
11
  import fs from "fs";
11
12
  import inquirer from "inquirer";
12
13
  import fetch from "node-fetch";
13
14
  import open from "open";
14
15
  import os from "os";
15
16
  import path from "path";
17
+ import { exit } from "process";
18
+ import Spinner from "tiny-spinner";
16
19
  import { fetcher } from "./fetcher.js";
17
- import { AniList, MyAnimeList } from "./lists.js";
20
+ import { AniDB, AniList, MyAnimeList } from "./lists.js";
18
21
  import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
19
- import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userQuery, } from "./queries.js";
22
+ import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, toggleFollowMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
23
+ import { responsiveOutput } from "./truncate.js";
20
24
  import { activityBy, aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
21
25
  const home_dir = os.homedir();
22
26
  const save_path = path.join(home_dir, ".anilist_token");
27
+ const spinner = new Spinner();
28
+ const vigenere = new Cipher.Vigenere("anilist");
23
29
  class Auth {
24
30
  /**
25
31
  * Get access-token from user
@@ -34,20 +40,29 @@ class Auth {
34
40
  message: "Please enter your AniList access token:",
35
41
  },
36
42
  ]);
43
+ if (!token) {
44
+ console.warn("\nNo token entered. Please try again.");
45
+ return null;
46
+ }
37
47
  return token;
38
48
  }
39
49
  catch (error) {
40
- console.error(`\nSomething went wrong. ${error.message}`);
50
+ console.error(`\nAn error occurred while getting the access token: ${error.message}`);
51
+ return null;
41
52
  }
42
53
  });
43
54
  }
44
55
  static StoreAccessToken(token) {
45
56
  return __awaiter(this, void 0, void 0, function* () {
46
57
  try {
47
- fs.writeFileSync(save_path, token, { encoding: "utf8" });
58
+ if (!token) {
59
+ console.warn("\nNo token provided. Nothing to store.");
60
+ return;
61
+ }
62
+ fs.writeFileSync(save_path, vigenere.encrypt(token), { encoding: "utf8" });
48
63
  }
49
64
  catch (error) {
50
- console.error(`\nError storing acess-token. ${error.message}`);
65
+ console.error(`\nError storing access token: ${error.message}`);
51
66
  }
52
67
  });
53
68
  }
@@ -55,7 +70,7 @@ class Auth {
55
70
  return __awaiter(this, void 0, void 0, function* () {
56
71
  try {
57
72
  if (fs.existsSync(save_path)) {
58
- return fs.readFileSync(save_path, { encoding: "utf8" });
73
+ return vigenere.decrypt(fs.readFileSync(save_path, { encoding: "utf8" }));
59
74
  }
60
75
  else {
61
76
  return null;
@@ -63,6 +78,7 @@ class Auth {
63
78
  }
64
79
  catch (error) {
65
80
  console.error(`\nError retriving acess-token. ${error.message}`);
81
+ return null;
66
82
  }
67
83
  });
68
84
  }
@@ -109,7 +125,7 @@ class Auth {
109
125
  }
110
126
  static Myself() {
111
127
  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, _t, _u, _v, _w;
128
+ 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
129
  try {
114
130
  if (yield Auth.isLoggedIn()) {
115
131
  const headers = {
@@ -130,35 +146,47 @@ class Auth {
130
146
  perPage: 10,
131
147
  });
132
148
  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;
149
+ // Get follower/following information
150
+ const req_followers = yield fetcher(userFollowersQuery, {
151
+ userId: user === null || user === void 0 ? void 0 : user.id,
152
+ });
153
+ const req_following = yield fetcher(userFollowingQuery, {
154
+ userId: user === null || user === void 0 ? void 0 : user.id,
155
+ });
156
+ 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;
157
+ 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;
133
158
  console.log(`
134
159
  ID: ${user === null || user === void 0 ? void 0 : user.id}
135
160
  Name: ${user === null || user === void 0 ? void 0 : user.name}
136
161
  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}
162
+ profileColor: ${(_j = user === null || user === void 0 ? void 0 : user.options) === null || _j === void 0 ? void 0 : _j.profileColor}
163
+ timeZone: ${(_k = user === null || user === void 0 ? void 0 : user.options) === null || _k === void 0 ? void 0 : _k.timezone}
164
+ activityMergeTime: ${(_l = user === null || user === void 0 ? void 0 : user.options) === null || _l === void 0 ? void 0 : _l.activityMergeTime}
140
165
  donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
141
166
  donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
142
167
  unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
143
168
  Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
144
169
  Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
170
+
171
+ Followers: ${followersCount}
172
+ Following: ${followingCount}
145
173
 
146
174
  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
- Episodes Watched: ${(_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.episodesWatched}
175
+ 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}
176
+ 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}
177
+ 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}
178
+ 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}
151
179
 
152
180
  Statistics (Manga):
153
- Count: ${(_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.count}
154
- Mean Score: ${(_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.meanScore}
155
- Chapters Read: ${(_u = (_t = user === null || user === void 0 ? void 0 : user.statistics) === null || _t === void 0 ? void 0 : _t.manga) === null || _u === void 0 ? void 0 : _u.chaptersRead}
156
- Volumes Read: ${(_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.volumesRead}
181
+ 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}
182
+ 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}
183
+ 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}
184
+ 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}
157
185
  `);
158
186
  console.log(`\nRecent Activities:`);
159
187
  if (activities.length > 0) {
160
188
  activities.map(({ status, progress, media, createdAt }) => {
161
- console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
189
+ responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
162
190
  });
163
191
  }
164
192
  return user;
@@ -181,15 +209,12 @@ Statistics (Manga):
181
209
  static isLoggedIn() {
182
210
  return __awaiter(this, void 0, void 0, function* () {
183
211
  try {
184
- if ((yield Auth.RetriveAccessToken()) !== null) {
185
- return true;
186
- }
187
- else {
188
- return false;
189
- }
212
+ const token = yield Auth.RetriveAccessToken();
213
+ return token !== null;
190
214
  }
191
215
  catch (error) {
192
- console.error(`\nError getting isLoggedIn. ${error.message}`);
216
+ console.error(`Error checking login status: ${error.message}`);
217
+ return false;
193
218
  }
194
219
  });
195
220
  }
@@ -203,15 +228,15 @@ Statistics (Manga):
203
228
  console.log(`\nLogout successful. See you soon, ${username}.`);
204
229
  }
205
230
  catch (error) {
206
- console.error("\nError logging out:", error);
231
+ console.error("\nFailed to remove the save file during logout:", error.message);
207
232
  }
208
233
  }
209
234
  else {
210
- console.error("\nYou may already be logged out.");
235
+ console.warn("\nNo active session found. You may already be logged out.");
211
236
  }
212
237
  }
213
238
  catch (error) {
214
- console.error(`\nError logging out. ${error.message}`);
239
+ console.error(`\nAn error occurred during logout: ${error.message}`);
215
240
  }
216
241
  });
217
242
  }
@@ -222,20 +247,7 @@ Statistics (Manga):
222
247
  console.warn(`\nUser not logged in.`);
223
248
  return null;
224
249
  }
225
- const token = yield Auth.RetriveAccessToken();
226
- const request = yield fetch(aniListEndpoint, {
227
- method: "POST",
228
- headers: {
229
- "Content-Type": "application/json",
230
- "Authorization": `Bearer ${token}`,
231
- },
232
- body: JSON.stringify({ query: currentUserQuery }),
233
- });
234
- if (!(request.status === 200)) {
235
- console.error(`Failed to fetch user data. Status: ${request.status}`);
236
- return null;
237
- }
238
- const { data } = yield request.json();
250
+ const { data } = yield fetcher(currentUserQuery, {});
239
251
  return (_b = (_a = data === null || data === void 0 ? void 0 : data.Viewer) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
240
252
  });
241
253
  }
@@ -246,20 +258,7 @@ Statistics (Manga):
246
258
  console.log(`\nUser not logged in.`);
247
259
  return null;
248
260
  }
249
- const token = yield Auth.RetriveAccessToken();
250
- const request = yield fetch(aniListEndpoint, {
251
- method: "POST",
252
- headers: {
253
- "Content-Type": "application/json",
254
- "Authorization": `Bearer ${token}`,
255
- },
256
- body: JSON.stringify({ query: currentUserQuery }),
257
- });
258
- if (!request.ok) {
259
- console.error(`Failed to fetch user data. Status: ${request.status}`);
260
- return null;
261
- }
262
- const { data } = yield request.json();
261
+ const { data } = yield fetcher(currentUserQuery, {});
263
262
  return (_b = (_a = data === null || data === void 0 ? void 0 : data.Viewer) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null;
264
263
  });
265
264
  }
@@ -267,72 +266,70 @@ Statistics (Manga):
267
266
  return __awaiter(this, void 0, void 0, function* () {
268
267
  var _a, _b, _c, _d, _e, _f;
269
268
  try {
270
- if (yield Auth.isLoggedIn()) {
271
- const { activityType } = yield inquirer.prompt([
272
- {
273
- type: "list",
274
- name: "activityType",
275
- message: "What type of activity you want to delete?",
276
- choices: [
277
- { name: "All Activity", value: 0 },
278
- { name: "Text Activity", value: 1 },
279
- { name: "Media List Activity", value: 2 },
280
- { name: "Anime List Activity", value: 3 },
281
- { name: "Manga List Activity", value: 4 },
282
- { name: "Message Activity", value: 5 },
283
- ],
284
- },
285
- ]);
286
- const queryMap = {
287
- 0: activityAllQuery,
288
- 1: activityTextQuery,
289
- 2: activityMediaList,
290
- 3: activityAnimeListQuery,
291
- 4: activityMangaListQuery,
292
- 5: activityMessageQuery,
293
- };
294
- const query = queryMap[activityType];
295
- let hasMoreActivities = true;
296
- let totalCount = 0;
297
- while (hasMoreActivities) {
298
- const response = yield fetcher(query, {
299
- page: 1,
300
- perPage: 50,
301
- userId: yield Auth.MyUserId(),
302
- });
303
- if ((_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities) {
304
- let count = 0;
305
- const activities = (_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.activities;
306
- if (!activities || activities.length === 0) {
307
- console.log(`\nNo more activities available.`);
308
- hasMoreActivities = false;
309
- }
310
- else {
311
- for (const act of activities) {
312
- // Ensure ID is present to avoid unintended errors
313
- if (act === null || act === void 0 ? void 0 : act.id) {
314
- const deleteResponse = yield fetcher(deleteActivityMutation, {
315
- id: act === null || act === void 0 ? void 0 : act.id,
316
- });
317
- 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;
318
- count++;
319
- totalCount++;
320
- console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "āœ…" : "āŒ"}`);
321
- // Avoiding rate-limit
322
- yield new Promise((resolve) => setTimeout(resolve, 1100));
323
- }
324
- }
325
- }
269
+ if (!(yield Auth.isLoggedIn())) {
270
+ console.error(`\nPlease log in to delete your activities.`);
271
+ return;
272
+ }
273
+ const { activityType } = yield inquirer.prompt([
274
+ {
275
+ type: "list",
276
+ name: "activityType",
277
+ message: "What type of activity you want to delete?",
278
+ choices: [
279
+ { name: "All Activity", value: 0 },
280
+ { name: "Text Activity", value: 1 },
281
+ { name: "Media List Activity", value: 2 },
282
+ { name: "Anime List Activity", value: 3 },
283
+ { name: "Manga List Activity", value: 4 },
284
+ { name: "Message Activity", value: 5 },
285
+ ],
286
+ },
287
+ ]);
288
+ const queryMap = {
289
+ 0: activityAllQuery,
290
+ 1: activityTextQuery,
291
+ 2: activityMediaList,
292
+ 3: activityAnimeListQuery,
293
+ 4: activityMangaListQuery,
294
+ 5: activityMessageQuery,
295
+ };
296
+ const query = queryMap[activityType];
297
+ let hasMoreActivities = true;
298
+ let totalCount = 0;
299
+ while (hasMoreActivities) {
300
+ const response = yield fetcher(query, {
301
+ page: 1,
302
+ perPage: 50,
303
+ userId: yield Auth.MyUserId(),
304
+ });
305
+ if ((_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities) {
306
+ let count = 0;
307
+ const activities = (_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.activities;
308
+ if (!activities || activities.length === 0) {
309
+ console.log(`\nNo more activities available.`);
310
+ hasMoreActivities = false;
326
311
  }
327
312
  else {
328
- // In case of an unexpected null response, exit the loop
329
- console.log(`\nProbably deleted all the activities of this type.`);
330
- hasMoreActivities = false;
313
+ for (const act of activities) {
314
+ if (act === null || act === void 0 ? void 0 : act.id) {
315
+ const deleteResponse = yield fetcher(deleteActivityMutation, {
316
+ id: act === null || act === void 0 ? void 0 : act.id,
317
+ });
318
+ 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;
319
+ count++;
320
+ totalCount++;
321
+ console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "āœ…" : "āŒ"}`);
322
+ // Avoiding rate-limit
323
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
324
+ }
325
+ }
331
326
  }
332
327
  }
333
- }
334
- else {
335
- console.error(`\nPlease log in to delete your activities.`);
328
+ else {
329
+ // In case of an unexpected null response, exit the loop
330
+ console.log(`\nProbably deleted all the activities of this type.`);
331
+ hasMoreActivities = false;
332
+ }
336
333
  }
337
334
  }
338
335
  catch (error) {
@@ -343,54 +340,51 @@ Statistics (Manga):
343
340
  static DeleteMyAnimeList() {
344
341
  return __awaiter(this, void 0, void 0, function* () {
345
342
  var _a, _b, _c, _d;
346
- if (yield Auth.isLoggedIn()) {
347
- const userID = yield Auth.MyUserId();
348
- if (userID) {
349
- const response = yield fetcher(currentUserAnimeList, { id: userID });
350
- if (response !== null) {
351
- 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;
352
- if (lists.length > 0) {
353
- const { selectedList } = yield inquirer.prompt([
354
- {
355
- type: "list",
356
- name: "selectedList",
357
- message: "Select an anime list:",
358
- choices: lists.map((list) => list.name),
359
- pageSize: 10,
360
- },
361
- ]);
362
- const selectedEntries = lists.find((list) => list.name === selectedList);
363
- if (selectedEntries) {
364
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
365
- for (const [, entry] of selectedEntries.entries.entries()) {
366
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
367
- 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);
368
- yield new Promise((resolve) => setTimeout(resolve, 1100));
369
- }
370
- else {
371
- console.log(`No id in entry.`);
372
- console.log(entry);
373
- }
374
- }
343
+ if (!(yield Auth.isLoggedIn())) {
344
+ console.error(`\nPlease log in first to delete your lists.`);
345
+ return;
346
+ }
347
+ if (!(yield Auth.MyUserId())) {
348
+ console.log(`\nFailed getting current user Id.`);
349
+ return;
350
+ }
351
+ const response = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
352
+ if (response !== null) {
353
+ 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;
354
+ if (lists.length > 0) {
355
+ const { selectedList } = yield inquirer.prompt([
356
+ {
357
+ type: "list",
358
+ name: "selectedList",
359
+ message: "Select an anime list:",
360
+ choices: lists.map((list) => list.name),
361
+ pageSize: 10,
362
+ },
363
+ ]);
364
+ const selectedEntries = lists.find((list) => list.name === selectedList);
365
+ if (selectedEntries) {
366
+ console.log(`\nDeleting entries of '${selectedEntries.name}':`);
367
+ for (const [, entry] of selectedEntries.entries.entries()) {
368
+ if (entry === null || entry === void 0 ? void 0 : entry.id) {
369
+ 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);
370
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
375
371
  }
376
372
  else {
377
- console.log("No entries found.");
373
+ console.log(`No id in entry.`);
374
+ console.log(entry);
378
375
  }
379
376
  }
380
- else {
381
- console.log(`\nNo anime(s) found in any list.`);
382
- }
383
377
  }
384
378
  else {
385
- console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
379
+ console.log("No entries found.");
386
380
  }
387
381
  }
388
382
  else {
389
- console.log(`\nFailed getting current user Id.`);
383
+ console.log(`\nNo anime(s) found in any list.`);
390
384
  }
391
385
  }
392
386
  else {
393
- console.error(`\nPlease log in first to delete your lists.`);
387
+ console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
394
388
  }
395
389
  });
396
390
  }
@@ -417,54 +411,50 @@ Statistics (Manga):
417
411
  return __awaiter(this, void 0, void 0, function* () {
418
412
  var _a, _b, _c, _d;
419
413
  try {
420
- if (yield Auth.isLoggedIn()) {
421
- const userID = yield Auth.MyUserId();
422
- if (userID) {
423
- const response = yield fetcher(currentUserMangaList, { id: userID });
424
- if (response === null || response === void 0 ? void 0 : response.data) {
425
- 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;
426
- if (lists.length > 0) {
427
- const { selectedList } = yield inquirer.prompt([
428
- {
429
- type: "list",
430
- name: "selectedList",
431
- message: "Select a manga list:",
432
- choices: lists.map((list) => list.name),
433
- pageSize: 10,
434
- },
435
- ]);
436
- const selectedEntries = lists.find((list) => list.name === selectedList);
437
- if (selectedEntries) {
438
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
439
- for (const [, entry] of selectedEntries.entries.entries()) {
440
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
441
- 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);
442
- yield new Promise((resolve) => setTimeout(resolve, 1100));
443
- }
444
- else {
445
- console.log(`No id in entry.`);
446
- console.log(entry);
447
- }
448
- }
449
- }
450
- else {
451
- console.error("\nNo entries found.");
452
- }
414
+ if (!(yield Auth.isLoggedIn())) {
415
+ console.error(`\nPlease log in first to delete your lists.`);
416
+ return;
417
+ }
418
+ if (!(yield Auth.MyUserId())) {
419
+ console.error(`\nFailed getting current user Id.`);
420
+ return;
421
+ }
422
+ const response = yield fetcher(currentUserMangaList, { id: yield Auth.MyUserId() });
423
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
424
+ console.error(`\nSomething went wrong. ${(_a = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
425
+ return;
426
+ }
427
+ const lists = (_c = (_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.MediaListCollection) === null || _c === void 0 ? void 0 : _c.lists;
428
+ if (lists.length > 0) {
429
+ const { selectedList } = yield inquirer.prompt([
430
+ {
431
+ type: "list",
432
+ name: "selectedList",
433
+ message: "Select a manga list:",
434
+ choices: lists.map((list) => list.name),
435
+ pageSize: 10,
436
+ },
437
+ ]);
438
+ const selectedEntries = lists.find((list) => list.name === selectedList);
439
+ if (selectedEntries) {
440
+ console.log(`\nDeleting entries of '${selectedEntries.name}':`);
441
+ for (const [, entry] of selectedEntries.entries.entries()) {
442
+ if (entry === null || entry === void 0 ? void 0 : entry.id) {
443
+ yield Auth.DeleteMangaById(entry === null || entry === void 0 ? void 0 : entry.id, (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.title);
444
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
453
445
  }
454
446
  else {
455
- console.error(`\nNo manga(s) found in any list.`);
447
+ console.log(`No id in entry.`);
448
+ console.log(entry);
456
449
  }
457
450
  }
458
- else {
459
- console.error(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
460
- }
461
451
  }
462
452
  else {
463
- console.error(`\nFailed getting current user Id.`);
453
+ console.error("\nNo entries found.");
464
454
  }
465
455
  }
466
456
  else {
467
- console.error(`\nPlease log in first to delete your lists.`);
457
+ console.error(`\nNo manga(s) found in any list.`);
468
458
  }
469
459
  }
470
460
  catch (error) {
@@ -493,23 +483,20 @@ Statistics (Manga):
493
483
  }
494
484
  static Write(status) {
495
485
  return __awaiter(this, void 0, void 0, function* () {
496
- var _a;
497
486
  try {
498
487
  if (!(yield Auth.isLoggedIn())) {
499
488
  console.error(`\nPlease login to use this feature.`);
500
489
  return;
501
490
  }
502
- const data = yield fetcher(saveTextActivityMutation, {
503
- status: status +
504
- `<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
491
+ const { data } = yield fetcher(saveTextActivityMutation, {
492
+ status: status,
505
493
  });
506
494
  if (!data) {
507
495
  console.error(`\nSomething went wrong. ${data}.`);
508
496
  return;
509
497
  }
510
- const savedActivity = (_a = data.data) === null || _a === void 0 ? void 0 : _a.SaveTextActivity;
511
- if (savedActivity === null || savedActivity === void 0 ? void 0 : savedActivity.id) {
512
- console.log(`\n[${savedActivity.id}] status saved successfully!`);
498
+ if (data.SaveTextActivity.id) {
499
+ console.log(`\n[${data.SaveTextActivity.id}] status saved successfully!`);
513
500
  }
514
501
  }
515
502
  catch (error) {
@@ -528,6 +515,7 @@ Statistics (Manga):
528
515
  choices: [
529
516
  { name: "Exported JSON file.", value: 1 },
530
517
  { name: "MyAnimeList (XML)", value: 2 },
518
+ { name: "AniDB (json-large)", value: 3 },
531
519
  ],
532
520
  pageSize: 10,
533
521
  },
@@ -539,6 +527,9 @@ Statistics (Manga):
539
527
  case 2:
540
528
  yield MyAnimeList.importAnime();
541
529
  break;
530
+ case 3:
531
+ yield AniDB.importAnime();
532
+ break;
542
533
  default:
543
534
  console.log(`\nInvalid Choice.`);
544
535
  break;
@@ -583,34 +574,39 @@ Statistics (Manga):
583
574
  }
584
575
  static LikeFollowing() {
585
576
  return __awaiter(this, void 0, void 0, function* () {
586
- var _a, _b, _c, _d;
577
+ var _a, _b, _c, _d, _e, _f;
587
578
  try {
588
579
  let page = 1;
589
580
  let hasMoreActivities = true;
590
581
  let retryCount = 0;
591
582
  const maxRetries = 5;
583
+ let likedCount = 0;
592
584
  while (hasMoreActivities) {
593
585
  const activities = yield fetcher(followingActivitiesQuery, {
594
586
  page,
595
587
  perPage: 50,
596
588
  });
597
589
  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) {
590
+ spinner.success(`Got ${(_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.length} activities..`);
598
591
  retryCount = 0; // Reset retry count on successful fetch
599
- 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;
592
+ const activiti = (_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities;
600
593
  for (let activ of activiti) {
601
594
  if (!activ.isLiked && activ.id) {
602
595
  try {
603
596
  const like = yield fetcher(likeActivityMutation, {
604
597
  activityId: activ.id,
605
598
  });
606
- console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"}`);
599
+ if (like === null || like === void 0 ? void 0 : like.data) {
600
+ likedCount++;
601
+ }
602
+ responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"} ${activityBy(activ, likedCount)}`);
607
603
  }
608
604
  catch (error) {
609
605
  console.error(`Activity possibly deleted. ${error.message}`);
610
606
  }
611
607
  }
612
608
  else {
613
- console.log(`${activityBy(activ)} šŸ”µ`);
609
+ responsiveOutput(`"šŸ”µ" ${activityBy(activ, likedCount)}`);
614
610
  }
615
611
  // avoiding rate-limit
616
612
  yield new Promise((resolve) => {
@@ -621,13 +617,13 @@ Statistics (Manga):
621
617
  }
622
618
  else {
623
619
  if (retryCount < maxRetries) {
620
+ spinner.start("Getting activities...");
624
621
  retryCount++;
625
- console.warn(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
626
- yield new Promise((resolve) => setTimeout(resolve, 3000));
622
+ spinner.update(`Empty activities returned. Retrying... (${retryCount}/${maxRetries})`);
623
+ yield new Promise((resolve) => setTimeout(resolve, 2000));
627
624
  }
628
625
  else {
629
- console.log(`\nProbably the end of activities after ${maxRetries} retries.`);
630
- console.info(activities);
626
+ spinner.error(`Probably the end of activities after ${maxRetries} retries.`);
631
627
  hasMoreActivities = false;
632
628
  }
633
629
  }
@@ -638,24 +634,22 @@ Statistics (Manga):
638
634
  }
639
635
  });
640
636
  }
641
- static Like(type) {
637
+ static LikeGlobal() {
642
638
  return __awaiter(this, void 0, void 0, function* () {
643
- var _a, _b, _c, _d;
639
+ var _a, _b, _c, _d, _e, _f;
644
640
  try {
645
641
  let page = 1;
646
642
  let hasMoreActivities = true;
647
- let activity = type === 0
648
- ? followingActivitiesQuery
649
- : type === 1
650
- ? globalActivitiesQuery
651
- : followingActivitiesQuery;
643
+ let likedCount = 0;
644
+ spinner.start(`Getting global activities...`);
652
645
  while (hasMoreActivities) {
653
- const activities = yield fetcher(activity, {
646
+ const activities = yield fetcher(globalActivitiesQuery, {
654
647
  page,
655
648
  perPage: 50,
656
649
  });
657
650
  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) {
658
651
  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;
652
+ spinner.success(`Got ${activiti.length} activities...`);
659
653
  for (let activ of activiti) {
660
654
  if (!activ.isLiked && activ.id) {
661
655
  try {
@@ -663,14 +657,15 @@ Statistics (Manga):
663
657
  activityId: activ.id,
664
658
  });
665
659
  // const ToggleLike = like?.data?.ToggleLike
666
- console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"}`);
660
+ likedCount++;
661
+ responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"} ${activityBy(activ, likedCount)}`);
667
662
  }
668
663
  catch (error) {
669
664
  console.error(`Activity possibly deleted. ${error.message}`);
670
665
  }
671
666
  }
672
667
  else {
673
- console.log(`${activityBy(activ)} šŸ”µ`);
668
+ responsiveOutput(`šŸ”µ ${activityBy(activ, likedCount)}`);
674
669
  }
675
670
  // avoiding rate-limit
676
671
  yield new Promise((resolve) => {
@@ -681,8 +676,7 @@ Statistics (Manga):
681
676
  }
682
677
  else {
683
678
  // No more activities to like
684
- console.log(`\nProbably the end of activities.`);
685
- console.info(activities);
679
+ spinner.error(`Probably the end of activities. ${(_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities}`);
686
680
  hasMoreActivities = false;
687
681
  }
688
682
  }
@@ -694,7 +688,7 @@ Statistics (Manga):
694
688
  }
695
689
  static LikeSpecificUser() {
696
690
  return __awaiter(this, void 0, void 0, function* () {
697
- var _a, _b, _c, _d;
691
+ var _a, _b, _c, _d, _e, _f;
698
692
  try {
699
693
  const { username } = yield inquirer.prompt([
700
694
  {
@@ -704,10 +698,12 @@ Statistics (Manga):
704
698
  },
705
699
  ]);
706
700
  const userDetails = yield fetcher(userQuery, { username: username });
707
- if (userDetails) {
701
+ spinner.start(`Getting activities by ${username}`);
702
+ if ((_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) {
708
703
  let page = 1;
709
704
  const perPage = 50;
710
- 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;
705
+ const userId = (_d = (_c = userDetails === null || userDetails === void 0 ? void 0 : userDetails.data) === null || _c === void 0 ? void 0 : _c.User) === null || _d === void 0 ? void 0 : _d.id;
706
+ let likedCount = 0;
711
707
  if (userId) {
712
708
  while (true) {
713
709
  const activities = yield fetcher(specificUserActivitiesQuery, {
@@ -715,26 +711,28 @@ Statistics (Manga):
715
711
  perPage,
716
712
  userId,
717
713
  });
718
- 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;
714
+ const activiti = (_f = (_e = activities === null || activities === void 0 ? void 0 : activities.data) === null || _e === void 0 ? void 0 : _e.Page) === null || _f === void 0 ? void 0 : _f.activities;
719
715
  // Break the loop if no more activities are found
720
716
  if (!activiti || activiti.length === 0) {
721
- console.log("No more activities found.");
717
+ spinner.error("No more activities found.");
722
718
  break;
723
719
  }
720
+ spinner.success(`Got ${activiti.length} activities...`);
724
721
  for (let activ of activiti) {
725
722
  if (!activ.isLiked && activ.id) {
726
723
  try {
727
724
  const like = yield fetcher(likeActivityMutation, {
728
725
  activityId: activ.id,
729
726
  });
730
- console.info(`${activityBy(activ)} ${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"}`);
727
+ likedCount++;
728
+ responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"} ${activityBy(activ, likedCount)}`);
731
729
  }
732
730
  catch (error) {
733
731
  console.error(`Activity possibly deleted. ${error.message}`);
734
732
  }
735
733
  }
736
734
  else {
737
- console.log(`${activityBy(activ)} šŸ”µ`);
735
+ responsiveOutput(`šŸ”µ ${activityBy(activ, likedCount)}`);
738
736
  }
739
737
  // Avoiding rate limit
740
738
  yield new Promise((resolve) => {
@@ -746,12 +744,116 @@ Statistics (Manga):
746
744
  }
747
745
  }
748
746
  }
747
+ else {
748
+ spinner.error(`User ${username} does not exist.`);
749
+ exit(1);
750
+ }
749
751
  }
750
752
  catch (error) {
751
753
  console.error(`\nError from LikeSpecificUser. ${error.message}`);
752
754
  }
753
755
  });
754
756
  }
757
+ static LikeFollowingActivityV2(perPage) {
758
+ return __awaiter(this, void 0, void 0, function* () {
759
+ var _a, _b, _c, _d, _e;
760
+ try {
761
+ if (!(yield Auth.isLoggedIn())) {
762
+ console.error(`\nPlease log in to use this feature.`);
763
+ return;
764
+ }
765
+ const allFollowingUsers = [];
766
+ let hasNextPage = true;
767
+ let page = 1;
768
+ let liked = 0;
769
+ // ------------------------
770
+ // Fetch all following users
771
+ // ------------------------
772
+ spinner.start(`Gathering following information...`);
773
+ while (hasNextPage) {
774
+ spinner.update(`Fetched page ${page}...`);
775
+ const followingUsers = yield fetcher(userFollowingQuery, {
776
+ userId: yield Auth.MyUserId(),
777
+ page,
778
+ });
779
+ 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)) {
780
+ console.error(`\nFailed to fetch following users.`);
781
+ return;
782
+ }
783
+ allFollowingUsers.push(...followingUsers.data.Page.following);
784
+ hasNextPage = followingUsers.data.Page.pageInfo.hasNextPage;
785
+ page++;
786
+ }
787
+ spinner.stop(`Got ${allFollowingUsers.length} following user.`);
788
+ // Extract the IDs of all following users
789
+ const followingUserIds = allFollowingUsers.map((user) => user.id);
790
+ // --------------------
791
+ // APPROXIMATE TIME
792
+ // --------------------
793
+ const totalActivities = followingUserIds.length * perPage;
794
+ const perActivityTimeInSec = 1;
795
+ const rateLimitTimeInSec = 60;
796
+ const batchSize = 29;
797
+ const batches = Math.floor(totalActivities / batchSize);
798
+ const remaining = totalActivities % batchSize;
799
+ const processingTime = batches * batchSize * perActivityTimeInSec +
800
+ remaining * perActivityTimeInSec;
801
+ const waitTime = (batches - 1) * rateLimitTimeInSec;
802
+ const totalWaitTimeInSec = processingTime + (batches > 0 ? waitTime : 0);
803
+ const hours = Math.floor(totalWaitTimeInSec / 3600);
804
+ const minutes = Math.floor((totalWaitTimeInSec % 3600) / 60);
805
+ const seconds = totalWaitTimeInSec % 60;
806
+ const time = `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(2, "0")}m ${String(seconds).padStart(2, "0")}s`;
807
+ console.log(`\nTotal following: ${followingUserIds.length}\nApproximately ${totalActivities} to like.\nWill take around ${time}`);
808
+ // -------------------
809
+ // Traverse the array and
810
+ // fetch users' activities one by one
811
+ // -------------------
812
+ let userNumber = 0;
813
+ for (const userId of followingUserIds) {
814
+ userNumber++;
815
+ console.log(`\n[${userNumber}]\tID: ${userId}`);
816
+ // Fetch `perPage` activities for the current user
817
+ const activities = yield fetcher(specificUserActivitiesQuery, {
818
+ userId,
819
+ page: 1, // Always fetch from the first page
820
+ perPage,
821
+ });
822
+ 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)) {
823
+ console.log(`[${userNumber}] No activities found for User ID: ${userId}`);
824
+ continue;
825
+ }
826
+ const activiti = activities.data.Page.activities;
827
+ for (let i = 0; i < activiti.length; i++) {
828
+ const activ = activiti[i];
829
+ if (!activ.isLiked && activ.id) {
830
+ try {
831
+ const like = yield fetcher(likeActivityMutation, {
832
+ activityId: activ.id,
833
+ });
834
+ responsiveOutput(`${(like === null || like === void 0 ? void 0 : like.data) ? "āœ…" : "āŒ"} ${activityBy(activ, i + 1)}`);
835
+ if (like === null || like === void 0 ? void 0 : like.data) {
836
+ liked++;
837
+ }
838
+ }
839
+ catch (error) {
840
+ console.error(`Activity possibly deleted. ${error.message}`);
841
+ }
842
+ }
843
+ else {
844
+ responsiveOutput(`šŸ”µ ${activityBy(activ, i + 1)}`);
845
+ }
846
+ // Avoid rate-limiting
847
+ yield new Promise((resolve) => setTimeout(resolve, 1200));
848
+ }
849
+ }
850
+ console.log(`\nāœ… All ${liked} activities liked successfully.`);
851
+ }
852
+ catch (error) {
853
+ console.error(`\nError in LikeFollowingActivityV2: ${error.message}`);
854
+ }
855
+ });
856
+ }
755
857
  static AutoLike() {
756
858
  return __awaiter(this, void 0, void 0, function* () {
757
859
  try {
@@ -765,9 +867,10 @@ Statistics (Manga):
765
867
  name: "activityType",
766
868
  message: "Select activity type:",
767
869
  choices: [
768
- { name: "Following", value: 1 },
769
- { name: "Global", value: 2 },
770
- { name: "Specific User", value: 3 },
870
+ { name: "Following • v1", value: 1 },
871
+ { name: "Following • v2", value: 2 },
872
+ { name: "Global", value: 3 },
873
+ { name: "Specific User", value: 4 },
771
874
  ],
772
875
  pageSize: 10,
773
876
  },
@@ -776,10 +879,21 @@ Statistics (Manga):
776
879
  case 1:
777
880
  yield this.LikeFollowing();
778
881
  break;
779
- case 2:
780
- yield this.Like(1);
882
+ case 2: {
883
+ const { count } = yield inquirer.prompt([
884
+ {
885
+ type: "number",
886
+ name: "count",
887
+ message: "Likes to give:",
888
+ },
889
+ ]);
890
+ yield this.LikeFollowingActivityV2(count);
781
891
  break;
892
+ }
782
893
  case 3:
894
+ yield this.LikeGlobal();
895
+ break;
896
+ case 4:
783
897
  yield this.LikeSpecificUser();
784
898
  break;
785
899
  default:
@@ -792,4 +906,124 @@ Statistics (Manga):
792
906
  });
793
907
  }
794
908
  }
795
- export { Auth };
909
+ class Social {
910
+ /**
911
+ * Follow the users that follows you
912
+ */
913
+ static follow() {
914
+ return __awaiter(this, void 0, void 0, function* () {
915
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
916
+ try {
917
+ let pager = 1;
918
+ let hasNextPage = true;
919
+ let allFollowerUsers = [];
920
+ let followedBack = 0;
921
+ spinner.start("Fetching all the followers...");
922
+ while (hasNextPage) {
923
+ const followerUsers = yield fetcher(userFollowersQuery, {
924
+ userId: yield Auth.MyUserId(),
925
+ page: pager,
926
+ });
927
+ spinner.update(`Fetched page ${pager} of ${(_c = (_b = (_a = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.pageInfo) === null || _c === void 0 ? void 0 : _c.lastPage}...`);
928
+ if (!((_f = (_e = (_d = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.pageInfo) === null || _f === void 0 ? void 0 : _f.hasNextPage)) {
929
+ hasNextPage = false;
930
+ }
931
+ allFollowerUsers.push(...(((_h = (_g = followerUsers === null || followerUsers === void 0 ? void 0 : followerUsers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.followers) || []));
932
+ pager++;
933
+ }
934
+ spinner.stop("Fetched all the followers. Starting follow back.");
935
+ // Filter users that do no follow me
936
+ const notFollowing = allFollowerUsers
937
+ .filter(({ isFollowing }) => !isFollowing)
938
+ .map(({ id, name }) => ({ id: id, name: name }));
939
+ console.log(`\nTotal follower ${allFollowerUsers.length}.\nNot followed back ${notFollowing.length}\n`);
940
+ if (notFollowing.length <= 0) {
941
+ console.log(`Probably followed back all the users.`);
942
+ return;
943
+ }
944
+ // Traverse and follow back
945
+ const maxIdLength = Math.max(...notFollowing.map(({ id }) => String(id).length));
946
+ const maxNameLength = Math.max(...notFollowing.map(({ name }) => name.length));
947
+ for (let nf of notFollowing) {
948
+ try {
949
+ const follow = yield fetcher(toggleFollowMutation, { userId: nf.id });
950
+ console.log(`${String(`[${nf.id}]`).padEnd(maxIdLength)}` +
951
+ `\t${String(`[${(_k = (_j = follow === null || follow === void 0 ? void 0 : follow.data) === null || _j === void 0 ? void 0 : _j.ToggleFollow) === null || _k === void 0 ? void 0 : _k.name}]`).padEnd(maxNameLength)}` +
952
+ `\t${((_m = (_l = follow === null || follow === void 0 ? void 0 : follow.data) === null || _l === void 0 ? void 0 : _l.ToggleFollow) === null || _m === void 0 ? void 0 : _m.id) ? "āœ…" : "🈵"}`);
953
+ // Count the followed back users
954
+ if ((_p = (_o = follow === null || follow === void 0 ? void 0 : follow.data) === null || _o === void 0 ? void 0 : _o.ToggleFollow) === null || _p === void 0 ? void 0 : _p.id) {
955
+ followedBack++;
956
+ }
957
+ }
958
+ catch (error) {
959
+ console.log(`automate_follow_toggle_follow: ${error.message}`);
960
+ }
961
+ }
962
+ console.log(`\nāœ… Followed back ${followedBack} users.`);
963
+ }
964
+ catch (error) {
965
+ console.log(`\nautomate_follow ${error.message}`);
966
+ }
967
+ });
968
+ }
969
+ /**
970
+ * Unfollow the users thats not following you
971
+ */
972
+ static unfollow() {
973
+ return __awaiter(this, void 0, void 0, function* () {
974
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
975
+ try {
976
+ let pager = 1;
977
+ let hasNextPage = true;
978
+ let allFollowingUsers = [];
979
+ let unfollowedUsers = 0;
980
+ spinner.start("Fetching all following users...");
981
+ while (hasNextPage) {
982
+ const followingUsers = yield fetcher(userFollowingQuery, {
983
+ userId: yield Auth.MyUserId(),
984
+ page: pager,
985
+ });
986
+ spinner.update(`Fetched page ${pager} of ${(_c = (_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.pageInfo) === null || _c === void 0 ? void 0 : _c.lastPage}...`);
987
+ if (!((_f = (_e = (_d = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.pageInfo) === null || _f === void 0 ? void 0 : _f.hasNextPage)) {
988
+ hasNextPage = false;
989
+ }
990
+ allFollowingUsers.push(...(((_h = (_g = followingUsers === null || followingUsers === void 0 ? void 0 : followingUsers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.following) || []));
991
+ pager++;
992
+ }
993
+ spinner.update(`Fetching complete. Total got ${allFollowingUsers.length} users.`);
994
+ // Filter users that do no follow me
995
+ const notFollowingMe = allFollowingUsers
996
+ .filter((user) => !user.isFollower)
997
+ .map((u3r) => ({ id: u3r.id, name: u3r.name }));
998
+ if (notFollowingMe.length <= 0) {
999
+ spinner.stop(`No users to unfollow. Exiting operation...`);
1000
+ return;
1001
+ }
1002
+ spinner.stop(`Unfollow process activated with ${notFollowingMe.length} users.`);
1003
+ let nfmCount = 0;
1004
+ console.log(`\n`);
1005
+ for (let nfm of notFollowingMe) {
1006
+ nfmCount++;
1007
+ try {
1008
+ const unfollow = yield fetcher(toggleFollowMutation, {
1009
+ userId: nfm.id,
1010
+ });
1011
+ console.log(`[${nfm.id}]\t[${(_k = (_j = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _j === void 0 ? void 0 : _j.ToggleFollow) === null || _k === void 0 ? void 0 : _k.name}]\t${((_m = (_l = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _l === void 0 ? void 0 : _l.ToggleFollow) === null || _m === void 0 ? void 0 : _m.id) ? "āœ…" : "🈵"}`);
1012
+ // Count the unfollowed users
1013
+ if ((_p = (_o = unfollow === null || unfollow === void 0 ? void 0 : unfollow.data) === null || _o === void 0 ? void 0 : _o.ToggleFollow) === null || _p === void 0 ? void 0 : _p.id) {
1014
+ unfollowedUsers++;
1015
+ }
1016
+ }
1017
+ catch (error) {
1018
+ console.log(`unfollow_toggle_follow. ${error.message}`);
1019
+ }
1020
+ }
1021
+ console.log(`\nTotal Unfollowed: ${unfollowedUsers} of ${nfmCount} users.`);
1022
+ }
1023
+ catch (error) {
1024
+ console.error(`\nautomate_unfollow: ${error.message}`);
1025
+ }
1026
+ });
1027
+ }
1028
+ }
1029
+ export { Auth, Social };