@irfanshadikrishad/anilist 1.3.0-forbidden.1 → 1.3.1

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.
@@ -10,6 +10,7 @@ declare class AniList {
10
10
  static getUpcomingAnime(count: number): Promise<void>;
11
11
  static getUserByUsername(username: string): Promise<void>;
12
12
  static getAnimeDetailsByID(anilistID: number): Promise<void>;
13
+ static getMangaDetailsByID(mangaID: number): Promise<void>;
13
14
  static searchAnime(search: string, count: number): Promise<void>;
14
15
  static searchManga(search: string, count: number): Promise<void>;
15
16
  }
@@ -19,4 +20,7 @@ declare class MyAnimeList {
19
20
  static exportAnime(): Promise<void>;
20
21
  static exportManga(): Promise<void>;
21
22
  }
22
- export { AniList, MyAnimeList };
23
+ declare class AniDB {
24
+ static importAnime(): Promise<void>;
25
+ }
26
+ export { AniDB, AniList, MyAnimeList };
@@ -8,23 +8,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { XMLParser } from "fast-xml-parser";
11
- import { readFile, writeFile } from "fs/promises";
11
+ import { readFile } from "fs/promises";
12
12
  import inquirer from "inquirer";
13
+ import { jsonrepair } from "jsonrepair";
13
14
  import { join } from "path";
14
15
  import { Auth } from "./auth.js";
15
16
  import { fetcher } from "./fetcher.js";
16
17
  import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
17
- import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, } from "./queries.js";
18
+ import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
18
19
  import { AniListMediaStatus, } from "./types.js";
19
- import { createAnimeListXML, createMangaListXML, formatDateObject, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, timestampToTimeAgo, } from "./workers.js";
20
+ import { Validate } from "./validation.js";
21
+ import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from "./workers.js";
20
22
  class AniList {
21
23
  static importAnime() {
22
24
  return __awaiter(this, void 0, void 0, function* () {
23
25
  try {
24
26
  const filename = yield selectFile(".json");
27
+ if (!filename) {
28
+ return;
29
+ }
25
30
  const filePath = join(getDownloadFolderPath(), filename);
26
31
  const fileContent = yield readFile(filePath, "utf8");
27
32
  const importedData = JSON.parse(fileContent);
33
+ if (!Validate.Import_JSON(importedData)) {
34
+ console.error(`\nInvalid JSON file.`);
35
+ return;
36
+ }
28
37
  let count = 0;
29
38
  const batchSize = 1; // Number of requests in each batch
30
39
  const delay = 1100; // delay to avoid rate-limiting
@@ -68,9 +77,16 @@ class AniList {
68
77
  return __awaiter(this, void 0, void 0, function* () {
69
78
  try {
70
79
  const filename = yield selectFile(".json");
80
+ if (!filename) {
81
+ return;
82
+ }
71
83
  const filePath = join(getDownloadFolderPath(), filename);
72
84
  const fileContent = yield readFile(filePath, "utf8");
73
85
  const importedData = JSON.parse(fileContent);
86
+ if (!Validate.Import_JSON(importedData)) {
87
+ console.error(`\nInvalid JSON file.`);
88
+ return;
89
+ }
74
90
  let count = 0;
75
91
  const batchSize = 1; // Adjust batch size as per rate-limit constraints
76
92
  const delay = 1100; // 2 seconds delay to avoid rate-limit
@@ -112,7 +128,76 @@ class AniList {
112
128
  static exportAnime() {
113
129
  return __awaiter(this, void 0, void 0, function* () {
114
130
  var _a, _b, _c;
115
- if (yield Auth.isLoggedIn()) {
131
+ if (!(yield Auth.isLoggedIn())) {
132
+ console.error(`\nMust login to use this feature.`);
133
+ return;
134
+ }
135
+ const { exportType } = yield inquirer.prompt([
136
+ {
137
+ type: "list",
138
+ name: "exportType",
139
+ message: "Choose export type:",
140
+ choices: [
141
+ { name: "CSV", value: 1 },
142
+ { name: "JSON", value: 2 },
143
+ { name: "XML (MyAnimeList/AniDB)", value: 3 },
144
+ ],
145
+ pageSize: 10,
146
+ },
147
+ ]);
148
+ const animeList = yield fetcher(currentUserAnimeList, {
149
+ id: yield Auth.MyUserId(),
150
+ });
151
+ if (animeList) {
152
+ const lists = (_c = (_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) !== null && _c !== void 0 ? _c : [];
153
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
154
+ var _a, _b, _c, _d;
155
+ return ({
156
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
157
+ title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
158
+ episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
159
+ siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
160
+ progress: entry.progress,
161
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
162
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
163
+ });
164
+ }));
165
+ switch (exportType) {
166
+ case 1:
167
+ yield saveJSONasCSV(mediaWithProgress, "anime");
168
+ break;
169
+ case 2:
170
+ yield saveJSONasJSON(mediaWithProgress, "anime");
171
+ break;
172
+ case 3:
173
+ yield MyAnimeList.exportAnime();
174
+ break;
175
+ default:
176
+ console.log(`\nInvalid export type. ${exportType}`);
177
+ break;
178
+ }
179
+ }
180
+ else {
181
+ console.error(`\nNo anime(s) found in your lists.`);
182
+ }
183
+ });
184
+ }
185
+ static exportManga() {
186
+ return __awaiter(this, void 0, void 0, function* () {
187
+ var _a, _b;
188
+ if (!(yield Auth.isLoggedIn())) {
189
+ console.error(`\nPlease login to use this feature.`);
190
+ return;
191
+ }
192
+ const mangaLists = yield fetcher(currentUserMangaList, {
193
+ id: yield Auth.MyUserId(),
194
+ });
195
+ if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
196
+ console.error(`\nCould not get manga list.`);
197
+ return;
198
+ }
199
+ const lists = ((_b = (_a = mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) || [];
200
+ if (lists.length > 0) {
116
201
  const { exportType } = yield inquirer.prompt([
117
202
  {
118
203
  type: "list",
@@ -126,111 +211,35 @@ class AniList {
126
211
  pageSize: 10,
127
212
  },
128
213
  ]);
129
- const animeList = yield fetcher(currentUserAnimeList, {
130
- id: yield Auth.MyUserId(),
131
- });
132
- if (animeList) {
133
- const lists = (_c = (_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) !== null && _c !== void 0 ? _c : [];
134
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
135
- var _a, _b, _c, _d, _e;
136
- return ({
137
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
138
- title: exportType === 1
139
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
140
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
141
- episodes: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.episodes,
142
- siteUrl: (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.siteUrl,
143
- progress: entry.progress,
144
- status: entry === null || entry === void 0 ? void 0 : entry.status,
145
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
146
- });
147
- }));
148
- switch (exportType) {
149
- case 1:
150
- yield saveJSONasCSV(mediaWithProgress, "anime");
151
- break;
152
- case 2:
153
- yield saveJSONasJSON(mediaWithProgress, "anime");
154
- break;
155
- case 3:
156
- yield MyAnimeList.exportAnime();
157
- break;
158
- default:
159
- console.log(`\nInvalid export type. ${exportType}`);
160
- break;
161
- }
162
- }
163
- else {
164
- console.error(`\nNo anime(s) found in your lists.`);
165
- }
166
- }
167
- else {
168
- console.error(`\nMust login to use this feature.`);
169
- }
170
- });
171
- }
172
- static exportManga() {
173
- return __awaiter(this, void 0, void 0, function* () {
174
- var _a, _b;
175
- if (yield Auth.isLoggedIn()) {
176
- const mangaLists = yield fetcher(currentUserMangaList, {
177
- id: yield Auth.MyUserId(),
178
- });
179
- if (mangaLists) {
180
- const lists = ((_b = (_a = mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists) || [];
181
- if (lists.length > 0) {
182
- const { exportType } = yield inquirer.prompt([
183
- {
184
- type: "list",
185
- name: "exportType",
186
- message: "Choose export type:",
187
- choices: [
188
- { name: "CSV", value: 1 },
189
- { name: "JSON", value: 2 },
190
- { name: "XML (MyAnimeList)", value: 3 },
191
- ],
192
- pageSize: 10,
193
- },
194
- ]);
195
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
196
- var _a, _b, _c;
197
- return ({
198
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
199
- title: exportType === 1
200
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
201
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
202
- private: entry.private,
203
- chapters: entry.media.chapters,
204
- progress: entry.progress,
205
- status: entry === null || entry === void 0 ? void 0 : entry.status,
206
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
207
- });
208
- }));
209
- switch (exportType) {
210
- case 1:
211
- yield saveJSONasCSV(mediaWithProgress, "manga");
212
- break;
213
- case 2:
214
- yield saveJSONasJSON(mediaWithProgress, "manga");
215
- break;
216
- case 3:
217
- yield MyAnimeList.exportManga();
218
- break;
219
- default:
220
- console.log(`\nInvalid export type. ${exportType}`);
221
- break;
222
- }
223
- }
224
- else {
225
- console.log(`\nList seems to be empty.`);
226
- }
227
- }
228
- else {
229
- console.error(`\nCould not get manga list.`);
214
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
215
+ var _a, _b;
216
+ return ({
217
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
218
+ title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
219
+ private: entry.private,
220
+ chapters: entry.media.chapters,
221
+ progress: entry.progress,
222
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
223
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
224
+ });
225
+ }));
226
+ switch (exportType) {
227
+ case 1:
228
+ yield saveJSONasCSV(mediaWithProgress, "manga");
229
+ break;
230
+ case 2:
231
+ yield saveJSONasJSON(mediaWithProgress, "manga");
232
+ break;
233
+ case 3:
234
+ yield MyAnimeList.exportManga();
235
+ break;
236
+ default:
237
+ console.log(`\nInvalid export type. ${exportType}`);
238
+ break;
230
239
  }
231
240
  }
232
241
  else {
233
- console.error(`\nPlease login to use this feature.`);
242
+ console.log(`\nList seems to be empty.`);
234
243
  }
235
244
  });
236
245
  }
@@ -241,11 +250,10 @@ class AniList {
241
250
  if (!(yield Auth.isLoggedIn())) {
242
251
  return console.error(`\nPlease log in first to access your lists.`);
243
252
  }
244
- const userId = yield Auth.MyUserId();
245
- if (!userId) {
253
+ if (!(yield Auth.MyUserId())) {
246
254
  return console.log(`\nFailed getting current user Id.`);
247
255
  }
248
- const data = yield fetcher(currentUserAnimeList, { id: userId });
256
+ const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
249
257
  if (data === null || data === void 0 ? void 0 : data.errors) {
250
258
  return console.log(`\nSomething went wrong. ${(_b = (_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message}`);
251
259
  }
@@ -612,7 +620,7 @@ class AniList {
612
620
  }
613
621
  static getUserByUsername(username) {
614
622
  return __awaiter(this, void 0, void 0, function* () {
615
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
623
+ 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;
616
624
  try {
617
625
  const response = yield fetcher(userQuery, { username });
618
626
  if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
@@ -625,6 +633,15 @@ class AniList {
625
633
  perPage: 10,
626
634
  });
627
635
  const activities = (_f = (_e = (_d = userActivityResponse === null || userActivityResponse === void 0 ? void 0 : userActivityResponse.data) === null || _d === void 0 ? void 0 : _d.Page) === null || _e === void 0 ? void 0 : _e.activities) !== null && _f !== void 0 ? _f : [];
636
+ // Get follower/following information
637
+ const req_followers = yield fetcher(userFollowersQuery, {
638
+ userId: user === null || user === void 0 ? void 0 : user.id,
639
+ });
640
+ const req_following = yield fetcher(userFollowingQuery, {
641
+ userId: user === null || user === void 0 ? void 0 : user.id,
642
+ });
643
+ const followersCount = ((_j = (_h = (_g = req_followers === null || req_followers === void 0 ? void 0 : req_followers.data) === null || _g === void 0 ? void 0 : _g.Page) === null || _h === void 0 ? void 0 : _h.pageInfo) === null || _j === void 0 ? void 0 : _j.total) || 0;
644
+ const followingCount = ((_m = (_l = (_k = req_following === null || req_following === void 0 ? void 0 : req_following.data) === null || _k === void 0 ? void 0 : _k.Page) === null || _l === void 0 ? void 0 : _l.pageInfo) === null || _m === void 0 ? void 0 : _m.total) || 0;
628
645
  console.log(`\nID:\t\t${user.id}`);
629
646
  console.log(`Name:\t\t${user.name}`);
630
647
  console.log(`Site URL:\t${user.siteUrl}`);
@@ -635,10 +652,12 @@ class AniList {
635
652
  console.log(`Blocked:\t${user.isBlocked}`);
636
653
  console.log(`Follower:\t${user.isFollower}`);
637
654
  console.log(`Following:\t${user.isFollowing}`);
638
- console.log(`Profile Color:\t${(_g = user.options) === null || _g === void 0 ? void 0 : _g.profileColor}`);
639
- console.log(`Timezone:\t${(_h = user.options) === null || _h === void 0 ? void 0 : _h.timezone}`);
640
- console.log(`\nStatistics (Anime)\nCount: ${((_k = (_j = user.statistics) === null || _j === void 0 ? void 0 : _j.anime) === null || _k === void 0 ? void 0 : _k.count) || 0} Episodes Watched: ${((_m = (_l = user.statistics) === null || _l === void 0 ? void 0 : _l.anime) === null || _m === void 0 ? void 0 : _m.episodesWatched) || 0} Minutes Watched: ${((_p = (_o = user.statistics) === null || _o === void 0 ? void 0 : _o.anime) === null || _p === void 0 ? void 0 : _p.minutesWatched) || 0}`);
641
- console.log(`Statistics (Manga)\nCount: ${((_r = (_q = user.statistics) === null || _q === void 0 ? void 0 : _q.manga) === null || _r === void 0 ? void 0 : _r.count) || 0} Chapters Read: ${((_t = (_s = user.statistics) === null || _s === void 0 ? void 0 : _s.manga) === null || _t === void 0 ? void 0 : _t.chaptersRead) || 0} Volumes Read: ${((_v = (_u = user.statistics) === null || _u === void 0 ? void 0 : _u.manga) === null || _v === void 0 ? void 0 : _v.volumesRead) || 0}`);
655
+ console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
656
+ console.log(`Timezone:\t${((_p = user.options) === null || _p === void 0 ? void 0 : _p.timezone) ? (_q = user.options) === null || _q === void 0 ? void 0 : _q.timezone : "N/A"}`);
657
+ console.log(`\nFollowers:\t${followersCount}`);
658
+ console.log(`Following:\t${followingCount}`);
659
+ console.log(`\nStatistics (Anime)\n\tCount: ${((_s = (_r = user.statistics) === null || _r === void 0 ? void 0 : _r.anime) === null || _s === void 0 ? void 0 : _s.count) || 0}\tEpisodes Watched: ${((_u = (_t = user.statistics) === null || _t === void 0 ? void 0 : _t.anime) === null || _u === void 0 ? void 0 : _u.episodesWatched) || 0}\tMinutes Watched: ${((_w = (_v = user.statistics) === null || _v === void 0 ? void 0 : _v.anime) === null || _w === void 0 ? void 0 : _w.minutesWatched) || 0}`);
660
+ console.log(`Statistics (Manga)\n\tCount: ${((_y = (_x = user.statistics) === null || _x === void 0 ? void 0 : _x.manga) === null || _y === void 0 ? void 0 : _y.count) || 0}\tChapters Read: ${((_0 = (_z = user.statistics) === null || _z === void 0 ? void 0 : _z.manga) === null || _0 === void 0 ? void 0 : _0.chaptersRead) || 0}\tVolumes Read: ${((_2 = (_1 = user.statistics) === null || _1 === void 0 ? void 0 : _1.manga) === null || _2 === void 0 ? void 0 : _2.volumesRead) || 0}`);
642
661
  if (activities.length > 0) {
643
662
  console.log(`\nRecent Activities:`);
644
663
  activities.forEach(({ status, progress, media, createdAt }) => {
@@ -678,6 +697,33 @@ class AniList {
678
697
  }
679
698
  });
680
699
  }
700
+ static getMangaDetailsByID(mangaID) {
701
+ return __awaiter(this, void 0, void 0, function* () {
702
+ var _a;
703
+ try {
704
+ const response = yield fetcher(mangaDetailsQuery, {
705
+ id: mangaID,
706
+ });
707
+ if (response === null || response === void 0 ? void 0 : response.errors) {
708
+ console.error(`${response.errors[0].message}`);
709
+ return;
710
+ }
711
+ const manga = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Media;
712
+ if (manga) {
713
+ console.log(`\n[${getTitle(manga.title)}]`);
714
+ console.log(`${manga.description}`);
715
+ console.log(`Chapters: ${manga.chapters}\t Volumes: ${manga.volumes}`);
716
+ console.log(`Status:\t${manga.status}`);
717
+ console.log(`Genres:\t${manga.genres.join(", ")}`);
718
+ console.log(`Start:\t${simpleDateFormat(manga.startDate)}`);
719
+ console.log(`End:\t${simpleDateFormat(manga.endDate)}`);
720
+ }
721
+ }
722
+ catch (error) {
723
+ console.error(`${error.message}`);
724
+ }
725
+ });
726
+ }
681
727
  static searchAnime(search, count) {
682
728
  return __awaiter(this, void 0, void 0, function* () {
683
729
  var _a, _b, _c;
@@ -804,8 +850,15 @@ class MyAnimeList {
804
850
  var _a, _b, _c, _d, _e;
805
851
  try {
806
852
  const filename = yield selectFile(".xml");
853
+ if (!filename) {
854
+ return;
855
+ }
807
856
  const filePath = join(getDownloadFolderPath(), filename);
808
857
  const fileContent = yield readFile(filePath, "utf8");
858
+ if (!(yield Validate.Import_AnimeXML(fileContent))) {
859
+ console.error(`\nInvalid XML file.`);
860
+ return;
861
+ }
809
862
  const parser = new XMLParser();
810
863
  if (fileContent) {
811
864
  const XMLObject = parser.parse(fileContent);
@@ -869,8 +922,15 @@ class MyAnimeList {
869
922
  var _a, _b, _c, _d, _e;
870
923
  try {
871
924
  const filename = yield selectFile(".xml");
925
+ if (!filename) {
926
+ return;
927
+ }
872
928
  const filePath = join(getDownloadFolderPath(), filename);
873
929
  const fileContent = yield readFile(filePath, "utf8");
930
+ if (!(yield Validate.Import_MangaXML(fileContent))) {
931
+ console.error(`\nInvalid XML file.`);
932
+ return;
933
+ }
874
934
  const parser = new XMLParser();
875
935
  if (fileContent) {
876
936
  const XMLObject = parser.parse(fileContent);
@@ -941,7 +1001,7 @@ class MyAnimeList {
941
1001
  if (((_b = (_a = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists.length) > 0) {
942
1002
  const lists = (_d = (_c = animeList === null || animeList === void 0 ? void 0 : animeList.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
943
1003
  const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
944
- var _a, _b, _c, _d, _e;
1004
+ var _a, _b, _c, _d, _e, _f;
945
1005
  return ({
946
1006
  id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
947
1007
  malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
@@ -951,13 +1011,10 @@ class MyAnimeList {
951
1011
  progress: entry.progress,
952
1012
  status: entry === null || entry === void 0 ? void 0 : entry.status,
953
1013
  hiddenFromStatusLists: false,
1014
+ format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
954
1015
  });
955
1016
  }));
956
- const xmlContent = createAnimeListXML(mediaWithProgress);
957
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
958
- yield writeFile(path, yield xmlContent, "utf8");
959
- console.log(`Generated XML for MyAnimeList.`);
960
- open(getDownloadFolderPath());
1017
+ yield saveJSONasXML(mediaWithProgress, 0);
961
1018
  }
962
1019
  else {
963
1020
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -992,11 +1049,7 @@ class MyAnimeList {
992
1049
  status: entry.status,
993
1050
  hiddenFromStatusLists: entry.hiddenFromStatusLists,
994
1051
  })));
995
- const XMLContent = createMangaListXML(mediaWithProgress);
996
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
997
- yield writeFile(path, yield XMLContent, "utf8");
998
- console.log(`Generated XML for MyAnimeList.`);
999
- open(getDownloadFolderPath());
1052
+ yield saveJSONasXML(mediaWithProgress, 1);
1000
1053
  }
1001
1054
  else {
1002
1055
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -1008,4 +1061,99 @@ class MyAnimeList {
1008
1061
  });
1009
1062
  }
1010
1063
  }
1011
- export { AniList, MyAnimeList };
1064
+ class AniDB {
1065
+ static importAnime() {
1066
+ return __awaiter(this, void 0, void 0, function* () {
1067
+ var _a, _b;
1068
+ try {
1069
+ const filename = yield selectFile(".json");
1070
+ if (!filename) {
1071
+ return;
1072
+ }
1073
+ const filePath = join(getDownloadFolderPath(), filename);
1074
+ const fileContent = yield readFile(filePath, "utf8");
1075
+ const js0n_repaired = jsonrepair(fileContent);
1076
+ if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
1077
+ console.error(`\nInvalid JSON Large file.`);
1078
+ return;
1079
+ }
1080
+ if (js0n_repaired) {
1081
+ const obj3ct = yield JSON.parse(js0n_repaired);
1082
+ const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
1083
+ if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
1084
+ let count = 0;
1085
+ let iteration = 0;
1086
+ let missed = [];
1087
+ for (const anime of animeList) {
1088
+ iteration++;
1089
+ const anidbId = anime.id;
1090
+ const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
1091
+ const status = anime.status;
1092
+ // const type = anime.type
1093
+ const totalEpisodes = anime.totalEpisodes;
1094
+ const ownEpisodes = anime.ownEpisodes;
1095
+ const romanjiName = anime.romanjiName;
1096
+ const englishName = anime.englishName;
1097
+ function getStatus(anidbStatus, episodesSeen) {
1098
+ if (anidbStatus === "complete") {
1099
+ return AniListMediaStatus.COMPLETED;
1100
+ }
1101
+ else if (anidbStatus === "incomplete" &&
1102
+ Number(episodesSeen) > 0) {
1103
+ return AniListMediaStatus.CURRENT;
1104
+ }
1105
+ else {
1106
+ return AniListMediaStatus.PLANNING;
1107
+ }
1108
+ }
1109
+ let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
1110
+ if (anilistId) {
1111
+ try {
1112
+ const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
1113
+ mediaId: anilistId,
1114
+ progress: ownEpisodes - 2,
1115
+ status: getStatus(status, ownEpisodes),
1116
+ hiddenFromStatusLists: false,
1117
+ private: false,
1118
+ });
1119
+ const entryId = (_b = (_a = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
1120
+ if (entryId) {
1121
+ count++;
1122
+ console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1123
+ }
1124
+ // Rate limit each API call to avoid server overload
1125
+ // await new Promise((resolve) => setTimeout(resolve, 1100))
1126
+ }
1127
+ catch (error) {
1128
+ console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
1129
+ }
1130
+ }
1131
+ else {
1132
+ missed.push({
1133
+ anidbId: anidbId,
1134
+ englishTitle: englishName,
1135
+ romajiTitle: romanjiName,
1136
+ });
1137
+ }
1138
+ }
1139
+ console.log(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
1140
+ if (missed.length > 0) {
1141
+ console.log(`Exporting missed entries to JSON file, Please add them manually.`);
1142
+ yield saveJSONasJSON(missed, "anidb-missed");
1143
+ }
1144
+ }
1145
+ else {
1146
+ console.log(`\nNo anime list found in the file.`);
1147
+ }
1148
+ }
1149
+ else {
1150
+ console.log(`\nNo content found in the file or unable to read.`);
1151
+ }
1152
+ }
1153
+ catch (error) {
1154
+ console.error(`\nError in AniDB import process: ${error.message}`);
1155
+ }
1156
+ });
1157
+ }
1158
+ }
1159
+ export { AniDB, AniList, MyAnimeList };
@@ -4,5 +4,4 @@ declare const deleteActivityMutation = "\nmutation($id: Int!) {\n DeleteActivit
4
4
  declare const saveTextActivityMutation = "\nmutation SaveTextActivity($status: String!) {\n SaveTextActivity(text: $status) { id text userId createdAt }\n}\n";
5
5
  declare const saveAnimeWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean) {\n SaveMediaListEntry(mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists) {\n id progress hiddenFromStatusLists\n }\n}\n";
6
6
  declare const saveMangaWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean, $private: Boolean) {\n SaveMediaListEntry( mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists, private: $private\n ) { id progress hiddenFromStatusLists private }\n}\n";
7
- declare const likeActivityMutation = "\nmutation($activityId: Int!) {\n ToggleLike(id: $activityId, type: ACTIVITY) { id }\n}\n";
8
- export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
7
+ export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
@@ -35,9 +35,4 @@ mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromSt
35
35
  ) { id progress hiddenFromStatusLists private }
36
36
  }
37
37
  `;
38
- const likeActivityMutation = `
39
- mutation($activityId: Int!) {
40
- ToggleLike(id: $activityId, type: ACTIVITY) { id }
41
- }
42
- `;
43
- export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
38
+ export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
@@ -2,14 +2,14 @@ declare const currentUserQuery = "{\n Viewer {\n id name about bans siteUrl
2
2
  declare const trendingQuery = "query ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n media(sort: TRENDING_DESC, type: ANIME) { id title { romaji english } }\n }\n}";
3
3
  declare const popularQuery = "query ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n media(sort: POPULARITY_DESC, type: ANIME) { id title { romaji english } }\n }\n}";
4
4
  declare const userQuery = "query ($username: String) {\n User(name: $username) {\n id name siteUrl donatorTier donatorBadge createdAt updatedAt previousNames { name createdAt updatedAt }\n isBlocked isFollower isFollowing options { profileColor timezone activityMergeTime }\n statistics { anime { count episodesWatched minutesWatched } manga { count chaptersRead volumesRead } }\n }\n}";
5
- declare const currentUserAnimeList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: ANIME) {\n lists { name entries { id progress hiddenFromStatusLists status media { id idMal title { romaji english } status episodes siteUrl } } }\n }\n}\n";
6
- declare const currentUserMangaList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: MANGA) {\n lists { name entries { id progress hiddenFromStatusLists private status media { id idMal title { romaji english } status chapters } } }\n }\n}\n";
5
+ declare const currentUserAnimeList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: ANIME) {\n lists { name entries { id progress hiddenFromStatusLists status media { id idMal title { romaji english native userPreferred } status episodes siteUrl format } } }\n }\n}\n";
6
+ declare const currentUserMangaList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: MANGA) {\n lists { name entries { id progress hiddenFromStatusLists private status media { id idMal title { romaji english native userPreferred } status chapters } } }\n }\n}\n";
7
7
  declare const deleteMediaEntryMutation = "mutation($id: Int!) {\n DeleteMediaListEntry(id: $id) { deleted }\n}";
8
8
  declare const deleteMangaEntryMutation = "mutation($id: Int) {\n DeleteMediaListEntry(id: $id) { deleted }\n}";
9
9
  declare const upcomingAnimesQuery = "query GetNextSeasonAnime($nextSeason: MediaSeason, $nextYear: Int, $perPage: Int) {\n Page(perPage: $perPage) {\n media(season: $nextSeason, seasonYear: $nextYear, type: ANIME, sort: POPULARITY_DESC) {\n id title { romaji english native userPreferred } season seasonYear startDate { year month day }\n episodes description genres\n }\n }\n}";
10
10
  declare const animeDetailsQuery = "query ($id: Int) {\n Media(id: $id) {\n id idMal title { romaji english native userPreferred } episodes nextAiringEpisode { id }\n duration startDate { year month day } endDate { year month day } countryOfOrigin description isAdult status season format genres siteUrl\n stats { scoreDistribution { score amount } statusDistribution { status amount } }\n }\n}";
11
11
  declare const userActivityQuery = "query ($id: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $id, type_in: [ANIME_LIST, MANGA_LIST], sort: ID_DESC) {\n ... on ListActivity { id status progress createdAt media { id title { romaji english } } }\n }\n }\n}";
12
- declare const animeSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: ANIME) { id title { romaji english native userPreferred } episodes status description }\n }\n}";
12
+ declare const animeSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: ANIME) { id title { romaji english native userPreferred } startDate { day month year } episodes status description }\n }\n}";
13
13
  declare const mangaSearchQuery = "query ($search: String, $perPage: Int) {\n Page(perPage: $perPage) {\n media(search: $search, type: MANGA) { id title { romaji english native userPreferred } chapters status description }\n }\n}";
14
14
  declare const activityTextQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: TEXT, sort: ID_DESC) {\n ... on TextActivity { id type text createdAt user { id name } }\n }\n }\n}";
15
15
  declare const activityAnimeListQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: ANIME_LIST, sort: ID_DESC) {\n ... on ListActivity { id type status progress createdAt media { id title { romaji english native } } }\n }\n }\n}";
@@ -17,9 +17,10 @@ declare const activityMangaListQuery = "query ($userId: Int, $page: Int, $perPag
17
17
  declare const activityMessageQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: MESSAGE, sort: ID_DESC) {\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
18
18
  declare const activityAllQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, sort: ID_DESC) {\n ... on TextActivity { id type text createdAt user { id name } }\n ... on ListActivity { id type status progress createdAt media { id title { romaji english native } } }\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
19
19
  declare const activityMediaList = "query ($userId: Int, $page: Int, $perPage: Int, $type: ActivityType) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total currentPage lastPage hasNextPage perPage }\n activities(userId: $userId, type: $type, sort: ID_DESC) {\n ... on ListActivity { id type status progress media { id title { romaji english native } format } createdAt }\n }\n }\n}";
20
- declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) { id title { romaji english } } }\n";
21
- declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) { id title { romaji english } } }\n";
22
- declare const followingActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(isFollowing: true, sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
23
- declare const globalActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
24
- declare const specificUserActivitiesQuery = "\nquery ($page: Int, $perPage: Int, $userId: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { messenger { name } id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
25
- export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, };
20
+ declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) {\n id title { romaji english } } \n}\n";
21
+ declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) {\n id title { romaji english } } \n}\n";
22
+ declare const userFollowingQuery = "query ($userId: Int!, $page: Int) {\n Page (page: $page) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }\n }\n}\n";
23
+ declare const userFollowersQuery = "query ($userId: Int!, $page: Int) {\n Page (page: $page) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }\n }\n}\n";
24
+ declare const toggleFollowMutation = "mutation ($userId: Int!) {\n ToggleFollow(userId: $userId) { id name isFollower isFollowing }\n}\n";
25
+ declare const mangaDetailsQuery = "query ($id: Int) {\n Media(id: $id, type: MANGA) {\n id title { romaji english native userPreferred } coverImage { color medium large extraLarge } \n bannerImage description chapters volumes status genres\n startDate { year month day } endDate { year month day }\n }\n}\n";
26
+ export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };