@irfanshadikrishad/anilist 1.0.2 → 1.0.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.
- package/README.md +56 -4
- package/bin/helpers/lists.js +216 -89
- package/bin/helpers/more.js +45 -38
- package/bin/helpers/mutations.d.ts +1 -1
- package/bin/helpers/mutations.js +1 -1
- package/bin/helpers/queries.d.ts +1 -1
- package/bin/helpers/queries.js +15 -2
- package/bin/index.js +4 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -48,17 +48,21 @@ here `<client-id>` and `<client-secret>` should be replaced by the ones that you
|
|
|
48
48
|
| **`-h, --help`** | _None_ | Display available commands and options |
|
|
49
49
|
| **`trending`** <br> _(alias: `tr`)_ | `-c (default: 10)` | Fetch trending anime (default count is 10) |
|
|
50
50
|
| **`popular`** <br> _(alias: `plr`)_ | `-c (default: 10)` | Fetch popular anime (default count is 10) |
|
|
51
|
-
| **`user`** |
|
|
51
|
+
| **`user`** | `<username>` | Get information about a specific AniList user |
|
|
52
52
|
| **`lists`** <br> _(alias: `ls`)_ | `-a, --anime` <br> `-m, --manga` | Fetch anime or manga lists of the logged-in user |
|
|
53
53
|
| **`delete`** <br> _(alias: `del`)_ | `-a, --anime` <br> `-m, --manga` <br> `-ac, --activity` | Delete collections of anime, manga or activities |
|
|
54
54
|
| **`upcoming`** <br> _(alias:`up`)_ | `-c (default: 10)` | Fetch upcoming anime (default count is 10) |
|
|
55
|
-
| **`anime`** |
|
|
55
|
+
| **`anime`** | `<anime-id>` | Get anime details by Anime Id |
|
|
56
56
|
| **`search`** <br> _(alias:`srch`/`find`)_ | `<query>` <br> `-a, --anime` <br> `-m, --manga` <br> `-c (default: 10)` | Get anime/manga search results |
|
|
57
57
|
|
|
58
58
|
#### Command Breakdown:
|
|
59
59
|
|
|
60
60
|
#### `login`:
|
|
61
61
|
|
|
62
|
+
```bash
|
|
63
|
+
anilist login -i <client-id> -s <client-secret>
|
|
64
|
+
```
|
|
65
|
+
|
|
62
66
|
- **Options**:
|
|
63
67
|
- `-i, --id`: Specify AniList Client ID
|
|
64
68
|
- `-s, --secret`: Provide the AniList Client Secret
|
|
@@ -66,46 +70,82 @@ here `<client-id>` and `<client-secret>` should be replaced by the ones that you
|
|
|
66
70
|
|
|
67
71
|
#### `logout`:
|
|
68
72
|
|
|
73
|
+
```bash
|
|
74
|
+
anilist logout
|
|
75
|
+
```
|
|
76
|
+
|
|
69
77
|
- **Description**: End the current session and log out from your AniList account.
|
|
70
78
|
|
|
71
79
|
#### `me`:
|
|
72
80
|
|
|
81
|
+
```bash
|
|
82
|
+
anilist me
|
|
83
|
+
```
|
|
84
|
+
|
|
73
85
|
- **Description**: Retrieve and display information about the currently logged-in user, including stats and profile details.
|
|
74
86
|
|
|
75
87
|
#### `-V, --version`:
|
|
76
88
|
|
|
89
|
+
```bash
|
|
90
|
+
anilist -V
|
|
91
|
+
```
|
|
92
|
+
|
|
77
93
|
- **Description**: Quickly check which version of the CLI you are running.
|
|
78
94
|
|
|
79
95
|
#### `-h, --help`:
|
|
80
96
|
|
|
97
|
+
```bash
|
|
98
|
+
anilist -h
|
|
99
|
+
```
|
|
100
|
+
|
|
81
101
|
- **Description**: List all available commands and their usage details for quick reference.
|
|
82
102
|
|
|
83
103
|
#### `trending` _(alias: `tr`)_:
|
|
84
104
|
|
|
105
|
+
```bash
|
|
106
|
+
anilist tr -c 15
|
|
107
|
+
```
|
|
108
|
+
|
|
85
109
|
- **Options**:
|
|
86
110
|
- `-c (count)`: Specify how many trending anime to fetch (default: 10).
|
|
87
111
|
- **Description**: Fetch the current trending anime series, with the option to customize how many results to display.
|
|
88
112
|
|
|
89
113
|
#### `popular` _(alias: `plr`)_:
|
|
90
114
|
|
|
115
|
+
```bash
|
|
116
|
+
anilist popular
|
|
117
|
+
```
|
|
118
|
+
|
|
91
119
|
- **Options**:
|
|
92
120
|
- `-c (count)`: Specify how many popular anime to fetch (default: 10).
|
|
93
121
|
- **Description**: Fetch the most popular anime series, with the option to customize how many results to display.
|
|
94
122
|
|
|
95
123
|
#### `upcoming` _(alias: `up`)_:
|
|
96
124
|
|
|
125
|
+
```bash
|
|
126
|
+
anilist up -c 25
|
|
127
|
+
```
|
|
128
|
+
|
|
97
129
|
- **Options**:
|
|
98
130
|
- `-c (count)`: Specify how many upcoming anime to fetch (default: 10).
|
|
99
131
|
- **Description**: Fetch the upcoming anime series next season, with the option to customize how many results to display.
|
|
100
132
|
|
|
101
133
|
#### `user`:
|
|
102
134
|
|
|
135
|
+
```bash
|
|
136
|
+
anilist user <username>
|
|
137
|
+
```
|
|
138
|
+
|
|
103
139
|
- **Options**:
|
|
104
|
-
-
|
|
140
|
+
- `<username>`: Specify the AniList username to fetch.
|
|
105
141
|
- **Description**: Retrieve profile information about a specific AniList user.
|
|
106
142
|
|
|
107
143
|
#### `lists` _(alias: `ls`)_:
|
|
108
144
|
|
|
145
|
+
```bash
|
|
146
|
+
anilist ls -a
|
|
147
|
+
```
|
|
148
|
+
|
|
109
149
|
- **Options**:
|
|
110
150
|
- `-a, --anime`: Fetch the authenticated user's anime list.
|
|
111
151
|
- `-m, --manga`: Fetch the authenticated user's manga list.
|
|
@@ -113,6 +153,10 @@ here `<client-id>` and `<client-secret>` should be replaced by the ones that you
|
|
|
113
153
|
|
|
114
154
|
#### `delete` _(alias: `del`)_:
|
|
115
155
|
|
|
156
|
+
```bash
|
|
157
|
+
anilist del -ac
|
|
158
|
+
```
|
|
159
|
+
|
|
116
160
|
- **Options**:
|
|
117
161
|
- `-a, --anime`: Delete your specific anime collection that you want.
|
|
118
162
|
- `-m, --manga`: Delete your specific manga collection that you want.
|
|
@@ -121,12 +165,20 @@ here `<client-id>` and `<client-secret>` should be replaced by the ones that you
|
|
|
121
165
|
|
|
122
166
|
#### `anime`
|
|
123
167
|
|
|
168
|
+
```bash
|
|
169
|
+
anilist anime <anime-id>
|
|
170
|
+
```
|
|
171
|
+
|
|
124
172
|
- **Options**
|
|
125
|
-
-
|
|
173
|
+
- `<anime-id>` _(eg: 21)_ : Id of the anime you want to get details of.
|
|
126
174
|
- **Description**: Get anime details by anime Id.
|
|
127
175
|
|
|
128
176
|
#### `search` _(alias: `srch`/`find`)_:
|
|
129
177
|
|
|
178
|
+
```bash
|
|
179
|
+
anilist search <query> -a -c 20
|
|
180
|
+
```
|
|
181
|
+
|
|
130
182
|
- **Options**:
|
|
131
183
|
- `<query>` : What you want to search (eg: naruto).
|
|
132
184
|
- `-a, --anime`: To get results of anime search.
|
package/bin/helpers/lists.js
CHANGED
|
@@ -13,7 +13,7 @@ import { aniListEndpoint, getNextSeasonAndYear, getTitle } from "./workers.js";
|
|
|
13
13
|
import { deleteMangaEntryMutation, deleteMediaEntryMutation, popularQuery, trendingQuery, upcomingAnimesQuery, } from "./queries.js";
|
|
14
14
|
import { currentUserAnimeList, currentUserMangaList } from "./queries.js";
|
|
15
15
|
import { isLoggedIn, currentUsersId, retriveAccessToken } from "./auth.js";
|
|
16
|
-
import { addAnimeToListMutation } from "./mutations.js";
|
|
16
|
+
import { addAnimeToListMutation, addMangaToListMutation } from "./mutations.js";
|
|
17
17
|
import { fetcher } from "./fetcher.js";
|
|
18
18
|
function getTrending(count) {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -38,10 +38,11 @@ function getTrending(count) {
|
|
|
38
38
|
type: "list",
|
|
39
39
|
name: "selectedAnime",
|
|
40
40
|
message: "Select anime to add to the list:",
|
|
41
|
-
choices: media.map((upx) => ({
|
|
42
|
-
name: getTitle(upx === null || upx === void 0 ? void 0 : upx.title)
|
|
41
|
+
choices: media.map((upx, idx) => ({
|
|
42
|
+
name: `[${idx + 1}] ${getTitle(upx === null || upx === void 0 ? void 0 : upx.title)}`,
|
|
43
43
|
value: upx === null || upx === void 0 ? void 0 : upx.id,
|
|
44
44
|
})),
|
|
45
|
+
pageSize: 10,
|
|
45
46
|
},
|
|
46
47
|
]);
|
|
47
48
|
// Where to save
|
|
@@ -113,10 +114,11 @@ function getPopular(count) {
|
|
|
113
114
|
type: "list",
|
|
114
115
|
name: "selectedAnime",
|
|
115
116
|
message: "Select anime to add to the list:",
|
|
116
|
-
choices: media.map((upx) => ({
|
|
117
|
-
name: getTitle(upx === null || upx === void 0 ? void 0 : upx.title)
|
|
117
|
+
choices: media.map((upx, idx) => ({
|
|
118
|
+
name: `[${idx + 1}] ${getTitle(upx === null || upx === void 0 ? void 0 : upx.title)}`,
|
|
118
119
|
value: upx === null || upx === void 0 ? void 0 : upx.id,
|
|
119
120
|
})),
|
|
121
|
+
pageSize: 10,
|
|
120
122
|
},
|
|
121
123
|
]);
|
|
122
124
|
// Where to save
|
|
@@ -167,7 +169,7 @@ function getPopular(count) {
|
|
|
167
169
|
}
|
|
168
170
|
function loggedInUsersAnimeLists() {
|
|
169
171
|
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
-
var _a, _b, _c;
|
|
172
|
+
var _a, _b, _c, _d, _e;
|
|
171
173
|
try {
|
|
172
174
|
const loggedIn = yield isLoggedIn();
|
|
173
175
|
if (loggedIn) {
|
|
@@ -187,28 +189,81 @@ function loggedInUsersAnimeLists() {
|
|
|
187
189
|
const response = yield request.json();
|
|
188
190
|
if (request.status === 200) {
|
|
189
191
|
const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
|
|
190
|
-
|
|
191
|
-
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
192
|
+
if (lists.length > 0) {
|
|
193
|
+
const { selectedList } = yield inquirer.prompt([
|
|
194
|
+
{
|
|
195
|
+
type: "list",
|
|
196
|
+
name: "selectedList",
|
|
197
|
+
message: "Select an anime list:",
|
|
198
|
+
choices: lists.map((list) => list.name),
|
|
199
|
+
},
|
|
200
|
+
]);
|
|
201
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
202
|
+
if (selectedEntries) {
|
|
203
|
+
console.log(`\nEntries for '${selectedEntries.name}':`);
|
|
204
|
+
if (((_c = selectedEntries === null || selectedEntries === void 0 ? void 0 : selectedEntries.entries) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
205
|
+
const { selectedAnime } = yield inquirer.prompt([
|
|
206
|
+
{
|
|
207
|
+
type: "list",
|
|
208
|
+
name: "selectedAnime",
|
|
209
|
+
message: "Select anime to add to the list:",
|
|
210
|
+
choices: selectedEntries === null || selectedEntries === void 0 ? void 0 : selectedEntries.entries.map((upx, idx) => {
|
|
211
|
+
var _a, _b;
|
|
212
|
+
return ({
|
|
213
|
+
name: `[${idx + 1}] ${getTitle((_a = upx === null || upx === void 0 ? void 0 : upx.media) === null || _a === void 0 ? void 0 : _a.title)}`,
|
|
214
|
+
value: (_b = upx === null || upx === void 0 ? void 0 : upx.media) === null || _b === void 0 ? void 0 : _b.id,
|
|
215
|
+
});
|
|
216
|
+
}),
|
|
217
|
+
pageSize: 10,
|
|
218
|
+
},
|
|
219
|
+
]);
|
|
220
|
+
// Where to save
|
|
221
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
222
|
+
{
|
|
223
|
+
type: "list",
|
|
224
|
+
name: "selectedListType",
|
|
225
|
+
message: "Select the list where you want to save this anime:",
|
|
226
|
+
choices: [
|
|
227
|
+
{ name: "Planning", value: "PLANNING" },
|
|
228
|
+
{ name: "Watching", value: "CURRENT" },
|
|
229
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
230
|
+
{ name: "Paused", value: "PAUSED" },
|
|
231
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
]);
|
|
235
|
+
// Lets save to the list now
|
|
236
|
+
const ISLOGGEDIN = yield isLoggedIn();
|
|
237
|
+
if (ISLOGGEDIN) {
|
|
238
|
+
const query = addAnimeToListMutation;
|
|
239
|
+
const variables = {
|
|
240
|
+
mediaId: selectedAnime,
|
|
241
|
+
status: selectedListType,
|
|
242
|
+
};
|
|
243
|
+
const response = yield fetcher(query, variables);
|
|
244
|
+
if (response) {
|
|
245
|
+
const saved = (_d = response === null || response === void 0 ? void 0 : response.data) === null || _d === void 0 ? void 0 : _d.SaveMediaListEntry;
|
|
246
|
+
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.error(`Please log in first to use this feature.`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(`Not available at this moment.`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.log("No entries found.");
|
|
259
|
+
}
|
|
205
260
|
}
|
|
206
261
|
else {
|
|
207
|
-
console.log(
|
|
262
|
+
console.log(`\nYou seems to have no anime(s) in your lists.`);
|
|
208
263
|
}
|
|
209
264
|
}
|
|
210
265
|
else {
|
|
211
|
-
console.log(`Something went wrong. ${(
|
|
266
|
+
console.log(`Something went wrong. ${(_e = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _e === void 0 ? void 0 : _e.message}`);
|
|
212
267
|
}
|
|
213
268
|
}
|
|
214
269
|
else {
|
|
@@ -226,7 +281,7 @@ function loggedInUsersAnimeLists() {
|
|
|
226
281
|
}
|
|
227
282
|
function loggedInUsersMangaLists() {
|
|
228
283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
-
var _a, _b, _c;
|
|
284
|
+
var _a, _b, _c, _d, _e, _f;
|
|
230
285
|
try {
|
|
231
286
|
const loggedIn = yield isLoggedIn();
|
|
232
287
|
if (loggedIn) {
|
|
@@ -235,7 +290,7 @@ function loggedInUsersMangaLists() {
|
|
|
235
290
|
const request = yield fetch(aniListEndpoint, {
|
|
236
291
|
method: "POST",
|
|
237
292
|
headers: {
|
|
238
|
-
"
|
|
293
|
+
"Content-Type": "application/json",
|
|
239
294
|
Authorization: `Bearer ${yield retriveAccessToken()}`,
|
|
240
295
|
},
|
|
241
296
|
body: JSON.stringify({
|
|
@@ -244,42 +299,101 @@ function loggedInUsersMangaLists() {
|
|
|
244
299
|
}),
|
|
245
300
|
});
|
|
246
301
|
const response = yield request.json();
|
|
247
|
-
if (request.status === 200) {
|
|
248
|
-
const lists =
|
|
249
|
-
|
|
250
|
-
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
302
|
+
if (request.status === 200 && ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection)) {
|
|
303
|
+
const lists = response.data.MediaListCollection.lists;
|
|
304
|
+
if (lists && lists.length > 0) {
|
|
305
|
+
const { selectedList } = yield inquirer.prompt([
|
|
306
|
+
{
|
|
307
|
+
type: "list",
|
|
308
|
+
name: "selectedList",
|
|
309
|
+
message: "Select a manga list:",
|
|
310
|
+
choices: lists.map((list) => list.name),
|
|
311
|
+
},
|
|
312
|
+
]);
|
|
313
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
314
|
+
if (selectedEntries && selectedEntries.entries.length > 0) {
|
|
315
|
+
console.log(`\nEntries for '${selectedEntries.name}':`);
|
|
316
|
+
const { selectedManga } = yield inquirer.prompt([
|
|
317
|
+
{
|
|
318
|
+
type: "list",
|
|
319
|
+
name: "selectedManga",
|
|
320
|
+
message: "Select a manga to add to the list:",
|
|
321
|
+
choices: selectedEntries.entries.map((entry, idx) => {
|
|
322
|
+
var _a;
|
|
323
|
+
return ({
|
|
324
|
+
name: `[${idx + 1}] ${getTitle(entry.media.title)}`,
|
|
325
|
+
value: (_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.id,
|
|
326
|
+
});
|
|
327
|
+
}),
|
|
328
|
+
pageSize: 10,
|
|
329
|
+
},
|
|
330
|
+
]);
|
|
331
|
+
// Prompt user to select list type to save to
|
|
332
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
333
|
+
{
|
|
334
|
+
type: "list",
|
|
335
|
+
name: "selectedListType",
|
|
336
|
+
message: "Select the list where you want to save this manga:",
|
|
337
|
+
choices: [
|
|
338
|
+
{ name: "Planning", value: "PLANNING" },
|
|
339
|
+
{ name: "Reading", value: "CURRENT" },
|
|
340
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
341
|
+
{ name: "Paused", value: "PAUSED" },
|
|
342
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
343
|
+
],
|
|
344
|
+
},
|
|
345
|
+
]);
|
|
346
|
+
// Save the selected manga to the selected list type
|
|
347
|
+
const ISLOGGEDIN = yield isLoggedIn();
|
|
348
|
+
if (ISLOGGEDIN) {
|
|
349
|
+
const query = addMangaToListMutation;
|
|
350
|
+
const variables = {
|
|
351
|
+
mediaId: selectedManga,
|
|
352
|
+
status: selectedListType,
|
|
353
|
+
};
|
|
354
|
+
const saveRequest = yield fetch(aniListEndpoint, {
|
|
355
|
+
method: "POST",
|
|
356
|
+
headers: {
|
|
357
|
+
"Content-Type": "application/json",
|
|
358
|
+
Authorization: `Bearer ${yield retriveAccessToken()}`,
|
|
359
|
+
},
|
|
360
|
+
body: JSON.stringify({ query, variables }),
|
|
361
|
+
});
|
|
362
|
+
const saveResponse = yield saveRequest.json();
|
|
363
|
+
if ((_b = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.data) === null || _b === void 0 ? void 0 : _b.SaveMediaListEntry) {
|
|
364
|
+
const saved = saveResponse.data.SaveMediaListEntry;
|
|
365
|
+
console.log(`\nEntry ${saved.id}. Saved as ${saved.status}.`);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
console.error(`Failed to save the manga. ${((_d = (_c = saveResponse === null || saveResponse === void 0 ? void 0 : saveResponse.errors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.message) || "Unknown error"}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
console.error(`Please log in first to use this feature.`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
console.log("No manga entries found in the selected list.");
|
|
377
|
+
}
|
|
264
378
|
}
|
|
265
379
|
else {
|
|
266
|
-
console.log("
|
|
380
|
+
console.log("\nYou don't seem to have any manga in your lists.");
|
|
267
381
|
}
|
|
268
382
|
}
|
|
269
383
|
else {
|
|
270
|
-
console.
|
|
384
|
+
console.error(`Failed to fetch manga lists. ${((_f = (_e = response === null || response === void 0 ? void 0 : response.errors) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.message) || "Unknown error"}`);
|
|
271
385
|
}
|
|
272
386
|
}
|
|
273
387
|
else {
|
|
274
|
-
console.
|
|
388
|
+
console.error(`Failed to get the current user ID.`);
|
|
275
389
|
}
|
|
276
390
|
}
|
|
277
391
|
else {
|
|
278
|
-
console.
|
|
392
|
+
console.error("Please log in first.");
|
|
279
393
|
}
|
|
280
394
|
}
|
|
281
395
|
catch (error) {
|
|
282
|
-
console.
|
|
396
|
+
console.error(`Something went wrong. ${error.message}`);
|
|
283
397
|
}
|
|
284
398
|
});
|
|
285
399
|
}
|
|
@@ -304,30 +418,36 @@ function deleteAnimeCollection() {
|
|
|
304
418
|
const response = yield request.json();
|
|
305
419
|
if (request.status === 200) {
|
|
306
420
|
const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
|
|
307
|
-
|
|
308
|
-
{
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
421
|
+
if (lists.length > 0) {
|
|
422
|
+
const { selectedList } = yield inquirer.prompt([
|
|
423
|
+
{
|
|
424
|
+
type: "list",
|
|
425
|
+
name: "selectedList",
|
|
426
|
+
message: "Select an anime list:",
|
|
427
|
+
choices: lists.map((list) => list.name),
|
|
428
|
+
pageSize: 10,
|
|
429
|
+
},
|
|
430
|
+
]);
|
|
431
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
432
|
+
if (selectedEntries) {
|
|
433
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
434
|
+
for (const [idx, entry] of selectedEntries.entries.entries()) {
|
|
435
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
436
|
+
yield deleteAnimeByAnimeId(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
437
|
+
yield new Promise((resolve) => setTimeout(resolve, 2000));
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
console.log(`No id in entry.`);
|
|
441
|
+
console.log(entry);
|
|
442
|
+
}
|
|
326
443
|
}
|
|
327
444
|
}
|
|
445
|
+
else {
|
|
446
|
+
console.log("No entries found.");
|
|
447
|
+
}
|
|
328
448
|
}
|
|
329
449
|
else {
|
|
330
|
-
console.log(
|
|
450
|
+
console.log(`\nNo anime(s) found in any list.`);
|
|
331
451
|
}
|
|
332
452
|
}
|
|
333
453
|
else {
|
|
@@ -394,30 +514,36 @@ function deleteMangaCollection() {
|
|
|
394
514
|
const response = yield request.json();
|
|
395
515
|
if (request.status === 200) {
|
|
396
516
|
const lists = (_b = (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.MediaListCollection) === null || _b === void 0 ? void 0 : _b.lists;
|
|
397
|
-
|
|
398
|
-
{
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
517
|
+
if (lists.length > 0) {
|
|
518
|
+
const { selectedList } = yield inquirer.prompt([
|
|
519
|
+
{
|
|
520
|
+
type: "list",
|
|
521
|
+
name: "selectedList",
|
|
522
|
+
message: "Select a manga list:",
|
|
523
|
+
choices: lists.map((list) => list.name),
|
|
524
|
+
pageSize: 10,
|
|
525
|
+
},
|
|
526
|
+
]);
|
|
527
|
+
const selectedEntries = lists.find((list) => list.name === selectedList);
|
|
528
|
+
if (selectedEntries) {
|
|
529
|
+
console.log(`\nDeleting entries of '${selectedEntries.name}':`);
|
|
530
|
+
for (const [idx, entry] of selectedEntries.entries.entries()) {
|
|
531
|
+
if (entry === null || entry === void 0 ? void 0 : entry.id) {
|
|
532
|
+
yield deleteMangaByMangaId(entry === null || entry === void 0 ? void 0 : entry.id, (_c = entry === null || entry === void 0 ? void 0 : entry.media) === null || _c === void 0 ? void 0 : _c.title);
|
|
533
|
+
yield new Promise((resolve) => setTimeout(resolve, 2000));
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
console.log(`No id in entry.`);
|
|
537
|
+
console.log(entry);
|
|
538
|
+
}
|
|
416
539
|
}
|
|
417
540
|
}
|
|
541
|
+
else {
|
|
542
|
+
console.log("No entries found.");
|
|
543
|
+
}
|
|
418
544
|
}
|
|
419
545
|
else {
|
|
420
|
-
console.log(
|
|
546
|
+
console.log(`\nNo manga(s) found in any list.`);
|
|
421
547
|
}
|
|
422
548
|
}
|
|
423
549
|
else {
|
|
@@ -491,10 +617,11 @@ function getUpcomingAnimes(count) {
|
|
|
491
617
|
type: "list",
|
|
492
618
|
name: "selectedAnime",
|
|
493
619
|
message: "Select anime to add to the list:",
|
|
494
|
-
choices: upcoming.map((upx) => ({
|
|
495
|
-
name: getTitle(upx === null || upx === void 0 ? void 0 : upx.title)
|
|
620
|
+
choices: upcoming.map((upx, idx) => ({
|
|
621
|
+
name: `[${idx + 1}] ${getTitle(upx === null || upx === void 0 ? void 0 : upx.title)}`,
|
|
496
622
|
value: upx === null || upx === void 0 ? void 0 : upx.id,
|
|
497
623
|
})),
|
|
624
|
+
pageSize: 10,
|
|
498
625
|
},
|
|
499
626
|
]);
|
|
500
627
|
// Where to save
|
package/bin/helpers/more.js
CHANGED
|
@@ -105,45 +105,51 @@ function getAnimeSearchResults(search, count) {
|
|
|
105
105
|
const searchResults = yield fetcher(query, variables);
|
|
106
106
|
if (searchResults) {
|
|
107
107
|
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;
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
108
|
+
if (results.length > 0) {
|
|
109
|
+
const { selectedList } = yield inquirer.prompt([
|
|
110
|
+
{
|
|
111
|
+
type: "list",
|
|
112
|
+
name: "selectedList",
|
|
113
|
+
message: "Select anime to add to your list:",
|
|
114
|
+
choices: results.map((res, idx) => ({
|
|
115
|
+
name: `[${idx + 1}] ${getTitle(res === null || res === void 0 ? void 0 : res.title)}`,
|
|
116
|
+
value: res === null || res === void 0 ? void 0 : res.id,
|
|
117
|
+
})),
|
|
118
|
+
pageSize: 10,
|
|
119
|
+
},
|
|
120
|
+
]);
|
|
121
|
+
// Where to save
|
|
122
|
+
const { selectedListType } = yield inquirer.prompt([
|
|
123
|
+
{
|
|
124
|
+
type: "list",
|
|
125
|
+
name: "selectedListType",
|
|
126
|
+
message: "Select the list where you want to save this anime:",
|
|
127
|
+
choices: [
|
|
128
|
+
{ name: "Planning", value: "PLANNING" },
|
|
129
|
+
{ name: "Watching", value: "CURRENT" },
|
|
130
|
+
{ name: "Completed", value: "COMPLETED" },
|
|
131
|
+
{ name: "Paused", value: "PAUSED" },
|
|
132
|
+
{ name: "Dropped", value: "DROPPED" },
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
]);
|
|
136
|
+
// Lets save to the list now
|
|
137
|
+
const ISLOGGEDIN = yield isLoggedIn();
|
|
138
|
+
if (ISLOGGEDIN) {
|
|
139
|
+
const query = addAnimeToListMutation;
|
|
140
|
+
const variables = { mediaId: selectedList, status: selectedListType };
|
|
141
|
+
const response = yield fetcher(query, variables);
|
|
142
|
+
if (response) {
|
|
143
|
+
const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
|
|
144
|
+
console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.error(`Please log in first to use this feature.`);
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
else {
|
|
146
|
-
console.
|
|
152
|
+
console.log(`\nNo search results!`);
|
|
147
153
|
}
|
|
148
154
|
}
|
|
149
155
|
else {
|
|
@@ -165,10 +171,11 @@ function getMangaSearchResults(search, count) {
|
|
|
165
171
|
type: "list",
|
|
166
172
|
name: "selectedMangaId",
|
|
167
173
|
message: "Select manga to add to your list:",
|
|
168
|
-
choices: results.map((res) => ({
|
|
169
|
-
name: getTitle(res === null || res === void 0 ? void 0 : res.title)
|
|
174
|
+
choices: results.map((res, idx) => ({
|
|
175
|
+
name: `[${idx + 1}] ${getTitle(res === null || res === void 0 ? void 0 : res.title)}`,
|
|
170
176
|
value: res === null || res === void 0 ? void 0 : res.id,
|
|
171
177
|
})),
|
|
178
|
+
pageSize: 10,
|
|
172
179
|
},
|
|
173
180
|
]);
|
|
174
181
|
// Options to save to the list
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
declare const addAnimeToListMutation = "\nmutation($mediaId: Int, $status: MediaListStatus) {\n SaveMediaListEntry(mediaId: $mediaId, status: $status) { id status }\n}\n";
|
|
2
|
-
declare const addMangaToListMutation = "\n mutation($mediaId: Int, $status: MediaListStatus) {\n SaveMediaListEntry(mediaId: $mediaId, status: $status) {\n id\n status\n media { title { romaji english } }\n }\n }\n";
|
|
2
|
+
declare const addMangaToListMutation = "\n mutation($mediaId: Int, $status: MediaListStatus) {\n SaveMediaListEntry(mediaId: $mediaId, status: $status) {\n id\n status\n media { id title { romaji english } }\n }\n }\n";
|
|
3
3
|
declare const deleteActivityMutation = "\nmutation($id: Int!) {\n DeleteActivity(id: $id) { deleted }\n}\n";
|
|
4
4
|
export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, };
|
package/bin/helpers/mutations.js
CHANGED
package/bin/helpers/queries.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare const trendingQuery = "query ($page: Int, $perPage: Int) {\n Page(page:
|
|
|
3
3
|
declare const popularQuery = "query ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n media(sort: POPULARITY_DESC, type: ANIME) { id title { romaji english } }\n }\n}";
|
|
4
4
|
declare const userQuery = "query ($username: String) {\n User(name: $username) {\n id name siteUrl donatorTier donatorBadge createdAt updatedAt previousNames { name createdAt updatedAt }\n isBlocked isFollower isFollowing options { profileColor timezone activityMergeTime }\n statistics { anime { count episodesWatched minutesWatched } manga { count chaptersRead volumesRead } }\n }\n}";
|
|
5
5
|
declare const currentUserAnimeList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: ANIME) {\n lists { name entries { id media { id title { romaji english } } } }\n }\n}";
|
|
6
|
-
declare const currentUserMangaList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: MANGA) {\n lists {
|
|
6
|
+
declare const currentUserMangaList = "query ($id: Int) {\n MediaListCollection(userId: $id, type: MANGA) {\n lists {\n name\n entries {\n id\n media {\n id\n title {\n romaji\n english\n }\n }\n }\n }\n }\n}\n";
|
|
7
7
|
declare const deleteMediaEntryMutation = "mutation($id: Int!) {\n DeleteMediaListEntry(id: $id) { deleted }\n}";
|
|
8
8
|
declare const deleteMangaEntryMutation = "mutation ($id: Int) {\n DeleteMediaListEntry(id: $id) { deleted }\n}";
|
|
9
9
|
declare const upcomingAnimesQuery = "query GetNextSeasonAnime($nextSeason: MediaSeason, $nextYear: Int, $perPage: Int) {\n Page(perPage: $perPage) {\n media(season: $nextSeason, seasonYear: $nextYear, type: ANIME, sort: POPULARITY_DESC) {\n id title { romaji english native userPreferred } season seasonYear startDate { year month day }\n episodes description genres\n }\n }\n}";
|
package/bin/helpers/queries.js
CHANGED
|
@@ -33,9 +33,22 @@ const currentUserAnimeList = `query ($id: Int) {
|
|
|
33
33
|
}`;
|
|
34
34
|
const currentUserMangaList = `query ($id: Int) {
|
|
35
35
|
MediaListCollection(userId: $id, type: MANGA) {
|
|
36
|
-
lists {
|
|
36
|
+
lists {
|
|
37
|
+
name
|
|
38
|
+
entries {
|
|
39
|
+
id
|
|
40
|
+
media {
|
|
41
|
+
id
|
|
42
|
+
title {
|
|
43
|
+
romaji
|
|
44
|
+
english
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
37
49
|
}
|
|
38
|
-
}
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
39
52
|
const deleteMediaEntryMutation = `mutation($id: Int!) {
|
|
40
53
|
DeleteMediaListEntry(id: $id) { deleted }
|
|
41
54
|
}`;
|
package/bin/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { anilistUserLogin, currentUserInfo, logoutUser, } from "./helpers/auth.j
|
|
|
13
13
|
import { deleteAnimeCollection, deleteMangaCollection, getPopular, getTrending, getUpcomingAnimes, loggedInUsersAnimeLists, loggedInUsersMangaLists, } from "./helpers/lists.js";
|
|
14
14
|
import { getAnimeDetailsByID, getAnimeSearchResults, getMangaSearchResults, deleteUserActivities, getUserInfoByUsername, } from "./helpers/more.js";
|
|
15
15
|
const cli = new Command();
|
|
16
|
-
cli.name("anilist").description("Unofficial AniList CLI").version("1.0.
|
|
16
|
+
cli.name("anilist").description("Unofficial AniList CLI").version("1.0.3");
|
|
17
17
|
cli
|
|
18
18
|
.command("login")
|
|
19
19
|
.description("Login with AniList")
|
|
@@ -50,10 +50,9 @@ cli
|
|
|
50
50
|
yield getPopular(Number(count));
|
|
51
51
|
}));
|
|
52
52
|
cli
|
|
53
|
-
.command("user")
|
|
53
|
+
.command("user <username>")
|
|
54
54
|
.description("Get user information")
|
|
55
|
-
.
|
|
56
|
-
.action((_a) => __awaiter(void 0, [_a], void 0, function* ({ username }) {
|
|
55
|
+
.action((username) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
56
|
yield getUserInfoByUsername(username);
|
|
58
57
|
}));
|
|
59
58
|
cli
|
|
@@ -132,7 +131,7 @@ cli
|
|
|
132
131
|
.description("Search anime or manga.")
|
|
133
132
|
.option("-a, --anime", "To get the anime search results.", false)
|
|
134
133
|
.option("-m, --manga", "To get the manga search results.", false)
|
|
135
|
-
.option("-c, --count", "Number of search results to show.", "10")
|
|
134
|
+
.option("-c, --count <number>", "Number of search results to show.", "10")
|
|
136
135
|
.action((query_1, _a) => __awaiter(void 0, [query_1, _a], void 0, function* (query, { anime, manga, count }) {
|
|
137
136
|
if ((!anime && !manga) || (anime && manga)) {
|
|
138
137
|
console.error(`Must select an option, either --anime or --manga`);
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@irfanshadikrishad/anilist",
|
|
3
3
|
"description": "Unofficial AniList CLI",
|
|
4
4
|
"author": "Irfan Shadik Rishad",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.3",
|
|
6
6
|
"main": "./bin/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"types": "./bin/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"license": "MPL-2.0",
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@types/node": "^22.7.
|
|
32
|
+
"@types/node": "^22.7.6",
|
|
33
33
|
"typescript": "^5.6.3"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|