@irfanshadikrishad/anilist 1.0.0 → 1.0.1-forbidden.3

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