@irfanshadikrishad/anilist 1.8.0 → 2.0.0-forbidden

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.
@@ -12,16 +12,14 @@ import { readFile } from 'fs/promises';
12
12
  import inquirer from 'inquirer';
13
13
  import { jsonrepair } from 'jsonrepair';
14
14
  import { join } from 'path';
15
- import Spinner from 'tiny-spinner';
16
15
  import { Auth } from './auth.js';
17
16
  import { fetcher } from './fetcher.js';
18
- import { addAnimeToListMutation, addMangaToListMutation, moveListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from './mutations.js';
17
+ import { addAnimeToListMutation, addMangaToListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, } from './mutations.js';
19
18
  import { animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, } from './queries.js';
20
19
  import { responsiveOutput } from './truncate.js';
21
20
  import { AniListMediaStatus, } from './types.js';
22
21
  import { Validate } from './validation.js';
23
22
  import { anidbToanilistMapper, formatDateObject, getDownloadFolderPath, getNextSeasonAndYear, getTitle, logUserDetails, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, selectFile, simpleDateFormat, timestampToTimeAgo, } from './workers.js';
24
- const spinner = new Spinner();
25
23
  class AniList {
26
24
  static importAnime() {
27
25
  return __awaiter(this, void 0, void 0, function* () {
@@ -55,7 +53,7 @@ class AniList {
55
53
  if (save) {
56
54
  const id = (_b = (_a = save === null || save === void 0 ? void 0 : save.data) === null || _a === void 0 ? void 0 : _a.SaveMediaListEntry) === null || _b === void 0 ? void 0 : _b.id;
57
55
  count++;
58
- console.log(`[${count}]\t${id}\t${anime === null || anime === void 0 ? void 0 : anime.id} ✔`);
56
+ console.log(`[${count}]\t${id}\t${anime === null || anime === void 0 ? void 0 : anime.id} ✅`);
59
57
  }
60
58
  else {
61
59
  console.error(`\nError saving ${anime === null || anime === void 0 ? void 0 : anime.id}`);
@@ -873,7 +871,7 @@ class MyAnimeList {
873
871
  const entryId = (_e = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _d === void 0 ? void 0 : _d.SaveMediaListEntry) === null || _e === void 0 ? void 0 : _e.id;
874
872
  if (entryId) {
875
873
  count++;
876
- console.log(`[${count}] ${entryId} ✔`);
874
+ console.log(`[${count}] ${entryId} ✅`);
877
875
  }
878
876
  }
879
877
  else {
@@ -943,7 +941,7 @@ class MyAnimeList {
943
941
  const entryId = (_e = (_d = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _d === void 0 ? void 0 : _d.SaveMediaListEntry) === null || _e === void 0 ? void 0 : _e.id;
944
942
  if (entryId) {
945
943
  count++;
946
- console.log(`[${count}] ${entryId} ✔`);
944
+ console.log(`[${count}] ${entryId} ✅`);
947
945
  }
948
946
  else {
949
947
  console.error(`Failed to save entry for ${malId}`);
@@ -1044,17 +1042,6 @@ class AniDB {
1044
1042
  static importAnime() {
1045
1043
  return __awaiter(this, void 0, void 0, function* () {
1046
1044
  var _a, _b;
1047
- function getStatus(anidbStatus, episodesSeen) {
1048
- if (anidbStatus === 'complete') {
1049
- return AniListMediaStatus.COMPLETED;
1050
- }
1051
- else if (anidbStatus === 'incomplete' && Number(episodesSeen) > 0) {
1052
- return AniListMediaStatus.CURRENT;
1053
- }
1054
- else {
1055
- return AniListMediaStatus.PLANNING;
1056
- }
1057
- }
1058
1045
  try {
1059
1046
  const filename = yield selectFile('.json');
1060
1047
  if (!filename) {
@@ -1084,7 +1071,19 @@ class AniDB {
1084
1071
  const ownEpisodes = anime.ownEpisodes;
1085
1072
  const romanjiName = anime.romanjiName;
1086
1073
  const englishName = anime.englishName;
1087
- const anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split('.')[2]), englishName);
1074
+ function getStatus(anidbStatus, episodesSeen) {
1075
+ if (anidbStatus === 'complete') {
1076
+ return AniListMediaStatus.COMPLETED;
1077
+ }
1078
+ else if (anidbStatus === 'incomplete' &&
1079
+ Number(episodesSeen) > 0) {
1080
+ return AniListMediaStatus.CURRENT;
1081
+ }
1082
+ else {
1083
+ return AniListMediaStatus.PLANNING;
1084
+ }
1085
+ }
1086
+ let anilistId = yield anidbToanilistMapper(romanjiName, Number(released.split('.')[2]), englishName);
1088
1087
  if (anilistId) {
1089
1088
  try {
1090
1089
  const saveResponse = yield fetcher(saveAnimeWithProgressMutation, {
@@ -1097,7 +1096,7 @@ class AniDB {
1097
1096
  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;
1098
1097
  if (entryId) {
1099
1098
  count++;
1100
- responsiveOutput(`[${count}]\t${entryId} ✔\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1099
+ responsiveOutput(`[${count}]\t${entryId} ✅\t${anidbId}\t${anilistId}\t(${ownEpisodes}/${totalEpisodes})\t${status}–>${getStatus(status, ownEpisodes)}`);
1101
1100
  }
1102
1101
  }
1103
1102
  catch (error) {
@@ -1132,125 +1131,4 @@ class AniDB {
1132
1131
  });
1133
1132
  }
1134
1133
  }
1135
- class MoveTo {
1136
- static AnimeList() {
1137
- return __awaiter(this, void 0, void 0, function* () {
1138
- var _a, _b, _c, _d, _e, _f, _g, _h;
1139
- try {
1140
- spinner.start(`Fetching your anime list...`);
1141
- const animeList = yield fetcher(currentUserAnimeList, {
1142
- id: yield Auth.MyUserId(),
1143
- });
1144
- 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) {
1145
- spinner.stop();
1146
- const list = (_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;
1147
- const { selectedList } = yield inquirer.prompt([
1148
- {
1149
- type: 'list',
1150
- name: 'selectedList',
1151
- message: 'Select a list to move:',
1152
- choices: list.map((list) => list.name),
1153
- },
1154
- ]);
1155
- const selectedEntries = list.find((list) => list.name === selectedList);
1156
- if (!selectedEntries || selectedEntries.entries.length === 0) {
1157
- return console.log('\nNo anime entries found in the selected list.');
1158
- }
1159
- const { toMoveList } = yield inquirer.prompt([
1160
- {
1161
- type: 'list',
1162
- name: 'toMoveList',
1163
- message: 'Select a list to move to:',
1164
- choices: list.map((list) => list.name),
1165
- },
1166
- ]);
1167
- const entries = selectedEntries.entries;
1168
- for (const entry of entries) {
1169
- const mediaId = (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.id;
1170
- const status = entry === null || entry === void 0 ? void 0 : entry.status;
1171
- // const progress = entry?.progress
1172
- // console.log(mediaId, status)
1173
- const response = yield fetcher(moveListMutation, {
1174
- mediaId,
1175
- status,
1176
- customList: toMoveList,
1177
- });
1178
- if (response === null || response === void 0 ? void 0 : response.data) {
1179
- const moved = (_f = response === null || response === void 0 ? void 0 : response.data) === null || _f === void 0 ? void 0 : _f.SaveMediaListEntry;
1180
- console.log(`✔ Entry ${moved === null || moved === void 0 ? void 0 : moved.id}. Moved from ${selectedList} to ${toMoveList}.`);
1181
- }
1182
- else {
1183
- console.error(`\nFailed to move the anime. ${((_h = (_g = response === null || response === void 0 ? void 0 : response.errors) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.message) || 'Unknown error'}`);
1184
- }
1185
- }
1186
- }
1187
- else {
1188
- console.log(`\nHey, ${yield Auth.MyUserName()}. Your anime list seems to be empty.`);
1189
- }
1190
- }
1191
- catch (error) {
1192
- console.error(`\nError from AnimeList. ${error.message}`);
1193
- }
1194
- });
1195
- }
1196
- static MangaList() {
1197
- return __awaiter(this, void 0, void 0, function* () {
1198
- var _a, _b, _c, _d, _e, _f, _g, _h;
1199
- try {
1200
- spinner.start(`Fetching your manga list...`);
1201
- const mangaList = yield fetcher(currentUserMangaList, {
1202
- id: yield Auth.MyUserId(),
1203
- });
1204
- if (((_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) {
1205
- spinner.stop();
1206
- const list = (_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;
1207
- const { selectedList } = yield inquirer.prompt([
1208
- {
1209
- type: 'list',
1210
- name: 'selectedList',
1211
- message: 'Select a list to move:',
1212
- choices: list.map((list) => list.name),
1213
- },
1214
- ]);
1215
- const selectedEntries = list.find((list) => list.name === selectedList);
1216
- if (!selectedEntries || selectedEntries.entries.length === 0) {
1217
- return console.log('\nNo manga entries found in the selected list.');
1218
- }
1219
- const { toMoveList } = yield inquirer.prompt([
1220
- {
1221
- type: 'list',
1222
- name: 'toMoveList',
1223
- message: 'Select a list to move to:',
1224
- choices: list.map((list) => list.name),
1225
- },
1226
- ]);
1227
- const entries = selectedEntries.entries;
1228
- for (const entry of entries) {
1229
- const mediaId = (_e = entry === null || entry === void 0 ? void 0 : entry.media) === null || _e === void 0 ? void 0 : _e.id;
1230
- const status = entry === null || entry === void 0 ? void 0 : entry.status;
1231
- // console.log(mediaId, status)
1232
- const response = yield fetcher(moveListMutation, {
1233
- mediaId,
1234
- status,
1235
- customList: toMoveList,
1236
- });
1237
- if (response === null || response === void 0 ? void 0 : response.data) {
1238
- const moved = (_f = response === null || response === void 0 ? void 0 : response.data) === null || _f === void 0 ? void 0 : _f.SaveMediaListEntry;
1239
- console.log(`✅ Entry ${moved === null || moved === void 0 ? void 0 : moved.id}. Moved from ${selectedList} to ${toMoveList}.`);
1240
- }
1241
- else {
1242
- console.error(`\nFailed to move the manga. ${((_h = (_g = response === null || response === void 0 ? void 0 : response.errors) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.message) || 'Unknown error'}`);
1243
- }
1244
- }
1245
- }
1246
- else {
1247
- console.log(`\nHey, ${yield Auth.MyUserName()}. Your manga list seems to be empty.`);
1248
- }
1249
- }
1250
- catch (error) {
1251
- console.error(`\nError from MangaList. ${error.message}`);
1252
- }
1253
- });
1254
- }
1255
- }
1256
- export { AniDB, AniList, MoveTo, MyAnimeList };
1134
+ export { AniDB, AniList, MyAnimeList };
@@ -4,8 +4,8 @@ declare const deleteActivityMutation = "\nmutation($id: Int!) { DeleteActivity(i
4
4
  declare const saveTextActivityMutation = "\nmutation SaveTextActivity($status: String!) { SaveTextActivity(text: $status) { id text userId createdAt } }\n";
5
5
  declare const saveAnimeWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean) {\n SaveMediaListEntry(mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists) {\n id progress hiddenFromStatusLists\n }\n}\n";
6
6
  declare const saveMangaWithProgressMutation = "\nmutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromStatusLists: Boolean, $private: Boolean) {\n SaveMediaListEntry( mediaId: $mediaId, progress: $progress, status: $status, hiddenFromStatusLists: $hiddenFromStatusLists, private: $private\n ) { id progress hiddenFromStatusLists private }\n}\n";
7
+ declare const likeActivityMutation = "\nmutation($activityId: Int!) {\n ToggleLike(id: $activityId, type: ACTIVITY) { id }\n}\n";
7
8
  declare const toggleFollowMutation = "mutation ($userId: Int!) { ToggleFollow(userId: $userId) { id name isFollower isFollowing } }";
8
9
  declare const deleteMediaEntryMutation = "mutation($id: Int!) { DeleteMediaListEntry(id: $id) { deleted } }";
9
10
  declare const deleteMangaEntryMutation = "mutation($id: Int) {\n DeleteMediaListEntry(id: $id) { deleted }\n}";
10
- declare const moveListMutation = "mutation ($mediaId: Int, $status: MediaListStatus, $customList: String) {\n SaveMediaListEntry(\n mediaId: $mediaId\n status: $status\n customLists: [$customList]\n hiddenFromStatusLists: true\n ) { id status hiddenFromStatusLists customLists media { title { romaji english native userPreferred } } }\n}";
11
- export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, deleteMangaEntryMutation, deleteMediaEntryMutation, moveListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, toggleFollowMutation, };
11
+ export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, deleteMangaEntryMutation, deleteMediaEntryMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, toggleFollowMutation, };
@@ -29,17 +29,14 @@ mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromSt
29
29
  ) { id progress hiddenFromStatusLists private }
30
30
  }
31
31
  `;
32
+ const likeActivityMutation = `
33
+ mutation($activityId: Int!) {
34
+ ToggleLike(id: $activityId, type: ACTIVITY) { id }
35
+ }
36
+ `;
32
37
  const toggleFollowMutation = `mutation ($userId: Int!) { ToggleFollow(userId: $userId) { id name isFollower isFollowing } }`;
33
38
  const deleteMediaEntryMutation = `mutation($id: Int!) { DeleteMediaListEntry(id: $id) { deleted } }`;
34
39
  const deleteMangaEntryMutation = `mutation($id: Int) {
35
40
  DeleteMediaListEntry(id: $id) { deleted }
36
41
  }`;
37
- const moveListMutation = `mutation ($mediaId: Int, $status: MediaListStatus, $customList: String) {
38
- SaveMediaListEntry(
39
- mediaId: $mediaId
40
- status: $status
41
- customLists: [$customList]
42
- hiddenFromStatusLists: true
43
- ) { id status hiddenFromStatusLists customLists media { title { romaji english native userPreferred } } }
44
- }`;
45
- export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, deleteMangaEntryMutation, deleteMediaEntryMutation, moveListMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, toggleFollowMutation, };
42
+ export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, deleteMangaEntryMutation, deleteMediaEntryMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, toggleFollowMutation, };
@@ -17,7 +17,10 @@ declare const activityAllQuery = "query ($userId: Int, $page: Int, $perPage: Int
17
17
  declare const activityMediaList = "query ($userId: Int, $page: Int, $perPage: Int, $type: ActivityType) {\n Page(page: $page, perPage: $perPage) {\n pageInfo { total currentPage lastPage hasNextPage perPage }\n activities(userId: $userId, type: $type, sort: ID_DESC) {\n ... on ListActivity { id type status progress media { id title { romaji english native } format } createdAt }\n }\n }\n}";
18
18
  declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) { id title { romaji english } } }\n";
19
19
  declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) { id title { romaji english } } }\n";
20
+ 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";
21
+ 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";
22
+ 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";
20
23
  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";
21
24
  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";
22
25
  declare const mangaDetailsQuery = "query ($id: Int) {\n Media(id: $id, type: MANGA) {\n id title { romaji english native userPreferred } coverImage { color medium large extraLarge } \n bannerImage description chapters volumes status genres\n startDate { year month day } endDate { year month day }\n }\n}\n";
23
- export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
26
+ export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
@@ -119,6 +119,40 @@ const malIdToAnilistAnimeId = `query ($malId: Int) {
119
119
  const malIdToAnilistMangaId = `query ($malId: Int) {
120
120
  Media(idMal: $malId, type: MANGA) { id title { romaji english } } }
121
121
  `;
122
+ const followingActivitiesQuery = `
123
+ query ($page: Int, $perPage: Int) {
124
+ Page(page: $page, perPage: $perPage) {
125
+ activities(isFollowing: true, sort: ID_DESC) {
126
+ ... on TextActivity { id type isLiked createdAt user { id name } }
127
+ ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
128
+ ... on MessageActivity { id type isLiked message createdAt recipient { id name } }
129
+ }
130
+ }
131
+ }
132
+ `;
133
+ const globalActivitiesQuery = `
134
+ query ($page: Int, $perPage: Int) {
135
+ Page(page: $page, perPage: $perPage) {
136
+ activities(sort: ID_DESC) {
137
+ ... on TextActivity { id type isLiked createdAt user { id name } }
138
+ ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
139
+ ... on MessageActivity { id type isLiked message createdAt recipient { id name } }
140
+ }
141
+ }
142
+ }
143
+ `;
144
+ const specificUserActivitiesQuery = `
145
+ query ($page: Int, $perPage: Int, $userId: Int) {
146
+ Page(page: $page, perPage: $perPage) {
147
+ pageInfo { total perPage currentPage lastPage hasNextPage }
148
+ activities(userId: $userId, sort: ID_DESC) {
149
+ ... on TextActivity { id type isLiked createdAt user { id name } }
150
+ ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
151
+ ... on MessageActivity { messenger { name } id type isLiked message createdAt recipient { id name } }
152
+ }
153
+ }
154
+ }
155
+ `;
122
156
  const userFollowingQuery = `query ($userId: Int!, $page: Int) {
123
157
  Page (page: $page) {
124
158
  pageInfo { total perPage currentPage lastPage hasNextPage }
@@ -141,4 +175,4 @@ const mangaDetailsQuery = `query ($id: Int) {
141
175
  }
142
176
  }
143
177
  `;
144
- export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
178
+ export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaDetailsQuery, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userFollowersQuery, userFollowingQuery, userQuery, };
@@ -323,6 +323,58 @@ type Activity = {
323
323
  };
324
324
  createdAt: number;
325
325
  };
326
+ interface TheActivity {
327
+ type: string;
328
+ id: number;
329
+ message?: string;
330
+ createdAt: number;
331
+ recipient?: {
332
+ id: number;
333
+ name: string;
334
+ };
335
+ isLiked?: boolean;
336
+ user?: {
337
+ id?: number;
338
+ name?: string;
339
+ };
340
+ messenger?: {
341
+ name: string;
342
+ };
343
+ media?: {
344
+ title?: {
345
+ userPreferred: string;
346
+ };
347
+ };
348
+ progress?: string | null;
349
+ status?: string;
350
+ }
351
+ type LikeActivityResponse = {
352
+ data?: {
353
+ ToggleLike: {
354
+ id: number;
355
+ };
356
+ };
357
+ errors?: {
358
+ message: string;
359
+ }[];
360
+ };
361
+ type SpecificUserActivitiesResponse = {
362
+ data?: {
363
+ Page: {
364
+ pageInfo: {
365
+ total: number;
366
+ perPage: number;
367
+ currentPage: number;
368
+ lastPage: number;
369
+ hasNextPage: boolean;
370
+ };
371
+ activities: TheActivity[];
372
+ };
373
+ };
374
+ errors?: {
375
+ message: string;
376
+ }[];
377
+ };
326
378
  type CoverImage = {
327
379
  color: string;
328
380
  medium: string;
@@ -347,18 +399,4 @@ type MangaDetails = {
347
399
  };
348
400
  errors?: Error;
349
401
  };
350
- type MoveListsResponse = {
351
- data?: {
352
- SaveMediaListEntry: {
353
- id: 474487691;
354
- status: 'COMPLETED';
355
- hiddenFromStatusLists: true;
356
- customLists: Record<string, boolean>;
357
- media: {
358
- title: MediaTitle;
359
- };
360
- };
361
- };
362
- errors?: Error;
363
- };
364
- export { Activity, AniListMediaStatus, AnimeDetails, AnimeList, AnimeSearchResponse, DateMonthYear, DeleteMangaResponse, DeleteMediaListResponse, List, MALAnimeStatus, MALAnimeXML, MALMangaStatus, MalIdToAnilistIdResponse, MangaDetails, MediaEntry, MediaList, MediaListCollectionResponse, MediaListEntry, MediaTitle, MediaWithProgress, MoveListsResponse, Myself, SaveMediaListEntryResponse, SaveTextActivityResponse, ToggleFollowResponse, User, UserActivitiesResponse, UserFollower, UserFollowing, UserResponse, saveAnimeWithProgressResponse, };
402
+ export { Activity, AniListMediaStatus, AnimeDetails, AnimeList, AnimeSearchResponse, DateMonthYear, DeleteMangaResponse, DeleteMediaListResponse, LikeActivityResponse, List, MALAnimeStatus, MALAnimeXML, MALMangaStatus, MalIdToAnilistIdResponse, MangaDetails, MediaEntry, MediaList, MediaListCollectionResponse, MediaListEntry, MediaTitle, MediaWithProgress, Myself, SaveMediaListEntryResponse, SaveTextActivityResponse, SpecificUserActivitiesResponse, TheActivity, ToggleFollowResponse, User, UserActivitiesResponse, UserFollower, UserFollowing, UserResponse, saveAnimeWithProgressResponse, };
@@ -9,8 +9,8 @@ declare class Validate {
9
9
  }[]): boolean;
10
10
  /**
11
11
  * Validate if MyAnimeList Anime XML file is valid or not
12
- * @param {string} xmlData
13
- * @returns {Promise<boolean>}
12
+ * @param xmlData string
13
+ * @returns boolean
14
14
  */
15
15
  static Import_AnimeXML(xmlData: string): Promise<boolean>;
16
16
  /**
@@ -20,8 +20,8 @@ class Validate {
20
20
  }
21
21
  /**
22
22
  * Validate if MyAnimeList Anime XML file is valid or not
23
- * @param {string} xmlData
24
- * @returns {Promise<boolean>}
23
+ * @param xmlData string
24
+ * @returns boolean
25
25
  */
26
26
  static Import_AnimeXML(xmlData) {
27
27
  return __awaiter(this, void 0, void 0, function* () {
@@ -100,7 +100,7 @@ class Validate {
100
100
  console.error('File content is empty or invalid.');
101
101
  return false;
102
102
  }
103
- const obj3ct = yield JSON.parse(file);
103
+ const obj3ct = JSON.parse(file);
104
104
  if (!obj3ct || !Array.isArray(obj3ct.anime)) {
105
105
  console.error("Invalid JSON structure: Missing or malformed 'anime' array.");
106
106
  return false;
@@ -1,4 +1,4 @@
1
- import { DateMonthYear, MALAnimeStatus, MALMangaStatus, MediaWithProgress, User } from './types.js';
1
+ import { DateMonthYear, MALAnimeStatus, MALMangaStatus, MediaWithProgress, TheActivity, User } from './types.js';
2
2
  declare const aniListEndpoint = "https://graphql.anilist.co";
3
3
  declare const redirectUri = "https://anilist.co/api/v2/oauth/pin";
4
4
  declare function getTitle(title: {
@@ -38,6 +38,7 @@ declare function createMangaListXML(mediaWithProgress: MediaWithProgress[]): Pro
38
38
  declare function getCurrentPackageVersion(): string | null;
39
39
  declare function timestampToTimeAgo(timestamp: number): string;
40
40
  declare const anidbToanilistMapper: (romanjiName: string, year: number, englishName?: string) => Promise<number | null>;
41
+ declare function activityBy(activity: TheActivity, count?: number): string;
41
42
  /**
42
43
  * Extract the save file path
43
44
  * @param data_type - anime|manga
@@ -48,4 +49,4 @@ declare function saveToPath(data_type: string, file_format: string): Promise<str
48
49
  declare function simpleDateFormat(date: DateMonthYear): string;
49
50
  declare function handleRateLimitRetry(retryCount: number): Promise<void>;
50
51
  declare function logUserDetails(user: User, followersCount: number, followingCount: number): void;
51
- export { anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, handleRateLimitRetry, logUserDetails, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, saveToPath, selectFile, simpleDateFormat, timestampToTimeAgo, };
52
+ export { activityBy, anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, handleRateLimitRetry, logUserDetails, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, saveToPath, selectFile, simpleDateFormat, timestampToTimeAgo, };
@@ -261,7 +261,6 @@ function createAnimeListXML(mediaWithProgress) {
261
261
  // Filter out anime without malId
262
262
  const filteredMedia = mediaWithProgress.filter((anime) => anime.malId);
263
263
  const xmlEntries = filteredMedia.map((anime) => {
264
- console.log(anime);
265
264
  const malId = anime.malId;
266
265
  const progress = anime.progress;
267
266
  const episodes = anime.episodes;
@@ -383,6 +382,27 @@ const anidbToanilistMapper = (romanjiName, year, englishName) => __awaiter(void
383
382
  }
384
383
  return null;
385
384
  });
385
+ function activityBy(activity, count) {
386
+ var _a, _b, _c, _d;
387
+ const countStr = `[${count ? count : '?'}]`.padEnd(6);
388
+ if ((_a = activity === null || activity === void 0 ? void 0 : activity.messenger) === null || _a === void 0 ? void 0 : _a.name) {
389
+ return `${countStr}${activity.messenger.name} >> messaged ${activity.recipient.name}`;
390
+ }
391
+ else if ((_c = (_b = activity === null || activity === void 0 ? void 0 : activity.media) === null || _b === void 0 ? void 0 : _b.title) === null || _c === void 0 ? void 0 : _c.userPreferred) {
392
+ if (activity.progress) {
393
+ return `${countStr}${activity.user.name} >> ${activity.status} ${activity.progress} of ${activity.media.title.userPreferred}`;
394
+ }
395
+ else {
396
+ return `${countStr}${activity.user.name} >> ${activity.status} ${activity.media.title.userPreferred}`;
397
+ }
398
+ }
399
+ else if ((_d = activity === null || activity === void 0 ? void 0 : activity.user) === null || _d === void 0 ? void 0 : _d.name) {
400
+ return `${countStr}${activity.user.name}`;
401
+ }
402
+ else {
403
+ return `${countStr}???`;
404
+ }
405
+ }
386
406
  /**
387
407
  * Extract the save file path
388
408
  * @param data_type - anime|manga
@@ -453,4 +473,4 @@ function logUserDetails(user, followersCount, followingCount) {
453
473
  'Volumes Read': ((_p = (_o = user.statistics) === null || _o === void 0 ? void 0 : _o.manga) === null || _p === void 0 ? void 0 : _p.volumesRead) || 0,
454
474
  });
455
475
  }
456
- export { anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, handleRateLimitRetry, logUserDetails, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, saveToPath, selectFile, simpleDateFormat, timestampToTimeAgo, };
476
+ export { activityBy, anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, handleRateLimitRetry, logUserDetails, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, saveJSONasXML, saveToPath, selectFile, simpleDateFormat, timestampToTimeAgo, };
package/bin/index.js CHANGED
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  import { Command } from 'commander';
12
12
  import process from 'process';
13
13
  import { Auth, Social } from './helpers/auth.js';
14
- import { AniList, MoveTo } from './helpers/lists.js';
14
+ import { AniList } from './helpers/lists.js';
15
15
  import { getCurrentPackageVersion } from './helpers/workers.js';
16
16
  const cli = new Command();
17
17
  cli
@@ -210,6 +210,13 @@ cli
210
210
  }
211
211
  }
212
212
  }));
213
+ cli
214
+ .command('autolike')
215
+ .alias('al')
216
+ .description('Autolike following or global activities.')
217
+ .action(() => __awaiter(void 0, void 0, void 0, function* () {
218
+ yield Auth.AutoLike();
219
+ }));
213
220
  cli
214
221
  .command('social')
215
222
  .alias('sol')
@@ -234,25 +241,4 @@ cli
234
241
  }
235
242
  }
236
243
  }));
237
- cli
238
- .command('move')
239
- .alias('mv')
240
- .description('Move anime or manga from one list to another')
241
- .option('-a, --anime', 'To move anime lists.', false)
242
- .option('-m, --manga', 'To move manga lists.', false)
243
- .action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga }) {
244
- if (!(yield Auth.isLoggedIn())) {
245
- console.error(`\nPlease login to use this feature.`);
246
- process.exit(1);
247
- }
248
- if ((!anime && !manga) || (anime && manga)) {
249
- console.error(`\nMust select an option, either --anime or --manga`);
250
- }
251
- if (anime) {
252
- yield MoveTo.AnimeList();
253
- }
254
- else if (manga) {
255
- yield MoveTo.MangaList();
256
- }
257
- }));
258
244
  cli.parse(process.argv);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@irfanshadikrishad/anilist",
3
3
  "description": "Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts",
4
4
  "author": "Irfan Shadik Rishad",
5
- "version": "1.8.0",
5
+ "version": "2.0.0-forbidden",
6
6
  "main": "./bin/index.js",
7
7
  "type": "module",
8
8
  "types": "./bin/index.d.ts",
@@ -56,15 +56,14 @@
56
56
  "prettier": "@irfanshadikrishad/prettier",
57
57
  "devDependencies": {
58
58
  "@babel/preset-env": "^7.28.0",
59
- "@eslint/js": "^9.30.1",
59
+ "@eslint/js": "^9.31.0",
60
60
  "@irfanshadikrishad/prettier": "^1.1.0",
61
61
  "@types/jest": "^30.0.0",
62
- "@types/node": "^24.0.10",
62
+ "@types/node": "^24.0.14",
63
63
  "@types/papaparse": "^5.3.16",
64
64
  "@types/xml2js": "^0.4.14",
65
- "@typescript-eslint/eslint-plugin": "^8.35.1",
66
- "@typescript-eslint/parser": "^8.35.1",
67
- "eslint": "^9.30.1",
65
+ "@typescript-eslint/eslint-plugin": "^8.37.0",
66
+ "eslint": "^9.31.0",
68
67
  "globals": "^16.3.0",
69
68
  "jest": "^30.0.4",
70
69
  "prettier": "^3.6.2",
@@ -74,15 +73,15 @@
74
73
  "typescript": "^5.8.3"
75
74
  },
76
75
  "dependencies": {
77
- "@irfanshadikrishad/cipher": "^1.2.1",
76
+ "@irfanshadikrishad/cipher": "^1.3.0",
78
77
  "chalk": "^5.4.1",
79
78
  "cli-truncate": "^4.0.0",
80
79
  "commander": "^14.0.0",
81
80
  "fast-xml-parser": "^5.2.5",
82
81
  "inquirer": "^12.7.0",
83
- "jsonrepair": "^3.12.0",
82
+ "jsonrepair": "^3.13.0",
84
83
  "node-fetch": "^3.3.2",
85
- "open": "^10.1.2",
84
+ "open": "^10.2.0",
86
85
  "papaparse": "^5.5.3",
87
86
  "tiny-spinner": "^2.0.5",
88
87
  "xml2js": "^0.6.2"
package/CITATION.cff DELETED
@@ -1,8 +0,0 @@
1
- cff-version: 1.2.0
2
- message: 'If you use this software, please cite it as below.'
3
- title: '@irfanshadikrishad/anilist'
4
- authors:
5
- - name: 'Irfan Shadik Rishad'
6
- orcid: '0009-0001-6745-5291'
7
- date-released: '2024-10-12'
8
- repository-code: 'https://github.com/irfanshadikrishad/anilist'
File without changes
File without changes