@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 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`** | `-un (username)` | Get information about a specific AniList 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`** | `anime Id` | Get anime details by Anime Id |
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
- - `-un (username)`: Specify the AniList username to fetch.
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
- - `anime Id` _(eg: 21)_ : Id of the anime you want to get details of.
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.
@@ -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
- const { selectedList } = yield inquirer.prompt([
191
- {
192
- type: "list",
193
- name: "selectedList",
194
- message: "Select an anime list:",
195
- choices: lists.map((list) => list.name),
196
- },
197
- ]);
198
- const selectedEntries = lists.find((list) => list.name === selectedList);
199
- if (selectedEntries) {
200
- console.log(`\nEntries for '${selectedEntries.name}':`);
201
- selectedEntries.entries.forEach((entry, idx) => {
202
- var _a;
203
- console.log(`${idx + 1}. ${getTitle((_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.title)}`);
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("No entries found.");
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. ${(_c = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _c === void 0 ? void 0 : _c.message}`);
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
- "content-type": "application/json",
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 = (_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;
249
- const { selectedList } = yield inquirer.prompt([
250
- {
251
- type: "list",
252
- name: "selectedList",
253
- message: "Select a manga list:",
254
- choices: lists.map((list) => list.name),
255
- },
256
- ]);
257
- const selectedEntries = lists.find((list) => list.name === selectedList);
258
- if (selectedEntries) {
259
- console.log(`\nEntries for '${selectedEntries.name}':`);
260
- selectedEntries.entries.forEach((entry, idx) => {
261
- var _a;
262
- console.log(`${idx + 1}. ${getTitle((_a = entry === null || entry === void 0 ? void 0 : entry.media) === null || _a === void 0 ? void 0 : _a.title)}`);
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("No entries found.");
380
+ console.log("\nYou don't seem to have any manga in your lists.");
267
381
  }
268
382
  }
269
383
  else {
270
- console.log(`Something went wrong. ${(_c = response === null || response === void 0 ? void 0 : response.errors[0]) === null || _c === void 0 ? void 0 : _c.message}`);
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.log(`Failed getting current user Id.`);
388
+ console.error(`Failed to get the current user ID.`);
275
389
  }
276
390
  }
277
391
  else {
278
- console.log(`Please log in first.`);
392
+ console.error("Please log in first.");
279
393
  }
280
394
  }
281
395
  catch (error) {
282
- console.log(`Something went wrong. ${error.message}`);
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
- const { selectedList } = yield inquirer.prompt([
308
- {
309
- type: "list",
310
- name: "selectedList",
311
- message: "Select an anime list:",
312
- choices: lists.map((list) => list.name),
313
- },
314
- ]);
315
- const selectedEntries = lists.find((list) => list.name === selectedList);
316
- if (selectedEntries) {
317
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
318
- for (const [idx, entry] of selectedEntries.entries.entries()) {
319
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
320
- 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);
321
- yield new Promise((resolve) => setTimeout(resolve, 2000));
322
- }
323
- else {
324
- console.log(`No id in entry.`);
325
- console.log(entry);
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("No entries found.");
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
- const { selectedList } = yield inquirer.prompt([
398
- {
399
- type: "list",
400
- name: "selectedList",
401
- message: "Select a manga list:",
402
- choices: lists.map((list) => list.name),
403
- },
404
- ]);
405
- const selectedEntries = lists.find((list) => list.name === selectedList);
406
- if (selectedEntries) {
407
- console.log(`\nDeleting entries of '${selectedEntries.name}':`);
408
- for (const [idx, entry] of selectedEntries.entries.entries()) {
409
- if (entry === null || entry === void 0 ? void 0 : entry.id) {
410
- 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);
411
- yield new Promise((resolve) => setTimeout(resolve, 2000));
412
- }
413
- else {
414
- console.log(`No id in entry.`);
415
- console.log(entry);
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("No entries found.");
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
@@ -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
- const { selectedList } = yield inquirer.prompt([
109
- {
110
- type: "list",
111
- name: "selectedList",
112
- message: "Select anime to add to your list:",
113
- choices: results.map((res, idx) => ({
114
- name: getTitle(res === null || res === void 0 ? void 0 : res.title),
115
- value: res === null || res === void 0 ? void 0 : res.id,
116
- })),
117
- },
118
- ]);
119
- // Where to save
120
- const { selectedListType } = yield inquirer.prompt([
121
- {
122
- type: "list",
123
- name: "selectedListType",
124
- message: "Select the list where you want to save this anime:",
125
- choices: [
126
- { name: "Planning", value: "PLANNING" },
127
- { name: "Watching", value: "CURRENT" },
128
- { name: "Completed", value: "COMPLETED" },
129
- { name: "Paused", value: "PAUSED" },
130
- { name: "Dropped", value: "DROPPED" },
131
- ],
132
- },
133
- ]);
134
- // Lets save to the list now
135
- const ISLOGGEDIN = yield isLoggedIn();
136
- if (ISLOGGEDIN) {
137
- const query = addAnimeToListMutation;
138
- const variables = { mediaId: selectedList, status: selectedListType };
139
- const response = yield fetcher(query, variables);
140
- if (response) {
141
- const saved = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.SaveMediaListEntry;
142
- console.log(`\nEntry ${saved === null || saved === void 0 ? void 0 : saved.id}. Saved as ${saved === null || saved === void 0 ? void 0 : saved.status}.`);
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.error(`Please log in first to use this feature.`);
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, };
@@ -8,7 +8,7 @@ const addMangaToListMutation = `
8
8
  SaveMediaListEntry(mediaId: $mediaId, status: $status) {
9
9
  id
10
10
  status
11
- media { title { romaji english } }
11
+ media { id title { romaji english } }
12
12
  }
13
13
  }
14
14
  `;
@@ -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 { name entries { id media { title { romaji english } } } }\n }\n}";
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}";
@@ -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 { name entries { id media { title { romaji english } } } }
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.1");
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
- .requiredOption("-un, --username <string>", "null")
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.2",
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.5",
32
+ "@types/node": "^22.7.6",
33
33
  "typescript": "^5.6.3"
34
34
  },
35
35
  "dependencies": {