@irfanshadikrishad/anilist 1.2.0-forbidden.1 → 1.2.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.
@@ -10,22 +10,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { XMLParser } from "fast-xml-parser";
11
11
  import { readFile, writeFile } from "fs/promises";
12
12
  import inquirer from "inquirer";
13
- import fetch from "node-fetch";
13
+ import { jsonrepair } from "jsonrepair";
14
+ import open from "open";
14
15
  import { join } from "path";
15
16
  import { Auth } from "./auth.js";
16
17
  import { fetcher } from "./fetcher.js";
17
18
  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";
19
+ import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.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, createAnimeListXML, createMangaListXML, formatDateObject, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, 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,78 @@ 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, _e;
156
+ return ({
157
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
158
+ title: exportType === 1
159
+ ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
160
+ : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
161
+ episodes: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.episodes,
162
+ siteUrl: (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.siteUrl,
163
+ progress: entry.progress,
164
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
165
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
166
+ });
167
+ }));
168
+ switch (exportType) {
169
+ case 1:
170
+ yield saveJSONasCSV(mediaWithProgress, "anime");
171
+ break;
172
+ case 2:
173
+ yield saveJSONasJSON(mediaWithProgress, "anime");
174
+ break;
175
+ case 3:
176
+ yield MyAnimeList.exportAnime();
177
+ break;
178
+ default:
179
+ console.log(`\nInvalid export type. ${exportType}`);
180
+ break;
181
+ }
182
+ }
183
+ else {
184
+ console.error(`\nNo anime(s) found in your lists.`);
185
+ }
186
+ });
187
+ }
188
+ static exportManga() {
189
+ return __awaiter(this, void 0, void 0, function* () {
190
+ var _a, _b;
191
+ if (!(yield Auth.isLoggedIn())) {
192
+ console.error(`\nPlease login to use this feature.`);
193
+ return;
194
+ }
195
+ const mangaLists = yield fetcher(currentUserMangaList, {
196
+ id: yield Auth.MyUserId(),
197
+ });
198
+ if (!(mangaLists === null || mangaLists === void 0 ? void 0 : mangaLists.data)) {
199
+ console.error(`\nCould not get manga list.`);
200
+ return;
201
+ }
202
+ 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) || [];
203
+ if (lists.length > 0) {
117
204
  const { exportType } = yield inquirer.prompt([
118
205
  {
119
206
  type: "list",
@@ -127,141 +214,55 @@ class AniList {
127
214
  pageSize: 10,
128
215
  },
129
216
  ]);
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.`);
217
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
218
+ var _a, _b, _c;
219
+ return ({
220
+ id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
221
+ title: exportType === 1
222
+ ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
223
+ : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
224
+ private: entry.private,
225
+ chapters: entry.media.chapters,
226
+ progress: entry.progress,
227
+ status: entry === null || entry === void 0 ? void 0 : entry.status,
228
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
229
+ });
230
+ }));
231
+ switch (exportType) {
232
+ case 1:
233
+ yield saveJSONasCSV(mediaWithProgress, "manga");
234
+ break;
235
+ case 2:
236
+ yield saveJSONasJSON(mediaWithProgress, "manga");
237
+ break;
238
+ case 3:
239
+ yield MyAnimeList.exportManga();
240
+ break;
241
+ default:
242
+ console.log(`\nInvalid export type. ${exportType}`);
243
+ break;
231
244
  }
232
245
  }
233
246
  else {
234
- console.error(`\nPlease login to use this feature.`);
247
+ console.log(`\nList seems to be empty.`);
235
248
  }
236
249
  });
237
250
  }
238
251
  static MyAnime() {
239
252
  return __awaiter(this, void 0, void 0, function* () {
240
- var _a, _b, _c;
253
+ var _a, _b, _c, _d, _e;
241
254
  try {
242
255
  if (!(yield Auth.isLoggedIn())) {
243
256
  return console.error(`\nPlease log in first to access your lists.`);
244
257
  }
245
- const userId = yield Auth.MyUserId();
246
- if (!userId) {
258
+ if (!(yield Auth.MyUserId())) {
247
259
  return console.log(`\nFailed getting current user Id.`);
248
260
  }
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}`);
261
+ const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
262
+ if (data === null || data === void 0 ? void 0 : data.errors) {
263
+ 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
264
  }
264
- const lists = (_b = data === null || data === void 0 ? void 0 : data.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
265
+ 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
266
  if (!lists || lists.length === 0) {
266
267
  return console.log(`\nYou seem to have no anime(s) in your lists.`);
267
268
  }
@@ -304,11 +305,12 @@ class AniList {
304
305
  ],
305
306
  },
306
307
  ]);
307
- const query = addAnimeToListMutation;
308
- const variables = { mediaId: selectedAnime, status: selectedListType };
309
- const saveResponse = yield fetcher(query, variables);
308
+ const saveResponse = yield fetcher(addAnimeToListMutation, {
309
+ mediaId: selectedAnime,
310
+ status: selectedListType,
311
+ });
310
312
  if (saveResponse) {
311
- const savedEntry = (_c = saveResponse.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
313
+ const savedEntry = (_e = saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
312
314
  console.log(`\nEntry ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.id}. Saved as ${savedEntry === null || savedEntry === void 0 ? void 0 : savedEntry.status}.`);
313
315
  }
314
316
  else {
@@ -322,7 +324,7 @@ class AniList {
322
324
  }
323
325
  static MyManga() {
324
326
  return __awaiter(this, void 0, void 0, function* () {
325
- var _a, _b, _c, _d, _e;
327
+ var _a, _b, _c, _d, _e, _f, _g;
326
328
  try {
327
329
  if (!(yield Auth.isLoggedIn())) {
328
330
  return console.error(`\nPlease log in first to access your lists.`);
@@ -331,23 +333,11 @@ class AniList {
331
333
  if (!userId) {
332
334
  return console.error(`\nFailed to get the current user ID.`);
333
335
  }
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"}`);
336
+ const response = yield fetcher(currentUserMangaList, { id: userId });
337
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
338
+ 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
339
  }
350
- const lists = (_b = data === null || data === void 0 ? void 0 : data.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
340
+ 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
341
  if (!lists || lists.length === 0) {
352
342
  return console.log("\nYou don't seem to have any manga in your lists.");
353
343
  }
@@ -393,24 +383,16 @@ class AniList {
393
383
  ],
394
384
  },
395
385
  ]);
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
- }),
386
+ const saveResponse = yield fetcher(addMangaToListMutation, {
387
+ mediaId: selectedManga,
388
+ status: selectedListType,
406
389
  });
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;
390
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
409
391
  if (saved) {
410
392
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
411
393
  }
412
394
  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"}`);
395
+ 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
396
  }
415
397
  }
416
398
  catch (error) {
@@ -420,27 +402,17 @@ class AniList {
420
402
  }
421
403
  static getTrendingAnime(count) {
422
404
  return __awaiter(this, void 0, void 0, function* () {
423
- var _a, _b, _c, _d, _e;
405
+ var _a, _b, _c, _d, _e, _f, _g;
424
406
  try {
425
407
  let page = 1;
426
408
  let allTrending = [];
427
409
  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"}`);
410
+ const response = yield fetcher(trendingQuery, { page, perPage: count });
411
+ if (response === null || response === void 0 ? void 0 : response.errors) {
412
+ 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
413
  return;
442
414
  }
443
- const media = (_b = data === null || data === void 0 ? void 0 : data.Page) === null || _b === void 0 ? void 0 : _b.media;
415
+ 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
416
  if (!media || media.length === 0) {
445
417
  console.log(`\nNo more trending anime available.`);
446
418
  break;
@@ -448,7 +420,7 @@ class AniList {
448
420
  allTrending = [...allTrending, ...media];
449
421
  const choices = allTrending.map((anime, idx) => ({
450
422
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
451
- value: anime === null || anime === void 0 ? void 0 : anime.id,
423
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
452
424
  }));
453
425
  choices.push({ name: "See more", value: "see_more" });
454
426
  const { selectedAnime } = yield inquirer.prompt([
@@ -485,12 +457,12 @@ class AniList {
485
457
  }
486
458
  const variables = { mediaId: selectedAnime, status: selectedListType };
487
459
  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;
460
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
489
461
  if (saved) {
490
462
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
491
463
  }
492
464
  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"}`);
465
+ 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
466
  }
495
467
  break;
496
468
  }
@@ -503,27 +475,17 @@ class AniList {
503
475
  }
504
476
  static getPopularAnime(count) {
505
477
  return __awaiter(this, void 0, void 0, function* () {
506
- var _a, _b, _c, _d, _e;
478
+ var _a, _b, _c, _d, _e, _f, _g;
507
479
  try {
508
480
  let page = 1;
509
481
  let allMedia = [];
510
482
  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"}`);
483
+ const response = yield fetcher(popularQuery, { page, perPage: count });
484
+ if (!(response === null || response === void 0 ? void 0 : response.data)) {
485
+ 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
486
  return;
525
487
  }
526
- const newMedia = (_b = data === null || data === void 0 ? void 0 : data.Page) === null || _b === void 0 ? void 0 : _b.media;
488
+ 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
489
  if (!newMedia || newMedia.length === 0) {
528
490
  console.log(`\nNo more popular anime available.`);
529
491
  break;
@@ -531,7 +493,7 @@ class AniList {
531
493
  allMedia = [...allMedia, ...newMedia];
532
494
  const choices = allMedia.map((anime, idx) => ({
533
495
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
534
- value: anime === null || anime === void 0 ? void 0 : anime.id,
496
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
535
497
  }));
536
498
  choices.push({ name: "See more", value: "see_more" });
537
499
  const { selectedAnime } = yield inquirer.prompt([
@@ -567,12 +529,12 @@ class AniList {
567
529
  }
568
530
  const variables = { mediaId: selectedAnime, status: selectedListType };
569
531
  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;
532
+ const saved = (_e = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _e === void 0 ? void 0 : _e.SaveMediaListEntry;
571
533
  if (saved) {
572
534
  console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
573
535
  }
574
536
  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"}`);
537
+ 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
538
  }
577
539
  break;
578
540
  }
@@ -609,7 +571,7 @@ class AniList {
609
571
  allUpcoming = [...allUpcoming, ...newUpcoming];
610
572
  const choices = allUpcoming.map((anime, idx) => ({
611
573
  name: `[${idx + 1}] ${getTitle(anime === null || anime === void 0 ? void 0 : anime.title)}`,
612
- value: anime === null || anime === void 0 ? void 0 : anime.id,
574
+ value: String(anime === null || anime === void 0 ? void 0 : anime.id),
613
575
  }));
614
576
  choices.push({ name: "See more", value: "see_more" });
615
577
  const { selectedAnime } = yield inquirer.prompt([
@@ -663,22 +625,11 @@ class AniList {
663
625
  }
664
626
  static getUserByUsername(username) {
665
627
  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;
628
+ 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
629
  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"}`);
630
+ const response = yield fetcher(userQuery, { username });
631
+ if (!((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.User)) {
632
+ 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
633
  }
683
634
  const user = response.data.User;
684
635
  const userActivityResponse = yield fetcher(userActivityQuery, {
@@ -687,6 +638,15 @@ class AniList {
687
638
  perPage: 10,
688
639
  });
689
640
  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 : [];
641
+ // Get follower/following information
642
+ const req_followers = yield fetcher(userFollowersQuery, {
643
+ userId: user === null || user === void 0 ? void 0 : user.id,
644
+ });
645
+ const req_following = yield fetcher(userFollowingQuery, {
646
+ userId: user === null || user === void 0 ? void 0 : user.id,
647
+ });
648
+ 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;
649
+ 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
650
  console.log(`\nID:\t\t${user.id}`);
691
651
  console.log(`Name:\t\t${user.name}`);
692
652
  console.log(`Site URL:\t${user.siteUrl}`);
@@ -697,14 +657,16 @@ class AniList {
697
657
  console.log(`Blocked:\t${user.isBlocked}`);
698
658
  console.log(`Follower:\t${user.isFollower}`);
699
659
  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}`);
660
+ console.log(`Profile Color:\t${(_o = user.options) === null || _o === void 0 ? void 0 : _o.profileColor}`);
661
+ 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"}`);
662
+ console.log(`\nFollowers:\t${followersCount}`);
663
+ console.log(`Following:\t${followingCount}`);
664
+ 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}`);
665
+ 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
666
  if (activities.length > 0) {
705
667
  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)}`);
668
+ activities.forEach(({ status, progress, media, createdAt }) => {
669
+ console.log(`${timestampToTimeAgo(createdAt)}\t${status} ${progress ? `${progress} of ` : ""}${getTitle(media === null || media === void 0 ? void 0 : media.title)}`);
708
670
  });
709
671
  }
710
672
  else {
@@ -719,9 +681,9 @@ class AniList {
719
681
  static getAnimeDetailsByID(anilistID) {
720
682
  return __awaiter(this, void 0, void 0, function* () {
721
683
  var _a;
722
- const query = animeDetailsQuery;
723
- const variables = { id: anilistID };
724
- const details = yield fetcher(query, variables);
684
+ const details = yield fetcher(animeDetailsQuery, {
685
+ id: anilistID,
686
+ });
725
687
  if ((_a = details === null || details === void 0 ? void 0 : details.data) === null || _a === void 0 ? void 0 : _a.Media) {
726
688
  const { id, title, description, duration, startDate, endDate, countryOfOrigin, isAdult, status, season, format, genres, siteUrl, } = details.data.Media;
727
689
  console.log(`\nID: ${id}`);
@@ -743,9 +705,11 @@ class AniList {
743
705
  static searchAnime(search, count) {
744
706
  return __awaiter(this, void 0, void 0, function* () {
745
707
  var _a, _b, _c;
746
- const query = animeSearchQuery;
747
- const variables = { search, page: 1, perPage: count };
748
- const searchResults = yield fetcher(query, variables);
708
+ const searchResults = yield fetcher(animeSearchQuery, {
709
+ search,
710
+ page: 1,
711
+ perPage: count,
712
+ });
749
713
  if (searchResults) {
750
714
  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
715
  if (results.length > 0) {
@@ -777,12 +741,10 @@ class AniList {
777
741
  ]);
778
742
  // Save selected anime to chosen list type
779
743
  if (yield Auth.isLoggedIn()) {
780
- const saveQuery = addAnimeToListMutation;
781
- const saveVariables = {
744
+ const response = yield fetcher(addAnimeToListMutation, {
782
745
  mediaId: selectedAnime,
783
746
  status: selectedListType,
784
- };
785
- const response = yield fetcher(saveQuery, saveVariables);
747
+ });
786
748
  if (response) {
787
749
  const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
788
750
  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 +766,11 @@ class AniList {
804
766
  static searchManga(search, count) {
805
767
  return __awaiter(this, void 0, void 0, function* () {
806
768
  var _a, _b, _c;
807
- const query = mangaSearchQuery;
808
- const variables = { search, page: 1, perPage: count };
809
- const mangaSearchResult = yield fetcher(query, variables);
769
+ const mangaSearchResult = yield fetcher(mangaSearchQuery, {
770
+ search,
771
+ page: 1,
772
+ perPage: count,
773
+ });
810
774
  if (mangaSearchResult) {
811
775
  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
776
  // List of manga search results
@@ -839,9 +803,10 @@ class AniList {
839
803
  ]);
840
804
  // If logged in save to the list
841
805
  if (yield Auth.isLoggedIn()) {
842
- const mutation = addMangaToListMutation;
843
- const variables = { mediaId: selectedMangaId, status: selectedListType };
844
- const response = yield fetcher(mutation, variables);
806
+ const response = yield fetcher(addMangaToListMutation, {
807
+ mediaId: selectedMangaId,
808
+ status: selectedListType,
809
+ });
845
810
  if (response) {
846
811
  const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
847
812
  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 +828,15 @@ class MyAnimeList {
863
828
  var _a, _b, _c, _d, _e;
864
829
  try {
865
830
  const filename = yield selectFile(".xml");
831
+ if (!filename) {
832
+ return;
833
+ }
866
834
  const filePath = join(getDownloadFolderPath(), filename);
867
835
  const fileContent = yield readFile(filePath, "utf8");
836
+ if (!(yield Validate.Import_AnimeXML(fileContent))) {
837
+ console.error(`\nInvalid XML file.`);
838
+ return;
839
+ }
868
840
  const parser = new XMLParser();
869
841
  if (fileContent) {
870
842
  const XMLObject = parser.parse(fileContent);
@@ -928,8 +900,15 @@ class MyAnimeList {
928
900
  var _a, _b, _c, _d, _e;
929
901
  try {
930
902
  const filename = yield selectFile(".xml");
903
+ if (!filename) {
904
+ return;
905
+ }
931
906
  const filePath = join(getDownloadFolderPath(), filename);
932
907
  const fileContent = yield readFile(filePath, "utf8");
908
+ if (!(yield Validate.Import_MangaXML(fileContent))) {
909
+ console.error(`\nInvalid XML file.`);
910
+ return;
911
+ }
933
912
  const parser = new XMLParser();
934
913
  if (fileContent) {
935
914
  const XMLObject = parser.parse(fileContent);
@@ -1041,19 +1020,16 @@ class MyAnimeList {
1041
1020
  });
1042
1021
  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
1022
  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
- }));
1023
+ const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => ({
1024
+ id: entry.media.id,
1025
+ malId: entry.media.idMal,
1026
+ title: entry.media.title,
1027
+ private: entry.private,
1028
+ chapters: entry.media.chapters,
1029
+ progress: entry.progress,
1030
+ status: entry.status,
1031
+ hiddenFromStatusLists: entry.hiddenFromStatusLists,
1032
+ })));
1057
1033
  const XMLContent = createMangaListXML(mediaWithProgress);
1058
1034
  const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
1059
1035
  yield writeFile(path, yield XMLContent, "utf8");
@@ -1070,4 +1046,99 @@ class MyAnimeList {
1070
1046
  });
1071
1047
  }
1072
1048
  }
1073
- export { AniList, MyAnimeList };
1049
+ class AniDB {
1050
+ static importAnime() {
1051
+ return __awaiter(this, void 0, void 0, function* () {
1052
+ var _a, _b;
1053
+ try {
1054
+ const filename = yield selectFile(".json");
1055
+ if (!filename) {
1056
+ return;
1057
+ }
1058
+ const filePath = join(getDownloadFolderPath(), filename);
1059
+ const fileContent = yield readFile(filePath, "utf8");
1060
+ const js0n_repaired = jsonrepair(fileContent);
1061
+ if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
1062
+ console.error(`\nInvalid JSON Large file.`);
1063
+ return;
1064
+ }
1065
+ if (js0n_repaired) {
1066
+ const obj3ct = yield JSON.parse(js0n_repaired);
1067
+ const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
1068
+ if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
1069
+ let count = 0;
1070
+ let iteration = 0;
1071
+ let missed = [];
1072
+ for (const anime of animeList) {
1073
+ iteration++;
1074
+ const anidbId = anime.id;
1075
+ const released = anime.broadcastDate; // DD-MM-YYYY (eg: "23.07.2016")
1076
+ const status = anime.status;
1077
+ // const type = anime.type
1078
+ const totalEpisodes = anime.totalEpisodes;
1079
+ const ownEpisodes = anime.ownEpisodes;
1080
+ const romanjiName = anime.romanjiName;
1081
+ const englishName = anime.englishName;
1082
+ function getStatus(anidbStatus, episodesSeen) {
1083
+ if (anidbStatus === "complete") {
1084
+ return AniListMediaStatus.COMPLETED;
1085
+ }
1086
+ else if (anidbStatus === "incomplete" &&
1087
+ Number(episodesSeen) > 0) {
1088
+ return AniListMediaStatus.CURRENT;
1089
+ }
1090
+ else {
1091
+ return AniListMediaStatus.PLANNING;
1092
+ }
1093
+ }
1094
+ let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split(".")[2]), englishName);
1095
+ if (anilistId) {
1096
+ try {
1097
+ const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
1098
+ mediaId: anilistId,
1099
+ progress: ownEpisodes - 2,
1100
+ status: getStatus(status, ownEpisodes),
1101
+ hiddenFromStatusLists: false,
1102
+ private: false,
1103
+ });
1104
+ 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;
1105
+ if (entryId) {
1106
+ count++;
1107
+ console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1108
+ }
1109
+ // Rate limit each API call to avoid server overload
1110
+ // await new Promise((resolve) => setTimeout(resolve, 1100))
1111
+ }
1112
+ catch (error) {
1113
+ console.error(`Error processing AniDB ID ${anidbId}: ${error.message}`);
1114
+ }
1115
+ }
1116
+ else {
1117
+ missed.push({
1118
+ anidbId: anidbId,
1119
+ englishTitle: englishName,
1120
+ romajiTitle: romanjiName,
1121
+ });
1122
+ }
1123
+ }
1124
+ console.log(`\nAccuracy: ${(((animeList.length - missed.length) / animeList.length) * 100).toFixed(2)}%\tTotal Processed: ${iteration}\tMissed: ${missed.length}`);
1125
+ if (missed.length > 0) {
1126
+ console.log(`Exporting missed entries to JSON file, Please add them manually.`);
1127
+ yield saveJSONasJSON(missed, "anidb-missed");
1128
+ }
1129
+ }
1130
+ else {
1131
+ console.log(`\nNo anime list found in the file.`);
1132
+ }
1133
+ }
1134
+ else {
1135
+ console.log(`\nNo content found in the file or unable to read.`);
1136
+ }
1137
+ }
1138
+ catch (error) {
1139
+ console.error(`\nError in AniDB import process: ${error.message}`);
1140
+ }
1141
+ });
1142
+ }
1143
+ }
1144
+ export { AniDB, AniList, MyAnimeList };