@irfanshadikrishad/anilist 1.2.0-forbidden.1 → 1.2.0-forbidden.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,24 +8,33 @@ 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 fetch from "node-fetch";
13
+ import { jsonrepair } from "jsonrepair";
14
14
  import { join } from "path";
15
15
  import { Auth } from "./auth.js";
16
16
  import { fetcher } from "./fetcher.js";
17
17
  import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
18
- 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";
19
+ import { responsiveOutput } from "./truncate.js";
19
20
  import { AniListMediaStatus, } from "./types.js";
20
- import { aniListEndpoint, createAnimeListXML, createMangaListXML, formatDateObject, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, } from "./workers.js";
21
+ import { Validate } from "./validation.js";
22
+ import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from "./workers.js";
21
23
  class AniList {
22
24
  static importAnime() {
23
25
  return __awaiter(this, void 0, void 0, function* () {
24
26
  try {
25
27
  const filename = yield selectFile(".json");
28
+ if (!filename) {
29
+ return;
30
+ }
26
31
  const filePath = join(getDownloadFolderPath(), filename);
27
32
  const fileContent = yield readFile(filePath, "utf8");
28
33
  const importedData = JSON.parse(fileContent);
34
+ if (!Validate.Import_JSON(importedData)) {
35
+ console.error(`\nInvalid JSON file.`);
36
+ return;
37
+ }
29
38
  let count = 0;
30
39
  const batchSize = 1; // Number of requests in each batch
31
40
  const delay = 1100; // delay to avoid rate-limiting
@@ -69,9 +78,16 @@ class AniList {
69
78
  return __awaiter(this, void 0, void 0, function* () {
70
79
  try {
71
80
  const filename = yield selectFile(".json");
81
+ if (!filename) {
82
+ return;
83
+ }
72
84
  const filePath = join(getDownloadFolderPath(), filename);
73
85
  const fileContent = yield readFile(filePath, "utf8");
74
86
  const importedData = JSON.parse(fileContent);
87
+ if (!Validate.Import_JSON(importedData)) {
88
+ console.error(`\nInvalid JSON file.`);
89
+ return;
90
+ }
75
91
  let count = 0;
76
92
  const batchSize = 1; // Adjust batch size as per rate-limit constraints
77
93
  const delay = 1100; // 2 seconds delay to avoid rate-limit
@@ -113,7 +129,76 @@ class AniList {
113
129
  static exportAnime() {
114
130
  return __awaiter(this, void 0, void 0, function* () {
115
131
  var _a, _b, _c;
116
- if (yield Auth.isLoggedIn()) {
132
+ if (!(yield Auth.isLoggedIn())) {
133
+ console.error(`\nMust login to use this feature.`);
134
+ return;
135
+ }
136
+ const { exportType } = yield inquirer.prompt([
137
+ {
138
+ type: "list",
139
+ name: "exportType",
140
+ message: "Choose export type:",
141
+ choices: [
142
+ { name: "CSV", value: 1 },
143
+ { name: "JSON", value: 2 },
144
+ { name: "XML (MyAnimeList/AniDB)", value: 3 },
145
+ ],
146
+ pageSize: 10,
147
+ },
148
+ ]);
149
+ const animeList = yield fetcher(currentUserAnimeList, {
150
+ id: yield Auth.MyUserId(),
151
+ });
152
+ if (animeList) {
153
+ 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 : [];
154
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
155
+ var _a, _b, _c, _d;
156
+ return ({
157
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
158
+ title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
159
+ episodes: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.episodes,
160
+ siteUrl: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.siteUrl,
161
+ progress: entry.progress,
162
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
163
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
164
+ });
165
+ }));
166
+ switch (exportType) {
167
+ case 1:
168
+ yield saveJSONasCSV(mediaWithProgress, "anime");
169
+ break;
170
+ case 2:
171
+ yield saveJSONasJSON(mediaWithProgress, "anime");
172
+ break;
173
+ case 3:
174
+ yield MyAnimeList.exportAnime();
175
+ break;
176
+ default:
177
+ console.log(`\nInvalid export type. ${exportType}`);
178
+ break;
179
+ }
180
+ }
181
+ else {
182
+ console.error(`\nNo anime(s) found in your lists.`);
183
+ }
184
+ });
185
+ }
186
+ static exportManga() {
187
+ return __awaiter(this, void 0, void 0, function* () {
188
+ var _a, _b;
189
+ if (!(yield Auth.isLoggedIn())) {
190
+ console.error(`\nPlease login to use this feature.`);
191
+ return;
192
+ }
193
+ const mangaLists = yield fetcher(currentUserMangaList, {
194
+ id: yield Auth.MyUserId(),
195
+ });
196
+ if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
197
+ console.error(`\nCould not get manga list.`);
198
+ return;
199
+ }
200
+ 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) || [];
201
+ if (lists.length > 0) {
117
202
  const { exportType } = yield inquirer.prompt([
118
203
  {
119
204
  type: "list",
@@ -127,141 +212,53 @@ class AniList {
127
212
  pageSize: 10,
128
213
  },
129
214
  ]);
130
- const animeList = yield fetcher(currentUserAnimeList, {
131
- id: yield Auth.MyUserId(),
132
- });
133
- if (animeList) {
134
- 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 : [];
135
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
136
- var _a, _b, _c, _d, _e;
137
- return ({
138
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
139
- title: exportType === 1
140
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
141
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
142
- episodes: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.episodes,
143
- siteUrl: (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.siteUrl,
144
- progress: entry.progress,
145
- status: entry === null || entry === void 0 ? void 0 : entry.status,
146
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
147
- });
148
- }));
149
- switch (exportType) {
150
- case 1:
151
- yield saveJSONasCSV(mediaWithProgress, "anime");
152
- break;
153
- case 2:
154
- yield saveJSONasJSON(mediaWithProgress, "anime");
155
- break;
156
- case 3:
157
- yield MyAnimeList.exportAnime();
158
- break;
159
- default:
160
- console.log(`\nInvalid export type. ${exportType}`);
161
- break;
162
- }
163
- }
164
- else {
165
- console.error(`\nNo anime(s) found in your lists.`);
166
- }
167
- }
168
- else {
169
- console.error(`\nMust login to use this feature.`);
170
- }
171
- });
172
- }
173
- static exportManga() {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- var _a, _b;
176
- if (yield Auth.isLoggedIn()) {
177
- const mangaLists = yield fetcher(currentUserMangaList, {
178
- id: yield Auth.MyUserId(),
179
- });
180
- if (mangaLists) {
181
- 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) || [];
182
- if (lists.length > 0) {
183
- const { exportType } = yield inquirer.prompt([
184
- {
185
- type: "list",
186
- name: "exportType",
187
- message: "Choose export type:",
188
- choices: [
189
- { name: "CSV", value: 1 },
190
- { name: "JSON", value: 2 },
191
- { name: "XML (MyAnimeList)", value: 3 },
192
- ],
193
- pageSize: 10,
194
- },
195
- ]);
196
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
197
- var _a, _b, _c;
198
- return ({
199
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
200
- title: exportType === 1
201
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
202
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
203
- private: entry.private,
204
- chapters: entry.media.chapters,
205
- progress: entry.progress,
206
- status: entry === null || entry === void 0 ? void 0 : entry.status,
207
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
208
- });
209
- }));
210
- switch (exportType) {
211
- case 1:
212
- yield saveJSONasCSV(mediaWithProgress, "manga");
213
- break;
214
- case 2:
215
- yield saveJSONasJSON(mediaWithProgress, "manga");
216
- break;
217
- case 3:
218
- yield MyAnimeList.exportManga();
219
- break;
220
- default:
221
- console.log(`\nInvalid export type. ${exportType}`);
222
- break;
223
- }
224
- }
225
- else {
226
- console.log(`\nList seems to be empty.`);
227
- }
228
- }
229
- else {
230
- console.error(`\nCould not get manga list.`);
215
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
216
+ var _a, _b;
217
+ return ({
218
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
219
+ title: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title,
220
+ private: entry.private,
221
+ chapters: entry.media.chapters,
222
+ progress: entry.progress,
223
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
224
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
225
+ });
226
+ }));
227
+ switch (exportType) {
228
+ case 1:
229
+ yield saveJSONasCSV(mediaWithProgress, "manga");
230
+ break;
231
+ case 2:
232
+ yield saveJSONasJSON(mediaWithProgress, "manga");
233
+ break;
234
+ case 3:
235
+ yield MyAnimeList.exportManga();
236
+ break;
237
+ default:
238
+ console.log(`\nInvalid export type. ${exportType}`);
239
+ break;
231
240
  }
232
241
  }
233
242
  else {
234
- console.error(`\nPlease login to use this feature.`);
243
+ console.log(`\nList seems to be empty.`);
235
244
  }
236
245
  });
237
246
  }
238
247
  static MyAnime() {
239
248
  return __awaiter(this, void 0, void 0, function* () {
240
- var _a, _b, _c;
249
+ var _a, _b, _c, _d, _e;
241
250
  try {
242
251
  if (!(yield Auth.isLoggedIn())) {
243
252
  return console.error(`\nPlease log in first to access your lists.`);
244
253
  }
245
- const userId = yield Auth.MyUserId();
246
- if (!userId) {
254
+ if (!(yield Auth.MyUserId())) {
247
255
  return console.log(`\nFailed getting current user Id.`);
248
256
  }
249
- const request = yield fetch(aniListEndpoint, {
250
- method: "POST",
251
- headers: {
252
- "content-type": "application/json",
253
- "Authorization": `Bearer ${yield Auth.RetriveAccessToken()}`,
254
- },
255
- body: JSON.stringify({
256
- query: currentUserAnimeList,
257
- variables: { id: userId },
258
- }),
259
- });
260
- const { data, errors } = yield request.json();
261
- if (request.status !== 200 || errors) {
262
- return console.log(`\nSomething went wrong. ${(_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message}`);
257
+ const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
258
+ if (data === null || data === void 0 ? void 0 : data.errors) {
259
+ 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}`);
263
260
  }
264
- const lists = (_b = data === null || data === void 0 ? void 0 : data.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
261
+ const lists = (_d = (_c = data === null || data === void 0 ? void 0 : data.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
265
262
  if (!lists || lists.length === 0) {
266
263
  return console.log(`\nYou seem to have no anime(s) in your lists.`);
267
264
  }
@@ -304,11 +301,12 @@ class AniList {
304
301
  ],
305
302
  },
306
303
  ]);
307
- const query = addAnimeToListMutation;
308
- const variables = { mediaId: selectedAnime, status: selectedListType };
309
- const saveResponse = yield fetcher(query, variables);
304
+ const saveResponse = yield fetcher(addAnimeToListMutation, {
305
+ mediaId: selectedAnime,
306
+ status: selectedListType,
307
+ });
310
308
  if (saveResponse) {
311
- const savedEntry = (_c = saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
309
+ const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
312
310
  console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
313
311
  }
314
312
  else {
@@ -322,7 +320,7 @@ class AniList {
322
320
  }
323
321
  static MyManga() {
324
322
  return __awaiter(this, void 0, void 0, function* () {
325
- var _a, _b, _c, _d, _e;
323
+ var _a, _b, _c, _d, _e, _f, _g;
326
324
  try {
327
325
  if (!(yield Auth.isLoggedIn())) {
328
326
  return console.error(`\nPlease log in first to access your lists.`);
@@ -331,23 +329,11 @@ class AniList {
331
329
  if (!userId) {
332
330
  return console.error(`\nFailed to get the current user ID.`);
333
331
  }
334
- const token = yield Auth.RetriveAccessToken();
335
- const request = yield fetch(aniListEndpoint, {
336
- method: "POST",
337
- headers: {
338
- "Content-Type": "application/json",
339
- "Authorization": `Bearer ${token}`,
340
- },
341
- body: JSON.stringify({
342
- query: currentUserMangaList,
343
- variables: { id: userId },
344
- }),
345
- });
346
- const { data, errors } = yield request.json();
347
- if (request.status !== 200 || errors) {
348
- return console.error(`\nFailed to fetch manga lists. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
332
+ const response = yield fetcher(currentUserMangaList, { id: userId });
333
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
334
+ return console.error(`\nFailed to fetch manga lists. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
349
335
  }
350
- const lists = (_b = data === null || data === void 0 ? void 0 : data.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
336
+ const lists = (_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
351
337
  if (!lists || lists.length === 0) {
352
338
  return console.log("\nYou don't seem to have any manga in your lists.");
353
339
  }
@@ -393,24 +379,16 @@ class AniList {
393
379
  ],
394
380
  },
395
381
  ]);
396
- const saveRequest = yield fetch(aniListEndpoint, {
397
- method: "POST",
398
- headers: {
399
- "Content-Type": "application/json",
400
- "Authorization": `Bearer ${token}`,
401
- },
402
- body: JSON.stringify({
403
- query: addMangaToListMutation,
404
- variables: { mediaId: selectedManga, status: selectedListType },
405
- }),
382
+ const saveResponse = yield fetcher(addMangaToListMutation, {
383
+ mediaId: selectedManga,
384
+ status: selectedListType,
406
385
  });
407
- const saveResponse = yield saveRequest.json();
408
- const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
386
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
409
387
  if (saved) {
410
388
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
411
389
  }
412
390
  else {
413
- console.error(`\nFailed to save the manga. ${((_e = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.message) || "Unknown error"}`);
391
+ console.error(`\nFailed to save the manga. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
414
392
  }
415
393
  }
416
394
  catch (error) {
@@ -420,27 +398,17 @@ class AniList {
420
398
  }
421
399
  static getTrendingAnime(count) {
422
400
  return __awaiter(this, void 0, void 0, function* () {
423
- var _a, _b, _c, _d, _e;
401
+ var _a, _b, _c, _d, _e, _f, _g;
424
402
  try {
425
403
  let page = 1;
426
404
  let allTrending = [];
427
405
  while (true) {
428
- const request = yield fetch(aniListEndpoint, {
429
- method: "POST",
430
- headers: {
431
- "Content-Type": "application/json",
432
- },
433
- body: JSON.stringify({
434
- query: trendingQuery,
435
- variables: { page, perPage: count },
436
- }),
437
- });
438
- const { data, errors } = yield request.json();
439
- if (request.status !== 200 || errors) {
440
- console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
406
+ const response = yield fetcher(trendingQuery, { page, perPage: count });
407
+ if (response === null || response === void 0 ? void 0 : response.errors) {
408
+ console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
441
409
  return;
442
410
  }
443
- const media = (_b = data === null || data === void 0 ? void 0 : data.Page) === null || _b === void 0 ? void 0 : _b.media;
411
+ const media = (_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.media;
444
412
  if (!media || media.length === 0) {
445
413
  console.log(`\nNo more trending anime available.`);
446
414
  break;
@@ -448,7 +416,7 @@ class AniList {
448
416
  allTrending = [...allTrending, ...media];
449
417
  const choices = allTrending.map((anime, idx) => ({
450
418
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
451
- value: anime === null || anime === void 0 ? void 0 : anime.id,
419
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
452
420
  }));
453
421
  choices.push({ name: "See more", value: "see_more" });
454
422
  const { selectedAnime } = yield inquirer.prompt([
@@ -485,12 +453,12 @@ class AniList {
485
453
  }
486
454
  const variables = { mediaId: selectedAnime, status: selectedListType };
487
455
  const saveResponse = yield fetcher(addAnimeToListMutation, variables);
488
- const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
456
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
489
457
  if (saved) {
490
458
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
491
459
  }
492
460
  else {
493
- console.error(`\nFailed to save the anime. ${((_e = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.message) || "Unknown error"}`);
461
+ console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
494
462
  }
495
463
  break;
496
464
  }
@@ -503,27 +471,17 @@ class AniList {
503
471
  }
504
472
  static getPopularAnime(count) {
505
473
  return __awaiter(this, void 0, void 0, function* () {
506
- var _a, _b, _c, _d, _e;
474
+ var _a, _b, _c, _d, _e, _f, _g;
507
475
  try {
508
476
  let page = 1;
509
477
  let allMedia = [];
510
478
  while (true) {
511
- const request = yield fetch(aniListEndpoint, {
512
- method: "POST",
513
- headers: {
514
- "Content-Type": "application/json",
515
- },
516
- body: JSON.stringify({
517
- query: popularQuery,
518
- variables: { page, perPage: count },
519
- }),
520
- });
521
- const { data, errors } = yield request.json();
522
- if (request.status !== 200 || errors) {
523
- console.error(`\nSomething went wrong. ${((_a = errors === null || errors === void 0 ? void 0 : errors[0]) === null || _a === void 0 ? void 0 : _a.message) || "Unknown error"}`);
479
+ const response = yield fetcher(popularQuery, { page, perPage: count });
480
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
481
+ console.error(`\nSomething went wrong. ${((_b = (_a = response === null || response === void 0 ? void 0 : response.errors) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.message) || "Unknown error"}`);
524
482
  return;
525
483
  }
526
- const newMedia = (_b = data === null || data === void 0 ? void 0 : data.Page) === null || _b === void 0 ? void 0 : _b.media;
484
+ const newMedia = (_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.media;
527
485
  if (!newMedia || newMedia.length === 0) {
528
486
  console.log(`\nNo more popular anime available.`);
529
487
  break;
@@ -531,7 +489,7 @@ class AniList {
531
489
  allMedia = [...allMedia, ...newMedia];
532
490
  const choices = allMedia.map((anime, idx) => ({
533
491
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
534
- value: anime === null || anime === void 0 ? void 0 : anime.id,
492
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
535
493
  }));
536
494
  choices.push({ name: "See more", value: "see_more" });
537
495
  const { selectedAnime } = yield inquirer.prompt([
@@ -567,12 +525,12 @@ class AniList {
567
525
  }
568
526
  const variables = { mediaId: selectedAnime, status: selectedListType };
569
527
  const saveResponse = yield fetcher(addAnimeToListMutation, variables);
570
- const saved = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
528
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
571
529
  if (saved) {
572
530
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
573
531
  }
574
532
  else {
575
- console.error(`\nFailed to save the anime. ${((_e = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.message) || "Unknown error"}`);
533
+ console.error(`\nFailed to save the anime. ${((_g = (_f = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.message) || "Unknown error"}`);
576
534
  }
577
535
  break;
578
536
  }
@@ -609,7 +567,7 @@ class AniList {
609
567
  allUpcoming = [...allUpcoming, ...newUpcoming];
610
568
  const choices = allUpcoming.map((anime, idx) => ({
611
569
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
612
- value: anime === null || anime === void 0 ? void 0 : anime.id,
570
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
613
571
  }));
614
572
  choices.push({ name: "See more", value: "see_more" });
615
573
  const { selectedAnime } = yield inquirer.prompt([
@@ -663,22 +621,11 @@ class AniList {
663
621
  }
664
622
  static getUserByUsername(username) {
665
623
  return __awaiter(this, void 0, void 0, function* () {
666
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
624
+ 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;
667
625
  try {
668
- const headers = {
669
- "Content-Type": "application/json",
670
- };
671
- if (yield Auth.isLoggedIn()) {
672
- headers["Authorization"] = `Bearer ${yield Auth.RetriveAccessToken()}`;
673
- }
674
- const request = yield fetch(aniListEndpoint, {
675
- method: "POST",
676
- headers,
677
- body: JSON.stringify({ query: userQuery, variables: { username } }),
678
- });
679
- const response = yield request.json();
680
- if (request.status !== 200 || !((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
681
- return console.error(`\n${request.status} ${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
626
+ const response = yield fetcher(userQuery, { username });
627
+ if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
628
+ return console.error(`\n${((_c = (_b = response === null || response === void 0 ? void 0 : response.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || "Unknown error"}`);
682
629
  }
683
630
  const user = response.data.User;
684
631
  const userActivityResponse = yield fetcher(userActivityQuery, {
@@ -687,6 +634,15 @@ class AniList {
687
634
  perPage: 10,
688
635
  });
689
636
  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 : [];
637
+ // Get follower/following information
638
+ const req_followers = yield fetcher(userFollowersQuery, {
639
+ userId: user === null || user === void 0 ? void 0 : user.id,
640
+ });
641
+ const req_following = yield fetcher(userFollowingQuery, {
642
+ userId: user === null || user === void 0 ? void 0 : user.id,
643
+ });
644
+ 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;
645
+ 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;
690
646
  console.log(`\nID:\t\t${user.id}`);
691
647
  console.log(`Name:\t\t${user.name}`);
692
648
  console.log(`Site URL:\t${user.siteUrl}`);
@@ -697,14 +653,16 @@ class AniList {
697
653
  console.log(`Blocked:\t${user.isBlocked}`);
698
654
  console.log(`Follower:\t${user.isFollower}`);
699
655
  console.log(`Following:\t${user.isFollowing}`);
700
- console.log(`Profile Color:\t${(_g = user.options) === null || _g === void 0 ? void 0 : _g.profileColor}`);
701
- console.log(`Timezone:\t${(_h = user.options) === null || _h === void 0 ? void 0 : _h.timezone}`);
702
- 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}`);
703
- 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}`);
656
+ console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
657
+ 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"}`);
658
+ console.log(`\nFollowers:\t${followersCount}`);
659
+ console.log(`Following:\t${followingCount}`);
660
+ 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}`);
661
+ 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}`);
704
662
  if (activities.length > 0) {
705
663
  console.log(`\nRecent Activities:`);
706
- activities.forEach(({ status, progress, media }) => {
707
- console.log(`${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
664
+ activities.forEach(({ status, progress, media, createdAt }) => {
665
+ responsiveOutput(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
708
666
  });
709
667
  }
710
668
  else {
@@ -719,9 +677,9 @@ class AniList {
719
677
  static getAnimeDetailsByID(anilistID) {
720
678
  return __awaiter(this, void 0, void 0, function* () {
721
679
  var _a;
722
- const query = animeDetailsQuery;
723
- const variables = { id: anilistID };
724
- const details = yield fetcher(query, variables);
680
+ const details = yield fetcher(animeDetailsQuery, {
681
+ id: anilistID,
682
+ });
725
683
  if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
726
684
  const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
727
685
  console.log(`\nID: ${id}`);
@@ -740,12 +698,41 @@ class AniList {
740
698
  }
741
699
  });
742
700
  }
701
+ static getMangaDetailsByID(mangaID) {
702
+ return __awaiter(this, void 0, void 0, function* () {
703
+ var _a;
704
+ try {
705
+ const response = yield fetcher(mangaDetailsQuery, {
706
+ id: mangaID,
707
+ });
708
+ if (response === null || response === void 0 ? void 0 : response.errors) {
709
+ console.error(`${response.errors[0].message}`);
710
+ return;
711
+ }
712
+ const manga = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Media;
713
+ if (manga) {
714
+ console.log(`\n[${getTitle(manga.title)}]`);
715
+ console.log(`${manga.description}`);
716
+ console.log(`Chapters: ${manga.chapters}\t Volumes: ${manga.volumes}`);
717
+ console.log(`Status:\t${manga.status}`);
718
+ console.log(`Genres:\t${manga.genres.join(", ")}`);
719
+ console.log(`Start:\t${simpleDateFormat(manga.startDate)}`);
720
+ console.log(`End:\t${simpleDateFormat(manga.endDate)}`);
721
+ }
722
+ }
723
+ catch (error) {
724
+ console.error(`${error.message}`);
725
+ }
726
+ });
727
+ }
743
728
  static searchAnime(search, count) {
744
729
  return __awaiter(this, void 0, void 0, function* () {
745
730
  var _a, _b, _c;
746
- const query = animeSearchQuery;
747
- const variables = { search, page: 1, perPage: count };
748
- const searchResults = yield fetcher(query, variables);
731
+ const searchResults = yield fetcher(animeSearchQuery, {
732
+ search,
733
+ page: 1,
734
+ perPage: count,
735
+ });
749
736
  if (searchResults) {
750
737
  const results = (_b = (_a = searchResults === null || searchResults === void 0 ? void 0 : searchResults.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
751
738
  if (results.length > 0) {
@@ -777,12 +764,10 @@ class AniList {
777
764
  ]);
778
765
  // Save selected anime to chosen list type
779
766
  if (yield Auth.isLoggedIn()) {
780
- const saveQuery = addAnimeToListMutation;
781
- const saveVariables = {
767
+ const response = yield fetcher(addAnimeToListMutation, {
782
768
  mediaId: selectedAnime,
783
769
  status: selectedListType,
784
- };
785
- const response = yield fetcher(saveQuery, saveVariables);
770
+ });
786
771
  if (response) {
787
772
  const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
788
773
  console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
@@ -804,9 +789,11 @@ class AniList {
804
789
  static searchManga(search, count) {
805
790
  return __awaiter(this, void 0, void 0, function* () {
806
791
  var _a, _b, _c;
807
- const query = mangaSearchQuery;
808
- const variables = { search, page: 1, perPage: count };
809
- const mangaSearchResult = yield fetcher(query, variables);
792
+ const mangaSearchResult = yield fetcher(mangaSearchQuery, {
793
+ search,
794
+ page: 1,
795
+ perPage: count,
796
+ });
810
797
  if (mangaSearchResult) {
811
798
  const results = (_b = (_a = mangaSearchResult === null || mangaSearchResult === void 0 ? void 0 : mangaSearchResult.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.media;
812
799
  // List of manga search results
@@ -839,9 +826,10 @@ class AniList {
839
826
  ]);
840
827
  // If logged in save to the list
841
828
  if (yield Auth.isLoggedIn()) {
842
- const mutation = addMangaToListMutation;
843
- const variables = { mediaId: selectedMangaId, status: selectedListType };
844
- const response = yield fetcher(mutation, variables);
829
+ const response = yield fetcher(addMangaToListMutation, {
830
+ mediaId: selectedMangaId,
831
+ status: selectedListType,
832
+ });
845
833
  if (response) {
846
834
  const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
847
835
  console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
@@ -863,8 +851,15 @@ class MyAnimeList {
863
851
  var _a, _b, _c, _d, _e;
864
852
  try {
865
853
  const filename = yield selectFile(".xml");
854
+ if (!filename) {
855
+ return;
856
+ }
866
857
  const filePath = join(getDownloadFolderPath(), filename);
867
858
  const fileContent = yield readFile(filePath, "utf8");
859
+ if (!(yield Validate.Import_AnimeXML(fileContent))) {
860
+ console.error(`\nInvalid XML file.`);
861
+ return;
862
+ }
868
863
  const parser = new XMLParser();
869
864
  if (fileContent) {
870
865
  const XMLObject = parser.parse(fileContent);
@@ -928,8 +923,15 @@ class MyAnimeList {
928
923
  var _a, _b, _c, _d, _e;
929
924
  try {
930
925
  const filename = yield selectFile(".xml");
926
+ if (!filename) {
927
+ return;
928
+ }
931
929
  const filePath = join(getDownloadFolderPath(), filename);
932
930
  const fileContent = yield readFile(filePath, "utf8");
931
+ if (!(yield Validate.Import_MangaXML(fileContent))) {
932
+ console.error(`\nInvalid XML file.`);
933
+ return;
934
+ }
933
935
  const parser = new XMLParser();
934
936
  if (fileContent) {
935
937
  const XMLObject = parser.parse(fileContent);
@@ -1000,7 +1002,7 @@ class MyAnimeList {
1000
1002
  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) {
1001
1003
  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;
1002
1004
  const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
1003
- var _a, _b, _c, _d, _e;
1005
+ var _a, _b, _c, _d, _e, _f;
1004
1006
  return ({
1005
1007
  id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
1006
1008
  malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
@@ -1010,13 +1012,10 @@ class MyAnimeList {
1010
1012
  progress: entry.progress,
1011
1013
  status: entry === null || entry === void 0 ? void 0 : entry.status,
1012
1014
  hiddenFromStatusLists: false,
1015
+ format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
1013
1016
  });
1014
1017
  }));
1015
- const xmlContent = createAnimeListXML(mediaWithProgress);
1016
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
1017
- yield writeFile(path, yield xmlContent, "utf8");
1018
- console.log(`Generated XML for MyAnimeList.`);
1019
- open(getDownloadFolderPath());
1018
+ yield saveJSONasXML(mediaWithProgress, 0);
1020
1019
  }
1021
1020
  else {
1022
1021
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -1041,24 +1040,17 @@ class MyAnimeList {
1041
1040
  });
1042
1041
  if (mangaList && ((_b = (_a = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists.length) > 0) {
1043
1042
  const lists = (_d = (_c = mangaList === null || mangaList === void 0 ? void 0 : mangaList.data) === null || _c === void 0 ? void 0 : _c.MediaListCollection) === null || _d === void 0 ? void 0 : _d.lists;
1044
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
1045
- var _a, _b, _c;
1046
- return ({
1047
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
1048
- malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
1049
- title: (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
1050
- private: entry.private,
1051
- chapters: entry.media.chapters,
1052
- progress: entry.progress,
1053
- status: entry === null || entry === void 0 ? void 0 : entry.status,
1054
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
1055
- });
1056
- }));
1057
- const XMLContent = createMangaListXML(mediaWithProgress);
1058
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
1059
- yield writeFile(path, yield XMLContent, "utf8");
1060
- console.log(`Generated XML for MyAnimeList.`);
1061
- open(getDownloadFolderPath());
1043
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
1044
+ id: entry.media.id,
1045
+ malId: entry.media.idMal,
1046
+ title: entry.media.title,
1047
+ private: entry.private,
1048
+ chapters: entry.media.chapters,
1049
+ progress: entry.progress,
1050
+ status: entry.status,
1051
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
1052
+ })));
1053
+ yield saveJSONasXML(mediaWithProgress, 1);
1062
1054
  }
1063
1055
  else {
1064
1056
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -1070,4 +1062,99 @@ class MyAnimeList {
1070
1062
  });
1071
1063
  }
1072
1064
  }
1073
- export { AniList, MyAnimeList };
1065
+ class AniDB {
1066
+ static importAnime() {
1067
+ return __awaiter(this, void 0, void 0, function* () {
1068
+ var _a, _b;
1069
+ try {
1070
+ const filename = yield selectFile(".json");
1071
+ if (!filename) {
1072
+ return;
1073
+ }
1074
+ const filePath = join(getDownloadFolderPath(), filename);
1075
+ const fileContent = yield readFile(filePath, "utf8");
1076
+ const js0n_repaired = jsonrepair(fileContent);
1077
+ if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
1078
+ console.error(`\nInvalid JSON Large file.`);
1079
+ return;
1080
+ }
1081
+ if (js0n_repaired) {
1082
+ const obj3ct = yield JSON.parse(js0n_repaired);
1083
+ const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
1084
+ if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
1085
+ let count = 0;
1086
+ let iteration = 0;
1087
+ let missed = [];
1088
+ for (const anime of animeList) {
1089
+ iteration++;
1090
+ const anidbId = anime.id;
1091
+ const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
1092
+ const status = anime.status;
1093
+ // const type = anime.type
1094
+ const totalEpisodes = anime.totalEpisodes;
1095
+ const ownEpisodes = anime.ownEpisodes;
1096
+ const romanjiName = anime.romanjiName;
1097
+ const englishName = anime.englishName;
1098
+ function getStatus(anidbStatus, episodesSeen) {
1099
+ if (anidbStatus === "complete") {
1100
+ return AniListMediaStatus.COMPLETED;
1101
+ }
1102
+ else if (anidbStatus === "incomplete" &&
1103
+ Number(episodesSeen) > 0) {
1104
+ return AniListMediaStatus.CURRENT;
1105
+ }
1106
+ else {
1107
+ return AniListMediaStatus.PLANNING;
1108
+ }
1109
+ }
1110
+ let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
1111
+ if (anilistId) {
1112
+ try {
1113
+ const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
1114
+ mediaId: anilistId,
1115
+ progress: ownEpisodes - 2,
1116
+ status: getStatus(status, ownEpisodes),
1117
+ hiddenFromStatusLists: false,
1118
+ private: false,
1119
+ });
1120
+ 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;
1121
+ if (entryId) {
1122
+ count++;
1123
+ responsiveOutput(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1124
+ }
1125
+ // Rate limit each API call to avoid server overload
1126
+ // await new Promise((resolve) => setTimeout(resolve, 1100))
1127
+ }
1128
+ catch (error) {
1129
+ console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
1130
+ }
1131
+ }
1132
+ else {
1133
+ missed.push({
1134
+ anidbId: anidbId,
1135
+ englishTitle: englishName,
1136
+ romajiTitle: romanjiName,
1137
+ });
1138
+ }
1139
+ }
1140
+ responsiveOutput(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
1141
+ if (missed.length > 0) {
1142
+ responsiveOutput(`Exporting missed entries to JSON file, Please add them manually.`);
1143
+ yield saveJSONasJSON(missed, "anidb-missed");
1144
+ }
1145
+ }
1146
+ else {
1147
+ console.log(`\nNo anime list found in the file.`);
1148
+ }
1149
+ }
1150
+ else {
1151
+ console.log(`\nNo content found in the file or unable to read.`);
1152
+ }
1153
+ }
1154
+ catch (error) {
1155
+ console.error(`\nError in AniDB import process: ${error.message}`);
1156
+ }
1157
+ });
1158
+ }
1159
+ }
1160
+ export { AniDB, AniList, MyAnimeList };