@irfanshadikrishad/anilist 1.0.0-forbidden.2 → 1.0.0-forbidden.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,25 +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
13
  import { jsonrepair } from "jsonrepair";
14
- import open from "open";
15
14
  import { join } from "path";
16
15
  import { Auth } from "./auth.js";
17
16
  import { fetcher } from "./fetcher.js";
18
17
  import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from "./mutations.js";
19
18
  import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from "./queries.js";
20
19
  import { AniListMediaStatus, } from "./types.js";
21
- import { anidbToanilistMapper, 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, timestampToTimeAgo, } from "./workers.js";
22
22
  class AniList {
23
23
  static importAnime() {
24
24
  return __awaiter(this, void 0, void 0, function* () {
25
25
  try {
26
26
  const filename = yield selectFile(".json");
27
+ if (!filename) {
28
+ return;
29
+ }
27
30
  const filePath = join(getDownloadFolderPath(), filename);
28
31
  const fileContent = yield readFile(filePath, "utf8");
29
32
  const importedData = JSON.parse(fileContent);
33
+ if (!Validate.Import_JSON(importedData)) {
34
+ console.error(`\nInvalid JSON file.`);
35
+ return;
36
+ }
30
37
  let count = 0;
31
38
  const batchSize = 1; // Number of requests in each batch
32
39
  const delay = 1100; // delay to avoid rate-limiting
@@ -70,9 +77,16 @@ class AniList {
70
77
  return __awaiter(this, void 0, void 0, function* () {
71
78
  try {
72
79
  const filename = yield selectFile(".json");
80
+ if (!filename) {
81
+ return;
82
+ }
73
83
  const filePath = join(getDownloadFolderPath(), filename);
74
84
  const fileContent = yield readFile(filePath, "utf8");
75
85
  const importedData = JSON.parse(fileContent);
86
+ if (!Validate.Import_JSON(importedData)) {
87
+ console.error(`\nInvalid JSON file.`);
88
+ return;
89
+ }
76
90
  let count = 0;
77
91
  const batchSize = 1; // Adjust batch size as per rate-limit constraints
78
92
  const delay = 1100; // 2 seconds delay to avoid rate-limit
@@ -114,7 +128,76 @@ class AniList {
114
128
  static exportAnime() {
115
129
  return __awaiter(this, void 0, void 0, function* () {
116
130
  var _a, _b, _c;
117
- 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) {
118
201
  const { exportType } = yield inquirer.prompt([
119
202
  {
120
203
  type: "list",
@@ -123,116 +206,40 @@ class AniList {
123
206
  choices: [
124
207
  { name: "CSV", value: 1 },
125
208
  { name: "JSON", value: 2 },
126
- { name: "XML (MyAnimeList/AniDB)", value: 3 },
209
+ { name: "XML (MyAnimeList)", value: 3 },
127
210
  ],
128
211
  pageSize: 10,
129
212
  },
130
213
  ]);
131
- const animeList = yield fetcher(currentUserAnimeList, {
132
- id: yield Auth.MyUserId(),
133
- });
134
- if (animeList) {
135
- 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 : [];
136
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
137
- var _a, _b, _c, _d, _e;
138
- return ({
139
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
140
- title: exportType === 1
141
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
142
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
143
- episodes: (_d = entry === null || entry === void 0 ? void 0 : entry.media) === null || _d === void 0 ? void 0 : _d.episodes,
144
- siteUrl: (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.siteUrl,
145
- progress: entry.progress,
146
- status: entry === null || entry === void 0 ? void 0 : entry.status,
147
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
148
- });
149
- }));
150
- switch (exportType) {
151
- case 1:
152
- yield saveJSONasCSV(mediaWithProgress, "anime");
153
- break;
154
- case 2:
155
- yield saveJSONasJSON(mediaWithProgress, "anime");
156
- break;
157
- case 3:
158
- yield MyAnimeList.exportAnime();
159
- break;
160
- default:
161
- console.log(`\nInvalid export type. ${exportType}`);
162
- break;
163
- }
164
- }
165
- else {
166
- console.error(`\nNo anime(s) found in your lists.`);
167
- }
168
- }
169
- else {
170
- console.error(`\nMust login to use this feature.`);
171
- }
172
- });
173
- }
174
- static exportManga() {
175
- return __awaiter(this, void 0, void 0, function* () {
176
- var _a, _b;
177
- if (yield Auth.isLoggedIn()) {
178
- const mangaLists = yield fetcher(currentUserMangaList, {
179
- id: yield Auth.MyUserId(),
180
- });
181
- if (mangaLists) {
182
- 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) || [];
183
- if (lists.length > 0) {
184
- const { exportType } = yield inquirer.prompt([
185
- {
186
- type: "list",
187
- name: "exportType",
188
- message: "Choose export type:",
189
- choices: [
190
- { name: "CSV", value: 1 },
191
- { name: "JSON", value: 2 },
192
- { name: "XML (MyAnimeList)", value: 3 },
193
- ],
194
- pageSize: 10,
195
- },
196
- ]);
197
- const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
198
- var _a, _b, _c;
199
- return ({
200
- id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
201
- title: exportType === 1
202
- ? getTitle((_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.title)
203
- : (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title,
204
- private: entry.private,
205
- chapters: entry.media.chapters,
206
- progress: entry.progress,
207
- status: entry === null || entry === void 0 ? void 0 : entry.status,
208
- hiddenFromStatusLists: entry.hiddenFromStatusLists,
209
- });
210
- }));
211
- switch (exportType) {
212
- case 1:
213
- yield saveJSONasCSV(mediaWithProgress, "manga");
214
- break;
215
- case 2:
216
- yield saveJSONasJSON(mediaWithProgress, "manga");
217
- break;
218
- case 3:
219
- yield MyAnimeList.exportManga();
220
- break;
221
- default:
222
- console.log(`\nInvalid export type. ${exportType}`);
223
- break;
224
- }
225
- }
226
- else {
227
- console.log(`\nList seems to be empty.`);
228
- }
229
- }
230
- else {
231
- 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;
232
239
  }
233
240
  }
234
241
  else {
235
- console.error(`\nPlease login to use this feature.`);
242
+ console.log(`\nList seems to be empty.`);
236
243
  }
237
244
  });
238
245
  }
@@ -243,11 +250,10 @@ class AniList {
243
250
  if (!(yield Auth.isLoggedIn())) {
244
251
  return console.error(`\nPlease log in first to access your lists.`);
245
252
  }
246
- const userId = yield Auth.MyUserId();
247
- if (!userId) {
253
+ if (!(yield Auth.MyUserId())) {
248
254
  return console.log(`\nFailed getting current user Id.`);
249
255
  }
250
- const data = yield fetcher(currentUserAnimeList, { id: userId });
256
+ const data = yield fetcher(currentUserAnimeList, { id: yield Auth.MyUserId() });
251
257
  if (data === null || data === void 0 ? void 0 : data.errors) {
252
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}`);
253
259
  }
@@ -817,8 +823,15 @@ class MyAnimeList {
817
823
  var _a, _b, _c, _d, _e;
818
824
  try {
819
825
  const filename = yield selectFile(".xml");
826
+ if (!filename) {
827
+ return;
828
+ }
820
829
  const filePath = join(getDownloadFolderPath(), filename);
821
830
  const fileContent = yield readFile(filePath, "utf8");
831
+ if (!(yield Validate.Import_AnimeXML(fileContent))) {
832
+ console.error(`\nInvalid XML file.`);
833
+ return;
834
+ }
822
835
  const parser = new XMLParser();
823
836
  if (fileContent) {
824
837
  const XMLObject = parser.parse(fileContent);
@@ -882,8 +895,15 @@ class MyAnimeList {
882
895
  var _a, _b, _c, _d, _e;
883
896
  try {
884
897
  const filename = yield selectFile(".xml");
898
+ if (!filename) {
899
+ return;
900
+ }
885
901
  const filePath = join(getDownloadFolderPath(), filename);
886
902
  const fileContent = yield readFile(filePath, "utf8");
903
+ if (!(yield Validate.Import_MangaXML(fileContent))) {
904
+ console.error(`\nInvalid XML file.`);
905
+ return;
906
+ }
887
907
  const parser = new XMLParser();
888
908
  if (fileContent) {
889
909
  const XMLObject = parser.parse(fileContent);
@@ -954,7 +974,7 @@ class MyAnimeList {
954
974
  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) {
955
975
  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;
956
976
  const mediaWithProgress = lists.flatMap((list) => list.entries.map((entry) => {
957
- var _a, _b, _c, _d, _e;
977
+ var _a, _b, _c, _d, _e, _f;
958
978
  return ({
959
979
  id: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
960
980
  malId: (_b = entry === null || entry === void 0 ? void 0 : entry.media) === null || _b === void 0 ? void 0 : _b.idMal,
@@ -964,13 +984,10 @@ class MyAnimeList {
964
984
  progress: entry.progress,
965
985
  status: entry === null || entry === void 0 ? void 0 : entry.status,
966
986
  hiddenFromStatusLists: false,
987
+ format: (_f = entry === null || entry === void 0 ? void 0 : entry.media) === null || _f === void 0 ? void 0 : _f.format,
967
988
  });
968
989
  }));
969
- const xmlContent = createAnimeListXML(mediaWithProgress);
970
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(anime)-${getFormattedDate()}.xml`);
971
- yield writeFile(path, yield xmlContent, "utf8");
972
- console.log(`Generated XML for MyAnimeList.`);
973
- open(getDownloadFolderPath());
990
+ yield saveJSONasXML(mediaWithProgress, 0);
974
991
  }
975
992
  else {
976
993
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -1005,11 +1022,7 @@ class MyAnimeList {
1005
1022
  status: entry.status,
1006
1023
  hiddenFromStatusLists: entry.hiddenFromStatusLists,
1007
1024
  })));
1008
- const XMLContent = createMangaListXML(mediaWithProgress);
1009
- const path = join(getDownloadFolderPath(), `${yield Auth.MyUserName()}@irfanshadikrishad-anilist-myanimelist(manga)-${getFormattedDate()}.xml`);
1010
- yield writeFile(path, yield XMLContent, "utf8");
1011
- console.log(`Generated XML for MyAnimeList.`);
1012
- open(getDownloadFolderPath());
1025
+ yield saveJSONasXML(mediaWithProgress, 1);
1013
1026
  }
1014
1027
  else {
1015
1028
  console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
@@ -1027,10 +1040,17 @@ class AniDB {
1027
1040
  var _a, _b;
1028
1041
  try {
1029
1042
  const filename = yield selectFile(".json");
1043
+ if (!filename) {
1044
+ return;
1045
+ }
1030
1046
  const filePath = join(getDownloadFolderPath(), filename);
1031
1047
  const fileContent = yield readFile(filePath, "utf8");
1032
1048
  const js0n_repaired = jsonrepair(fileContent);
1033
- if (fileContent) {
1049
+ if (!(yield Validate.Import_AniDBJSONLarge(js0n_repaired))) {
1050
+ console.error(`\nInvalid JSON Large file.`);
1051
+ return;
1052
+ }
1053
+ if (js0n_repaired) {
1034
1054
  const obj3ct = yield JSON.parse(js0n_repaired);
1035
1055
  const animeList = obj3ct === null || obj3ct === void 0 ? void 0 : obj3ct.anime;
1036
1056
  if ((animeList === null || animeList === void 0 ? void 0 : animeList.length) > 0) {
@@ -1072,7 +1092,7 @@ class AniDB {
1072
1092
  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;
1073
1093
  if (entryId) {
1074
1094
  count++;
1075
- console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}→${getStatus(status, ownEpisodes)}`);
1095
+ console.log(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1076
1096
  }
1077
1097
  // Rate limit each API call to avoid server overload
1078
1098
  // await new Promise((resolve) => setTimeout(resolve, 1100))
@@ -22,6 +22,7 @@ declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $ma
22
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
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
24
  declare const specificUserActivitiesQuery = "\nquery ($page: Int, $perPage: Int, $userId: Int) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total perPage currentPage lastPage hasNextPage }\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
- 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 }\n }\n}\n";
26
- declare const userFollowersQuery = "query ($userId: Int!) {\n Page {\n pageInfo { total perPage currentPage lastPage hasNextPage }\n followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }\n }\n}\n";
27
- export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
25
+ 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";
26
+ 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";
27
+ declare const toggleFollowMutation = "mutation ($userId: Int!) {\n ToggleFollow(userId: $userId) { id name isFollower isFollowing }\n}\n";
28
+ export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
@@ -159,18 +159,22 @@ query ($page: Int, $perPage: Int, $userId: Int) {
159
159
  }
160
160
  }
161
161
  `;
162
- const userFollowingQuery = `query ($userId: Int!, $page:Int) {
162
+ const userFollowingQuery = `query ($userId: Int!, $page: Int) {
163
163
  Page (page: $page) {
164
164
  pageInfo { total perPage currentPage lastPage hasNextPage }
165
- following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
165
+ following(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }
166
166
  }
167
167
  }
168
168
  `;
169
- const userFollowersQuery = `query ($userId: Int!) {
170
- Page {
169
+ const userFollowersQuery = `query ($userId: Int!, $page: Int) {
170
+ Page (page: $page) {
171
171
  pageInfo { total perPage currentPage lastPage hasNextPage }
172
- followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage }
172
+ followers(userId: $userId, sort: [USERNAME]) { id name avatar { large medium } bannerImage isFollowing isFollower }
173
173
  }
174
174
  }
175
175
  `;
176
- export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
176
+ const toggleFollowMutation = `mutation ($userId: Int!) {
177
+ ToggleFollow(userId: $userId) { id name isFollower isFollowing }
178
+ }
179
+ `;
180
+ export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, toggleFollowMutation, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };