@irfanshadikrishad/anilist 1.0.0 → 1.0.1-forbidden.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,368 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import fs from "fs";
11
+ import { readdir, writeFile } from "fs/promises";
12
+ import inquirer from "inquirer";
13
+ import { parse } from "json2csv";
14
+ import { createRequire } from "module";
15
+ import open from "open";
16
+ import { homedir } from "os";
17
+ import { join } from "path";
18
+ import process from "process";
19
+ import { Auth } from "./auth.js";
20
+ import { fetcher } from "./fetcher.js";
21
+ import { animeSearchQuery } from "./queries.js";
22
+ import { MALAnimeStatus, MALMangaStatus, } from "./types.js";
1
23
  const aniListEndpoint = `https://graphql.anilist.co`;
2
24
  const redirectUri = "https://anilist.co/api/v2/oauth/pin";
3
25
  function getTitle(title) {
4
- if (title === null || title === void 0 ? void 0 : title.english) {
5
- return title === null || title === void 0 ? void 0 : title.english;
26
+ return (title === null || title === void 0 ? void 0 : title.english) || (title === null || title === void 0 ? void 0 : title.romaji) || "???";
27
+ }
28
+ function formatDateObject(dateObj) {
29
+ if (!dateObj)
30
+ return "null";
31
+ return ([dateObj.day, dateObj.month, dateObj.year].filter(Boolean).join("/") ||
32
+ "null");
33
+ }
34
+ function getNextSeasonAndYear() {
35
+ const currentMonth = new Date().getMonth() + 1;
36
+ const currentYear = new Date().getFullYear();
37
+ let nextSeason;
38
+ let nextYear;
39
+ // Determine the current season
40
+ if (currentMonth >= 12 || currentMonth <= 2) {
41
+ nextSeason = "SPRING";
42
+ nextYear = currentMonth === 12 ? currentYear + 1 : currentYear;
43
+ }
44
+ else if (currentMonth >= 3 && currentMonth <= 5) {
45
+ nextSeason = "SUMMER";
46
+ nextYear = currentYear;
47
+ }
48
+ else if (currentMonth >= 6 && currentMonth <= 8) {
49
+ nextSeason = "FALL";
50
+ nextYear = currentYear;
51
+ }
52
+ else if (currentMonth >= 9 && currentMonth <= 11) {
53
+ nextSeason = "WINTER";
54
+ nextYear = currentYear + 1;
55
+ }
56
+ return { nextSeason, nextYear };
57
+ }
58
+ function removeHtmlAndMarkdown(input) {
59
+ if (input) {
60
+ input = input.replace(/<\/?[^>]+(>|$)/g, "");
61
+ input = input.replace(/(^|\n)#{1,6}\s+(.+?)(\n|$)/g, "$2 ");
62
+ input = input.replace(/(\*\*|__)(.*?)\1/g, "$2");
63
+ input = input.replace(/(\*|_)(.*?)\1/g, "$2");
64
+ input = input.replace(/`(.+?)`/g, "$1");
65
+ input = input.replace(/\[(.*?)\]\(.*?\)/g, "$1");
66
+ input = input.replace(/!\[(.*?)\]\(.*?\)/g, "$1");
67
+ input = input.replace(/(^|\n)>\s+(.+?)(\n|$)/g, "$2 ");
68
+ input = input.replace(/(^|\n)-\s+(.+?)(\n|$)/g, "$2 ");
69
+ input = input.replace(/(^|\n)\d+\.\s+(.+?)(\n|$)/g, "$2 ");
70
+ input = input.replace(/(^|\n)\s*([-*_]){3,}\s*(\n|$)/g, "$1");
71
+ input = input.replace(/~~(.*?)~~/g, "$1");
72
+ input = input.replace(/\s+/g, " ").trim();
73
+ }
74
+ return input;
75
+ }
76
+ function getDownloadFolderPath() {
77
+ const homeDirectory = homedir();
78
+ // Determine the Downloads folder path based on the platform
79
+ if (process.platform === "win32") {
80
+ return join(homeDirectory, "Downloads");
6
81
  }
7
- else if (title === null || title === void 0 ? void 0 : title.romaji) {
8
- return title === null || title === void 0 ? void 0 : title.romaji;
82
+ else if (process.platform === "darwin" || process.platform === "linux") {
83
+ return join(homeDirectory, "Downloads");
84
+ }
85
+ return homeDirectory;
86
+ }
87
+ function getFormattedDate() {
88
+ const date = new Date();
89
+ const day = String(date.getDate()).padStart(2, "0");
90
+ const month = String(date.getMonth() + 1).padStart(2, "0");
91
+ const year = date.getFullYear();
92
+ const hours = String(date.getHours()).padStart(2, "0");
93
+ const minutes = String(date.getMinutes()).padStart(2, "0");
94
+ // Format as DD-MM-YYYY-HH-MM
95
+ return `${day}-${month}-${year}-${hours}-${minutes}`;
96
+ }
97
+ /**
98
+ * Export JSON as JSON
99
+ * @param js0n
100
+ * @param dataType (eg: anime/manga)
101
+ */
102
+ function saveJSONasJSON(js0n, dataType) {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ try {
105
+ const jsonData = JSON.stringify(js0n, null, 2);
106
+ const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-${dataType}-${getFormattedDate()}.json`);
107
+ yield writeFile(path, jsonData, "utf8");
108
+ console.log(`\nSaved as JSON successfully.`);
109
+ open(getDownloadFolderPath());
110
+ }
111
+ catch (error) {
112
+ console.error("\nError saving JSON data:", error);
113
+ }
114
+ });
115
+ }
116
+ /**
117
+ * Export JSON as CSV
118
+ * @param js0n
119
+ * @param dataType (eg: anime/manga)
120
+ */
121
+ function saveJSONasCSV(js0n, dataType) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ try {
124
+ const csvData = parse(js0n);
125
+ const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-${dataType}-${getFormattedDate()}.csv`);
126
+ yield writeFile(path, csvData, "utf8");
127
+ console.log(`\nSaved as CSV successfully.`);
128
+ open(getDownloadFolderPath());
129
+ }
130
+ catch (error) {
131
+ console.error("\nError saving CSV data:", error);
132
+ }
133
+ });
134
+ }
135
+ function listFilesInDownloadFolder() {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ const downloadFolderPath = getDownloadFolderPath();
138
+ const files = yield readdir(downloadFolderPath);
139
+ return files;
140
+ });
141
+ }
142
+ function selectFile(fileType) {
143
+ return __awaiter(this, void 0, void 0, function* () {
144
+ try {
145
+ const files = yield listFilesInDownloadFolder();
146
+ console.log(getDownloadFolderPath());
147
+ // Filter to include only files, not directories, with the specified extension
148
+ const onlyFiles = files.filter((file) => {
149
+ const filePath = `${getDownloadFolderPath()}/${file}`; // Adjust this to the correct path
150
+ const isFile = fs.lstatSync(filePath).isFile(); // Check if it's a file
151
+ return isFile && file.endsWith(fileType);
152
+ });
153
+ if (onlyFiles.length > 0) {
154
+ const answers = yield inquirer.prompt([
155
+ {
156
+ type: "list",
157
+ name: "fileName",
158
+ message: "Select a file to import:",
159
+ choices: onlyFiles,
160
+ },
161
+ ]);
162
+ return answers.fileName;
163
+ }
164
+ else {
165
+ throw new Error(`\nNo importable ${fileType} file(s) found in download folder.`);
166
+ }
167
+ }
168
+ catch (error) {
169
+ console.error("\nError selecting file:", error);
170
+ throw error;
171
+ }
172
+ });
173
+ }
174
+ function createAnimeXML(malId, progress, status, episodes, title) {
175
+ return `
176
+ <anime>
177
+ <series_animedb_id>${malId}</series_animedb_id>
178
+ <series_title><![CDATA[${title}]]></series_title>
179
+ <series_type>""</series_type>
180
+ <series_episodes>${episodes}</series_episodes>
181
+ <my_id>0</my_id>
182
+ <my_watched_episodes>${progress}</my_watched_episodes>
183
+ <my_start_date>0000-00-00</my_start_date>
184
+ <my_finish_date>0000-00-00</my_finish_date>
185
+ <my_score>0</my_score>
186
+ <my_storage_value>0.00</my_storage_value>
187
+ <my_status>${status}</my_status>
188
+ <my_comments><![CDATA[]]></my_comments>
189
+ <my_times_watched>0</my_times_watched>
190
+ <my_rewatch_value></my_rewatch_value>
191
+ <my_priority>LOW</my_priority>
192
+ <my_tags><![CDATA[]]></my_tags>
193
+ <my_rewatching>0</my_rewatching>
194
+ <my_rewatching_ep>0</my_rewatching_ep>
195
+ <my_discuss>0</my_discuss>
196
+ <my_sns>default</my_sns>
197
+ <update_on_import>1</update_on_import>
198
+ </anime>`;
199
+ }
200
+ function createMangaXML(malId, progress, status, chapters, title) {
201
+ return `
202
+ <manga>
203
+ <manga_mangadb_id>${malId}</manga_mangadb_id>
204
+ <manga_title><![CDATA[${title ? title : "unknown"}]]></manga_title>
205
+ <manga_volumes>0</manga_volumes>
206
+ <manga_chapters>${chapters ? chapters : 0}</manga_chapters>
207
+ <my_id>0</my_id>
208
+ <my_read_chapters>${progress}</my_read_chapters>
209
+ <my_start_date>0000-00-00</my_start_date>
210
+ <my_finish_date>0000-00-00</my_finish_date>
211
+ <my_score>0</my_score>
212
+ <my_status>${status}</my_status>
213
+ <my_reread_value></my_reread_value>
214
+ <my_priority>LOW</my_priority>
215
+ <my_rereading>0</my_rereading>
216
+ <my_discuss>0</my_discuss>
217
+ <update_on_import>1</update_on_import>
218
+ </manga>`;
219
+ }
220
+ function createAnimeListXML(mediaWithProgress) {
221
+ return __awaiter(this, void 0, void 0, function* () {
222
+ const statusMap = {
223
+ PLANNING: MALAnimeStatus.PLAN_TO_WATCH,
224
+ COMPLETED: MALAnimeStatus.COMPLETED,
225
+ CURRENT: MALAnimeStatus.WATCHING,
226
+ PAUSED: MALAnimeStatus.ON_HOLD,
227
+ DROPPED: MALAnimeStatus.DROPPED,
228
+ };
229
+ const xmlEntries = mediaWithProgress.map((anime) => {
230
+ const malId = anime.malId;
231
+ const progress = anime.progress;
232
+ const episodes = anime.episodes;
233
+ const title = getTitle(anime.title);
234
+ const status = statusMap[anime.status];
235
+ return createAnimeXML(malId, progress, status, episodes, title);
236
+ });
237
+ return `<myanimelist>
238
+ <myinfo>
239
+ <user_id/>
240
+ <user_name>${yield Auth.MyUserName()}</user_name>
241
+ <user_export_type>1</user_export_type>
242
+ <user_total_anime>0</user_total_anime>
243
+ <user_total_watching>0</user_total_watching>
244
+ <user_total_completed>0</user_total_completed>
245
+ <user_total_onhold>0</user_total_onhold>
246
+ <user_total_dropped>0</user_total_dropped>
247
+ <user_total_plantowatch>0</user_total_plantowatch>
248
+ </myinfo>
249
+ \n${xmlEntries.join("\n")}\n
250
+ </myanimelist>`;
251
+ });
252
+ }
253
+ function createMangaListXML(mediaWithProgress) {
254
+ return __awaiter(this, void 0, void 0, function* () {
255
+ const statusMap = {
256
+ PLANNING: MALMangaStatus.PLAN_TO_READ,
257
+ COMPLETED: MALMangaStatus.COMPLETED,
258
+ CURRENT: MALMangaStatus.READING,
259
+ PAUSED: MALMangaStatus.ON_HOLD,
260
+ DROPPED: MALMangaStatus.DROPPED,
261
+ };
262
+ const xmlEntries = mediaWithProgress.map((manga) => {
263
+ const malId = manga.malId;
264
+ const progress = manga.progress;
265
+ const chapters = manga.chapters;
266
+ const title = getTitle(manga.title);
267
+ const status = statusMap[manga.status];
268
+ return createMangaXML(malId, progress, status, chapters, title);
269
+ });
270
+ return `<myanimelist>
271
+ <myinfo>
272
+ <user_id/>
273
+ <user_name>${yield Auth.MyUserName()}</user_name>
274
+ <user_export_type>2</user_export_type>
275
+ <user_total_manga>5</user_total_manga>
276
+ <user_total_reading>1</user_total_reading>
277
+ <user_total_completed>1</user_total_completed>
278
+ <user_total_onhold>1</user_total_onhold>
279
+ <user_total_dropped>1</user_total_dropped>
280
+ <user_total_plantoread>1</user_total_plantoread>
281
+ </myinfo>
282
+ \n${xmlEntries.join("\n")}\n
283
+ </myanimelist>`;
284
+ });
285
+ }
286
+ function getCurrentPackageVersion() {
287
+ const require = createRequire(import.meta.url);
288
+ const packageJson = require("../../package.json");
289
+ const version = packageJson.version;
290
+ return version || null;
291
+ }
292
+ function timestampToTimeAgo(timestamp) {
293
+ const now = Math.floor(Date.now() / 1000);
294
+ const elapsed = now - timestamp;
295
+ if (elapsed < 60) {
296
+ return `${elapsed} second${elapsed === 1 ? "" : "s"} ago`;
297
+ }
298
+ else if (elapsed < 3600) {
299
+ const minutes = Math.floor(elapsed / 60);
300
+ return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
301
+ }
302
+ else if (elapsed < 86400) {
303
+ const hours = Math.floor(elapsed / 3600);
304
+ return `${hours} hour${hours === 1 ? "" : "s"} ago`;
305
+ }
306
+ else if (elapsed < 2592000) {
307
+ const days = Math.floor(elapsed / 86400);
308
+ return `${days} day${days === 1 ? "" : "s"} ago`;
309
+ }
310
+ else if (elapsed < 31536000) {
311
+ const months = Math.floor(elapsed / 2592000);
312
+ return `${months} month${months === 1 ? "" : "s"} ago`;
9
313
  }
10
314
  else {
11
- return "???";
315
+ const years = Math.floor(elapsed / 31536000);
316
+ return `${years} year${years === 1 ? "" : "s"} ago`;
12
317
  }
13
318
  }
14
- export { aniListEndpoint, redirectUri, getTitle };
319
+ function activityBy(activity) {
320
+ var _a, _b, _c, _d;
321
+ if ((_a = activity === null || activity === void 0 ? void 0 : activity.messenger) === null || _a === void 0 ? void 0 : _a.name) {
322
+ return `[${activity.id}]\t${activity.messenger.name} messaged ${activity.recipient.name}`;
323
+ }
324
+ else if ((_c = (_b = activity === null || activity === void 0 ? void 0 : activity.media) === null || _b === void 0 ? void 0 : _b.title) === null || _c === void 0 ? void 0 : _c.userPreferred) {
325
+ if (activity.progress) {
326
+ return `[${activity.id}]\t${activity.user.name} ${activity.status} ${activity.progress} of ${activity.media.title.userPreferred}`;
327
+ }
328
+ else {
329
+ return `[${activity.id}]\t${activity.user.name} ${activity.status} ${activity.media.title.userPreferred}`;
330
+ }
331
+ }
332
+ else if ((_d = activity === null || activity === void 0 ? void 0 : activity.user) === null || _d === void 0 ? void 0 : _d.name) {
333
+ return `[${activity.id}]\t${activity.user.name}`;
334
+ }
335
+ else {
336
+ return `[${activity === null || activity === void 0 ? void 0 : activity.id}] ???`;
337
+ }
338
+ }
339
+ const anidbToanilistMapper = (romanjiName, year, englishName) => __awaiter(void 0, void 0, void 0, function* () {
340
+ const fetchAnime = (search) => __awaiter(void 0, void 0, void 0, function* () {
341
+ var _a;
342
+ try {
343
+ const response = yield fetcher(animeSearchQuery, {
344
+ search,
345
+ perPage: 50,
346
+ });
347
+ return ((_a = response.data) === null || _a === void 0 ? void 0 : _a.Page.media) || [];
348
+ }
349
+ catch (error) {
350
+ console.error("Error fetching AniList data:", error);
351
+ return [];
352
+ }
353
+ });
354
+ // Search using romanjiName first
355
+ let results = yield fetchAnime(romanjiName);
356
+ // If no results, fallback to englishName
357
+ if (!results.length && englishName) {
358
+ results = yield fetchAnime(englishName);
359
+ }
360
+ // Match using year
361
+ for (const anime of results) {
362
+ if (anime.startDate.year === year) {
363
+ return anime.id;
364
+ }
365
+ }
366
+ return null;
367
+ });
368
+ export { activityBy, anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, timestampToTimeAgo, };
package/bin/index.js CHANGED
@@ -9,11 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  import { Command } from "commander";
12
- import { anilistUserLogin, currentUserInfo, logoutUser, } from "./helpers/auth.js";
13
- import { deleteAnimeCollection, deleteMangaCollection, getPopular, getTrending, loggedInUsersAnimeLists, loggedInUsersMangaLists, } from "./helpers/lists.js";
14
- import { getUserInfoByUsername } from "./helpers/more.js";
12
+ import process from "process";
13
+ import { Auth, Social } from "./helpers/auth.js";
14
+ import { AniList } from "./helpers/lists.js";
15
+ import { getCurrentPackageVersion } from "./helpers/workers.js";
15
16
  const cli = new Command();
16
- cli.name("anilist").description("Unofficial AniList CLI").version("1.0.0");
17
+ cli
18
+ .name("anilist")
19
+ .description("Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts.")
20
+ .version(getCurrentPackageVersion());
17
21
  cli
18
22
  .command("login")
19
23
  .description("Login with AniList")
@@ -21,17 +25,17 @@ cli
21
25
  .requiredOption("-s, --secret <string>", null)
22
26
  .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ id, secret }) {
23
27
  if (id && secret) {
24
- yield anilistUserLogin(id, secret);
28
+ yield Auth.Login(id, secret);
25
29
  }
26
30
  else {
27
- console.log("Tokens not provided correctly!");
31
+ console.log("\nMust provide both ClientId and ClientSecret!");
28
32
  }
29
33
  }));
30
34
  cli
31
- .command("me")
35
+ .command("whoami")
32
36
  .description("Get details of the logged in user")
33
37
  .action(() => __awaiter(void 0, void 0, void 0, function* () {
34
- yield currentUserInfo();
38
+ yield Auth.Myself();
35
39
  }));
36
40
  cli
37
41
  .command("trending")
@@ -39,7 +43,7 @@ cli
39
43
  .description("Get the trending list from AniList")
40
44
  .option("-c, --count <number>", "Number of list items to get", "10")
41
45
  .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ count }) {
42
- yield getTrending(Number(count));
46
+ yield AniList.getTrendingAnime(Number(count));
43
47
  }));
44
48
  cli
45
49
  .command("popular")
@@ -47,20 +51,19 @@ cli
47
51
  .description("Get the popular list from AniList")
48
52
  .option("-c, --count <number>", "Number of list items to get", "10")
49
53
  .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ count }) {
50
- yield getPopular(Number(count));
54
+ yield AniList.getPopularAnime(Number(count));
51
55
  }));
52
56
  cli
53
- .command("user")
57
+ .command("user <username>")
54
58
  .description("Get user information")
55
- .requiredOption("-un, --username <string>", "null")
56
- .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ username }) {
57
- yield getUserInfoByUsername(username);
59
+ .action((username) => __awaiter(void 0, void 0, void 0, function* () {
60
+ yield AniList.getUserByUsername(username);
58
61
  }));
59
62
  cli
60
63
  .command("logout")
61
64
  .description("Log out the current user.")
62
65
  .action(() => __awaiter(void 0, void 0, void 0, function* () {
63
- yield logoutUser();
66
+ yield Auth.Logout();
64
67
  }));
65
68
  cli
66
69
  .command("lists")
@@ -70,30 +73,172 @@ cli
70
73
  .option("-m, --manga", "For manga list of authenticated user", false)
71
74
  .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga }) {
72
75
  if ((!anime && !manga) || (anime && manga)) {
73
- console.log(`Must select an option, either --anime or --manga`);
76
+ console.error(`\nMust select an option, either --anime or --manga`);
74
77
  }
75
78
  else if (anime) {
76
- yield loggedInUsersAnimeLists();
79
+ yield AniList.MyAnime();
77
80
  }
78
81
  else if (manga) {
79
- yield loggedInUsersMangaLists();
82
+ yield AniList.MyManga();
80
83
  }
81
84
  }));
82
85
  cli
83
86
  .command("delete")
84
87
  .alias("del")
85
- .description("Delete entire collections of anime or mang")
88
+ .description("Delete entire collections of anime or manga")
86
89
  .option("-a, --anime", "For anime list of authenticated user", false)
87
90
  .option("-m, --manga", "For manga list of authenticated user", false)
91
+ .option("-s, --activity", "For activity of authenticated user", false)
92
+ .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga, activity }) {
93
+ const selectedOptions = [anime, manga, activity].filter(Boolean).length;
94
+ if (selectedOptions === 0) {
95
+ console.error(`\nMust select one option: either --anime, --manga, or --activity`);
96
+ process.exit(1);
97
+ }
98
+ if (selectedOptions > 1) {
99
+ console.error(`\nOnly one option can be selected at a time: --anime, --manga, or --activity`);
100
+ process.exit(1);
101
+ }
102
+ if (anime) {
103
+ yield Auth.DeleteMyAnimeList();
104
+ }
105
+ else if (manga) {
106
+ yield Auth.DeleteMyMangaList();
107
+ }
108
+ else if (activity) {
109
+ yield Auth.DeleteMyActivities();
110
+ }
111
+ }));
112
+ cli
113
+ .command("upcoming")
114
+ .alias("up")
115
+ .description("Anime that will be released in upcoming season")
116
+ .option("-c, --count <number>", "Number of items to get", "10")
117
+ .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ count }) {
118
+ yield AniList.getUpcomingAnime(Number(count));
119
+ }));
120
+ cli
121
+ .command("anime <id>")
122
+ .description("Get anime details by their ID")
123
+ .action((id) => __awaiter(void 0, void 0, void 0, function* () {
124
+ if (id && !Number.isNaN(Number(id))) {
125
+ yield AniList.getAnimeDetailsByID(Number(id));
126
+ }
127
+ else {
128
+ console.error(`\nInvalid or missing ID (${id}). Please provide a valid numeric ID.`);
129
+ }
130
+ }));
131
+ cli
132
+ .command("search <query>")
133
+ .alias("srch")
134
+ .alias("find")
135
+ .description("Search anime or manga.")
136
+ .option("-a, --anime", "To get the anime search results.", false)
137
+ .option("-m, --manga", "To get the manga search results.", false)
138
+ .option("-c, --count <number>", "Number of search results to show.", "10")
139
+ .action((query_1, _a) => __awaiter(void 0, [query_1, _a], void 0, function* (query, { anime, manga, count }) {
140
+ if ((!anime && !manga) || (anime && manga)) {
141
+ console.error(`\nMust select an option, either --anime or --manga`);
142
+ }
143
+ else {
144
+ if (anime) {
145
+ yield AniList.searchAnime(query, Number(count));
146
+ }
147
+ else if (manga) {
148
+ yield AniList.searchManga(query, Number(count));
149
+ }
150
+ else {
151
+ console.error(`\nMust select an option, either --anime or --manga`);
152
+ }
153
+ }
154
+ }));
155
+ cli
156
+ .command("status <status>")
157
+ .alias("post")
158
+ .alias("write")
159
+ .description("Write a status...")
160
+ .action((status) => __awaiter(void 0, void 0, void 0, function* () {
161
+ yield Auth.Write(status);
162
+ }));
163
+ cli
164
+ .command("export")
165
+ .alias("exp")
166
+ .description("Export your anime or manga list.")
167
+ .option("-a, --anime", "To get the anime search results.", false)
168
+ .option("-m, --manga", "To get the manga search results.", false)
88
169
  .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga }) {
89
170
  if ((!anime && !manga) || (anime && manga)) {
90
- console.log(`Must select an option, either --anime or --manga`);
171
+ console.error(`\nMust select an option, either --anime or --manga`);
91
172
  }
92
- else if (anime) {
93
- yield deleteAnimeCollection();
173
+ else {
174
+ if (anime) {
175
+ yield AniList.exportAnime();
176
+ }
177
+ else if (manga) {
178
+ yield AniList.exportManga();
179
+ }
94
180
  }
95
- else if (manga) {
96
- yield deleteMangaCollection();
181
+ }));
182
+ cli
183
+ .command("import")
184
+ .alias("imp")
185
+ .description("Import your anime or manga from anilist or other sources.")
186
+ .option("-a, --anime", "To get the anime search results.", false)
187
+ .option("-m, --manga", "To get the manga search results.", false)
188
+ .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga }) {
189
+ if ((!anime && !manga) || (anime && manga)) {
190
+ console.error(`\nMust select an option, either --anime or --manga`);
191
+ }
192
+ else {
193
+ if (yield Auth.isLoggedIn()) {
194
+ if (anime) {
195
+ yield Auth.callAnimeImporter();
196
+ }
197
+ else if (manga) {
198
+ yield Auth.callMangaImporter();
199
+ }
200
+ }
201
+ else {
202
+ console.error(`\nPlease login to use this feature.`);
203
+ }
204
+ }
205
+ }));
206
+ cli
207
+ .command("autolike")
208
+ .alias("al")
209
+ .option("-2, --v2", "Like the activities", false)
210
+ .option("-c, --count <number>", "Number of activities to like", "25")
211
+ .description("Autolike following or global activities.")
212
+ .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ v2, count }) {
213
+ if (v2) {
214
+ yield Auth.LikeFollowingActivityV2(count);
215
+ }
216
+ else {
217
+ yield Auth.AutoLike();
218
+ }
219
+ }));
220
+ cli
221
+ .command("social")
222
+ .alias("sol")
223
+ .description("Automate your process")
224
+ .option("-f, --follow", "Follow the user whos following you.", false)
225
+ .option("-u, --unfollow", "Unfollow the user whos not following you.", false)
226
+ .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ follow, unfollow }) {
227
+ if (!follow && !unfollow) {
228
+ console.error(`\nMust select an option, either --follow or --unfollow`);
229
+ }
230
+ else {
231
+ if (yield Auth.isLoggedIn()) {
232
+ if (follow) {
233
+ yield Social.follow();
234
+ }
235
+ else if (unfollow) {
236
+ yield Social.unfollow();
237
+ }
238
+ }
239
+ else {
240
+ console.error(`\nPlease login to use this feature.`);
241
+ }
97
242
  }
98
243
  }));
99
244
  cli.parse(process.argv);