@irfanshadikrishad/anilist 1.2.5 → 1.2.7

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.
@@ -13,13 +13,15 @@ import fetch from "node-fetch";
13
13
  import open from "open";
14
14
  import os from "os";
15
15
  import path from "path";
16
+ import Spinner from "tiny-spinner";
16
17
  import { fetcher } from "./fetcher.js";
17
18
  import { AniDB, AniList, MyAnimeList } from "./lists.js";
18
19
  import { deleteActivityMutation, saveTextActivityMutation, } from "./mutations.js";
19
- import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, } from "./queries.js";
20
+ import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, toggleFollowMutation, userActivityQuery, userFollowersQuery, userFollowingQuery, } from "./queries.js";
20
21
  import { aniListEndpoint, getTitle, redirectUri, timestampToTimeAgo, } from "./workers.js";
21
22
  const home_dir = os.homedir();
22
23
  const save_path = path.join(home_dir, ".anilist_token");
24
+ const spinner = new Spinner();
23
25
  class Auth {
24
26
  /**
25
27
  * Get access-token from user
@@ -34,20 +36,29 @@ class Auth {
34
36
  message: "Please enter your AniList access token:",
35
37
  },
36
38
  ]);
39
+ if (!token) {
40
+ console.warn("\nNo token entered. Please try again.");
41
+ return null;
42
+ }
37
43
  return token;
38
44
  }
39
45
  catch (error) {
40
- console.error(`\nSomething went wrong. ${error.message}`);
46
+ console.error(`\nAn error occurred while getting the access token: ${error.message}`);
47
+ return null;
41
48
  }
42
49
  });
43
50
  }
44
51
  static StoreAccessToken(token) {
45
52
  return __awaiter(this, void 0, void 0, function* () {
46
53
  try {
54
+ if (!token) {
55
+ console.warn("\nNo token provided. Nothing to store.");
56
+ return;
57
+ }
47
58
  fs.writeFileSync(save_path, token, { encoding: "utf8" });
48
59
  }
49
60
  catch (error) {
50
- console.error(`\nError storing acess-token. ${error.message}`);
61
+ console.error(`\nError storing access token: ${error.message}`);
51
62
  }
52
63
  });
53
64
  }
@@ -63,6 +74,7 @@ class Auth {
63
74
  }
64
75
  catch (error) {
65
76
  console.error(`\nError retriving acess-token. ${error.message}`);
77
+ return null;
66
78
  }
67
79
  });
68
80
  }
@@ -193,15 +205,12 @@ Statistics (Manga):
193
205
  static isLoggedIn() {
194
206
  return __awaiter(this, void 0, void 0, function* () {
195
207
  try {
196
- if ((yield Auth.RetriveAccessToken()) !== null) {
197
- return true;
198
- }
199
- else {
200
- return false;
201
- }
208
+ const token = yield Auth.RetriveAccessToken();
209
+ return token !== null;
202
210
  }
203
211
  catch (error) {
204
- console.error(`\nError getting isLoggedIn. ${error.message}`);
212
+ console.error(`Error checking login status: ${error.message}`);
213
+ return false;
205
214
  }
206
215
  });
207
216
  }
@@ -215,15 +224,15 @@ Statistics (Manga):
215
224
  console.log(`\nLogout successful. See you soon, ${username}.`);
216
225
  }
217
226
  catch (error) {
218
- console.error("\nError logging out:", error);
227
+ console.error("\nFailed to remove the save file during logout:", error.message);
219
228
  }
220
229
  }
221
230
  else {
222
- console.error("\nYou may already be logged out.");
231
+ console.warn("\nNo active session found. You may already be logged out.");
223
232
  }
224
233
  }
225
234
  catch (error) {
226
- console.error(`\nError logging out. ${error.message}`);
235
+ console.error(`\nAn error occurred during logout: ${error.message}`);
227
236
  }
228
237
  });
229
238
  }
@@ -234,20 +243,7 @@ Statistics (Manga):
234
243
  console.warn(`\nUser not logged in.`);
235
244
  return null;
236
245
  }
237
- const token = yield Auth.RetriveAccessToken();
238
- const request = yield fetch(aniListEndpoint, {
239
- method: "POST",
240
- headers: {
241
- "Content-Type": "application/json",
242
- "Authorization": `Bearer ${token}`,
243
- },
244
- body: JSON.stringify({ query: currentUserQuery }),
245
- });
246
- if (!(request.status === 200)) {
247
- console.error(`Failed to fetch user data. Status: ${request.status}`);
248
- return null;
249
- }
250
- const { data } = yield request.json();
246
+ const { data } = yield fetcher(currentUserQuery, {});
251
247
  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;
252
248
  });
253
249
  }
@@ -258,20 +254,7 @@ Statistics (Manga):
258
254
  console.log(`\nUser not logged in.`);
259
255
  return null;
260
256
  }
261
- const token = yield Auth.RetriveAccessToken();
262
- const request = yield fetch(aniListEndpoint, {
263
- method: "POST",
264
- headers: {
265
- "Content-Type": "application/json",
266
- "Authorization": `Bearer ${token}`,
267
- },
268
- body: JSON.stringify({ query: currentUserQuery }),
269
- });
270
- if (!request.ok) {
271
- console.error(`Failed to fetch user data. Status: ${request.status}`);
272
- return null;
273
- }
274
- const { data } = yield request.json();
257
+ const { data } = yield fetcher(currentUserQuery, {});
275
258
  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;
276
259
  });
277
260
  }
@@ -279,72 +262,70 @@ Statistics (Manga):
279
262
  return __awaiter(this, void 0, void 0, function* () {
280
263
  var _a, _b, _c, _d, _e, _f;
281
264
  try {
282
- if (yield Auth.isLoggedIn()) {
283
- const { activityType } = yield inquirer.prompt([
284
- {
285
- type: "list",
286
- name: "activityType",
287
- message: "What type of activity you want to delete?",
288
- choices: [
289
- { name: "All Activity", value: 0 },
290
- { name: "Text Activity", value: 1 },
291
- { name: "Media List Activity", value: 2 },
292
- { name: "Anime List Activity", value: 3 },
293
- { name: "Manga List Activity", value: 4 },
294
- { name: "Message Activity", value: 5 },
295
- ],
296
- },
297
- ]);
298
- const queryMap = {
299
- 0: activityAllQuery,
300
- 1: activityTextQuery,
301
- 2: activityMediaList,
302
- 3: activityAnimeListQuery,
303
- 4: activityMangaListQuery,
304
- 5: activityMessageQuery,
305
- };
306
- const query = queryMap[activityType];
307
- let hasMoreActivities = true;
308
- let totalCount = 0;
309
- while (hasMoreActivities) {
310
- const response = yield fetcher(query, {
311
- page: 1,
312
- perPage: 50,
313
- userId: yield Auth.MyUserId(),
314
- });
315
- 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) {
316
- let count = 0;
317
- 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;
318
- if (!activities || activities.length === 0) {
319
- console.log(`\nNo more activities available.`);
320
- hasMoreActivities = false;
321
- }
322
- else {
323
- for (const act of activities) {
324
- // Ensure ID is present to avoid unintended errors
325
- if (act === null || act === void 0 ? void 0 : act.id) {
326
- const deleteResponse = yield fetcher(deleteActivityMutation, {
327
- id: act === null || act === void 0 ? void 0 : act.id,
328
- });
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;
330
- count++;
331
- totalCount++;
332
- console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "āœ…" : "āŒ"}`);
333
- // Avoiding rate-limit
334
- yield new Promise((resolve) => setTimeout(resolve, 1100));
335
- }
336
- }
337
- }
265
+ if (!(yield Auth.isLoggedIn())) {
266
+ console.error(`\nPlease log in to delete your activities.`);
267
+ return;
268
+ }
269
+ const { activityType } = yield inquirer.prompt([
270
+ {
271
+ type: "list",
272
+ name: "activityType",
273
+ message: "What type of activity you want to delete?",
274
+ choices: [
275
+ { name: "All Activity", value: 0 },
276
+ { name: "Text Activity", value: 1 },
277
+ { name: "Media List Activity", value: 2 },
278
+ { name: "Anime List Activity", value: 3 },
279
+ { name: "Manga List Activity", value: 4 },
280
+ { name: "Message Activity", value: 5 },
281
+ ],
282
+ },
283
+ ]);
284
+ const queryMap = {
285
+ 0: activityAllQuery,
286
+ 1: activityTextQuery,
287
+ 2: activityMediaList,
288
+ 3: activityAnimeListQuery,
289
+ 4: activityMangaListQuery,
290
+ 5: activityMessageQuery,
291
+ };
292
+ const query = queryMap[activityType];
293
+ let hasMoreActivities = true;
294
+ let totalCount = 0;
295
+ while (hasMoreActivities) {
296
+ const response = yield fetcher(query, {
297
+ page: 1,
298
+ perPage: 50,
299
+ userId: yield Auth.MyUserId(),
300
+ });
301
+ 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) {
302
+ let count = 0;
303
+ 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;
304
+ if (!activities || activities.length === 0) {
305
+ console.log(`\nNo more activities available.`);
306
+ hasMoreActivities = false;
338
307
  }
339
308
  else {
340
- // In case of an unexpected null response, exit the loop
341
- console.log(`\nProbably deleted all the activities of this type.`);
342
- hasMoreActivities = false;
309
+ for (const act of activities) {
310
+ if (act === null || act === void 0 ? void 0 : act.id) {
311
+ const deleteResponse = yield fetcher(deleteActivityMutation, {
312
+ id: act === null || act === void 0 ? void 0 : act.id,
313
+ });
314
+ 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;
315
+ count++;
316
+ totalCount++;
317
+ console.log(`[${count}/${activities.length}/${totalCount}]\t${act === null || act === void 0 ? void 0 : act.id} ${isDeleted ? "āœ…" : "āŒ"}`);
318
+ // Avoiding rate-limit
319
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
320
+ }
321
+ }
343
322
  }
344
323
  }
345
- }
346
- else {
347
- console.error(`\nPlease log in to delete your activities.`);
324
+ else {
325
+ // In case of an unexpected null response, exit the loop
326
+ console.log(`\nProbably deleted all the activities of this type.`);
327
+ hasMoreActivities = false;
328
+ }
348
329
  }
349
330
  }
350
331
  catch (error) {
@@ -355,54 +336,51 @@ Statistics (Manga):
355
336
  static DeleteMyAnimeList() {
356
337
  return __awaiter(this, void 0, void 0, function* () {
357
338
  var _a, _b, _c, _d;
358
- if (yield Auth.isLoggedIn()) {
359
- const userID = yield Auth.MyUserId();
360
- if (userID) {
361
- const response = yield fetcher(currentUserAnimeList, { id: userID });
362
- if (response !== null) {
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;
364
- if (lists.length > 0) {
365
- const { selectedList } = yield inquirer.prompt([
366
- {
367
- type: "list",
368
- name: "selectedList",
369
- message: "Select an anime list:",
370
- choices: lists.map((list) => list.name),
371
- pageSize: 10,
372
- },
373
- ]);
374
- const selectedEntries = lists.find((list) => list.name === selectedList);
375
- if (selectedEntries) {
376
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
377
- for (const [, entry] of selectedEntries.entries.entries()) {
378
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
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);
380
- yield new Promise((resolve) => setTimeout(resolve, 1100));
381
- }
382
- else {
383
- console.log(`No id in entry.`);
384
- console.log(entry);
385
- }
386
- }
339
+ if (!(yield Auth.isLoggedIn())) {
340
+ console.error(`\nPlease log in first to delete your lists.`);
341
+ return;
342
+ }
343
+ if (!(yield Auth.MyUserId())) {
344
+ console.log(`\nFailed getting current user Id.`);
345
+ return;
346
+ }
347
+ const response = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
348
+ if (response !== null) {
349
+ 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;
350
+ if (lists.length > 0) {
351
+ const { selectedList } = yield inquirer.prompt([
352
+ {
353
+ type: "list",
354
+ name: "selectedList",
355
+ message: "Select an anime list:",
356
+ choices: lists.map((list) => list.name),
357
+ pageSize: 10,
358
+ },
359
+ ]);
360
+ const selectedEntries = lists.find((list) => list.name === selectedList);
361
+ if (selectedEntries) {
362
+ console.log(`\nDeleting entries of '${selectedEntries.name}':`);
363
+ for (const [, entry] of selectedEntries.entries.entries()) {
364
+ if (entry === null || entry === void 0 ? void 0 : entry.id) {
365
+ 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);
366
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
387
367
  }
388
368
  else {
389
- console.log("No entries found.");
369
+ console.log(`No id in entry.`);
370
+ console.log(entry);
390
371
  }
391
372
  }
392
- else {
393
- console.log(`\nNo anime(s) found in any list.`);
394
- }
395
373
  }
396
374
  else {
397
- console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
375
+ console.log("No entries found.");
398
376
  }
399
377
  }
400
378
  else {
401
- console.log(`\nFailed getting current user Id.`);
379
+ console.log(`\nNo anime(s) found in any list.`);
402
380
  }
403
381
  }
404
382
  else {
405
- console.error(`\nPlease log in first to delete your lists.`);
383
+ console.log(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
406
384
  }
407
385
  });
408
386
  }
@@ -429,54 +407,50 @@ Statistics (Manga):
429
407
  return __awaiter(this, void 0, void 0, function* () {
430
408
  var _a, _b, _c, _d;
431
409
  try {
432
- if (yield Auth.isLoggedIn()) {
433
- const userID = yield Auth.MyUserId();
434
- if (userID) {
435
- const response = yield fetcher(currentUserMangaList, { id: userID });
436
- if (response === null || response === void 0 ? void 0 : response.data) {
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;
438
- if (lists.length > 0) {
439
- const { selectedList } = yield inquirer.prompt([
440
- {
441
- type: "list",
442
- name: "selectedList",
443
- message: "Select a manga list:",
444
- choices: lists.map((list) => list.name),
445
- pageSize: 10,
446
- },
447
- ]);
448
- const selectedEntries = lists.find((list) => list.name === selectedList);
449
- if (selectedEntries) {
450
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
451
- for (const [, entry] of selectedEntries.entries.entries()) {
452
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
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);
454
- yield new Promise((resolve) => setTimeout(resolve, 1100));
455
- }
456
- else {
457
- console.log(`No id in entry.`);
458
- console.log(entry);
459
- }
460
- }
461
- }
462
- else {
463
- console.error("\nNo entries found.");
464
- }
410
+ if (!(yield Auth.isLoggedIn())) {
411
+ console.error(`\nPlease log in first to delete your lists.`);
412
+ return;
413
+ }
414
+ if (!(yield Auth.MyUserId())) {
415
+ console.error(`\nFailed getting current user Id.`);
416
+ return;
417
+ }
418
+ const response = yield fetcher(currentUserMangaList, { id: yield Auth.MyUserId() });
419
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
420
+ console.error(`\nSomething went wrong. ${(_a = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
421
+ return;
422
+ }
423
+ 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;
424
+ if (lists.length > 0) {
425
+ const { selectedList } = yield inquirer.prompt([
426
+ {
427
+ type: "list",
428
+ name: "selectedList",
429
+ message: "Select a manga list:",
430
+ choices: lists.map((list) => list.name),
431
+ pageSize: 10,
432
+ },
433
+ ]);
434
+ const selectedEntries = lists.find((list) => list.name === selectedList);
435
+ if (selectedEntries) {
436
+ console.log(`\nDeleting entries of '${selectedEntries.name}':`);
437
+ for (const [, entry] of selectedEntries.entries.entries()) {
438
+ if (entry === null || entry === void 0 ? void 0 : entry.id) {
439
+ 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);
440
+ yield new Promise((resolve) => setTimeout(resolve, 1100));
465
441
  }
466
442
  else {
467
- console.error(`\nNo manga(s) found in any list.`);
443
+ console.log(`No id in entry.`);
444
+ console.log(entry);
468
445
  }
469
446
  }
470
- else {
471
- console.error(`\nSomething went wrong. ${(_d = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _d === void 0 ? void 0 : _d.message}`);
472
- }
473
447
  }
474
448
  else {
475
- console.error(`\nFailed getting current user Id.`);
449
+ console.error("\nNo entries found.");
476
450
  }
477
451
  }
478
452
  else {
479
- console.error(`\nPlease log in first to delete your lists.`);
453
+ console.error(`\nNo manga(s) found in any list.`);
480
454
  }
481
455
  }
482
456
  catch (error) {
@@ -505,23 +479,20 @@ Statistics (Manga):
505
479
  }
506
480
  static Write(status) {
507
481
  return __awaiter(this, void 0, void 0, function* () {
508
- var _a;
509
482
  try {
510
483
  if (!(yield Auth.isLoggedIn())) {
511
484
  console.error(`\nPlease login to use this feature.`);
512
485
  return;
513
486
  }
514
- const data = yield fetcher(saveTextActivityMutation, {
515
- status: status +
516
- `<br><br><br><br>*Written using [@irfanshadikrishad/anilist](https://www.npmjs.com/package/@irfanshadikrishad/anilist).*`,
487
+ const { data } = yield fetcher(saveTextActivityMutation, {
488
+ status: status,
517
489
  });
518
490
  if (!data) {
519
491
  console.error(`\nSomething went wrong. ${data}.`);
520
492
  return;
521
493
  }
522
- const savedActivity = (_a = data.data) === null || _a === void 0 ? void 0 : _a.SaveTextActivity;
523
- if (savedActivity === null || savedActivity === void 0 ? void 0 : savedActivity.id) {
524
- console.log(`\n[${savedActivity.id}] status saved successfully!`);
494
+ if (data.SaveTextActivity.id) {
495
+ console.log(`\n[${data.SaveTextActivity.id}] status saved successfully!`);
525
496
  }
526
497
  }
527
498
  catch (error) {
@@ -598,4 +569,115 @@ Statistics (Manga):
598
569
  });
599
570
  }
600
571
  }
601
- export { Auth };
572
+ class Social {
573
+ /**
574
+ * Follow the users that follows you
575
+ */
576
+ static follow() {
577
+ return __awaiter(this, void 0, void 0, function* () {
578
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
579
+ try {
580
+ let pager = 1;
581
+ let hasNextPage = true;
582
+ let allFollowerUsers = [];
583
+ spinner.start("Fetching all the followers...");
584
+ while (hasNextPage) {
585
+ const followerUsers = yield fetcher(userFollowersQuery, {
586
+ userId: yield Auth.MyUserId(),
587
+ page: pager,
588
+ });
589
+ 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}...`);
590
+ 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)) {
591
+ hasNextPage = false;
592
+ }
593
+ 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) || []));
594
+ pager++;
595
+ }
596
+ spinner.stop("Fetched all the followers. Starting follow back.");
597
+ // Filter users that do no follow me
598
+ const notFollowing = allFollowerUsers
599
+ .filter(({ isFollowing }) => !isFollowing)
600
+ .map(({ id, name }) => ({ id: id, name: name }));
601
+ console.log(`\nTotal follower ${allFollowerUsers.length}.\nNot followed back ${notFollowing.length}\n`);
602
+ if (notFollowing.length <= 0) {
603
+ console.log(`Probably followed back all the users.`);
604
+ return;
605
+ }
606
+ // Traverse and follow back
607
+ const maxIdLength = Math.max(...notFollowing.map(({ id }) => String(id).length));
608
+ const maxNameLength = Math.max(...notFollowing.map(({ name }) => name.length));
609
+ for (let nf of notFollowing) {
610
+ try {
611
+ const follow = yield fetcher(toggleFollowMutation, { userId: nf.id });
612
+ console.log(`${String(`[${nf.id}]`).padEnd(maxIdLength)}` +
613
+ `\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)}` +
614
+ `\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) ? "āœ…" : "🈵"}`);
615
+ }
616
+ catch (error) {
617
+ console.log(`automate_follow_toggle_follow: ${error.message}`);
618
+ }
619
+ }
620
+ console.log(`\nāœ… Followed back ${notFollowing.length} users.`);
621
+ }
622
+ catch (error) {
623
+ console.log(`\nautomate_follow ${error.message}`);
624
+ }
625
+ });
626
+ }
627
+ /**
628
+ * Unfollow the users thats not following you
629
+ */
630
+ static unfollow() {
631
+ return __awaiter(this, void 0, void 0, function* () {
632
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
633
+ try {
634
+ let pager = 1;
635
+ let hasNextPage = true;
636
+ let allFollowingUsers = [];
637
+ spinner.start("Fetching all following users...");
638
+ while (hasNextPage) {
639
+ const followingUsers = yield fetcher(userFollowingQuery, {
640
+ userId: yield Auth.MyUserId(),
641
+ page: pager,
642
+ });
643
+ 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} ...`);
644
+ 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)) {
645
+ hasNextPage = false;
646
+ }
647
+ 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) || []));
648
+ pager++;
649
+ }
650
+ spinner.update(`Fetching complete. Total got ${allFollowingUsers.length} users.`);
651
+ // Filter users that do no follow me
652
+ const notFollowingMe = allFollowingUsers
653
+ .filter((user) => !user.isFollower)
654
+ .map((u3r) => ({ id: u3r.id, name: u3r.name }));
655
+ if (notFollowingMe.length <= 0) {
656
+ console.warn(`\nNot following list is empty!`);
657
+ spinner.stop(`No users to unfollow. Aborting process...`);
658
+ return;
659
+ }
660
+ spinner.stop(`Unfollow process activated with ${notFollowingMe.length} users.`);
661
+ let nfmCount = 0;
662
+ console.log(`\n`);
663
+ for (let nfm of notFollowingMe) {
664
+ nfmCount++;
665
+ try {
666
+ const unfollow = yield fetcher(toggleFollowMutation, {
667
+ userId: nfm.id,
668
+ });
669
+ 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) ? "āœ…" : "🈵"}`);
670
+ }
671
+ catch (error) {
672
+ console.log(`unfollow_toggle_follow. ${error.message}`);
673
+ }
674
+ }
675
+ console.log(`\nTotal Unfollowed: ${nfmCount}`);
676
+ }
677
+ catch (error) {
678
+ console.error(`\nautomate_unfollow: ${error.message}`);
679
+ }
680
+ });
681
+ }
682
+ }
683
+ export { Auth, Social };