@irfanshadikrishad/anilist 1.2.0-forbidden.1 → 1.2.1-forbidden.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +382 -382
- package/README.md +255 -245
- package/bin/helpers/auth.d.ts +48 -8
- package/bin/helpers/auth.js +415 -259
- package/bin/helpers/fetcher.d.ts +1 -1
- package/bin/helpers/lists.d.ts +5 -2
- package/bin/helpers/lists.js +317 -246
- package/bin/helpers/mutations.js +35 -35
- package/bin/helpers/queries.d.ts +7 -4
- package/bin/helpers/queries.js +173 -154
- package/bin/helpers/types.d.ts +349 -8
- package/bin/helpers/validation.d.ts +29 -0
- package/bin/helpers/validation.js +117 -0
- package/bin/helpers/workers.d.ts +8 -5
- package/bin/helpers/workers.js +155 -72
- package/bin/index.js +36 -5
- package/package.json +84 -80
- package/assets/binance.jpg +0 -0
package/bin/helpers/workers.js
CHANGED
|
@@ -17,7 +17,9 @@ import { homedir } from "os";
|
|
|
17
17
|
import { join } from "path";
|
|
18
18
|
import process from "process";
|
|
19
19
|
import { Auth } from "./auth.js";
|
|
20
|
-
import {
|
|
20
|
+
import { fetcher } from "./fetcher.js";
|
|
21
|
+
import { animeSearchQuery } from "./queries.js";
|
|
22
|
+
import { MALAnimeStatus, MALMangaStatus, } from "./types.js";
|
|
21
23
|
const aniListEndpoint = `https://graphql.anilist.co`;
|
|
22
24
|
const redirectUri = "https://anilist.co/api/v2/oauth/pin";
|
|
23
25
|
function getTitle(title) {
|
|
@@ -160,59 +162,60 @@ function selectFile(fileType) {
|
|
|
160
162
|
return answers.fileName;
|
|
161
163
|
}
|
|
162
164
|
else {
|
|
163
|
-
|
|
165
|
+
console.error(`\nNo importable ${fileType} file(s) found in download folder.`);
|
|
166
|
+
return null;
|
|
164
167
|
}
|
|
165
168
|
}
|
|
166
169
|
catch (error) {
|
|
167
170
|
console.error("\nError selecting file:", error);
|
|
168
|
-
|
|
171
|
+
return null;
|
|
169
172
|
}
|
|
170
173
|
});
|
|
171
174
|
}
|
|
172
175
|
function createAnimeXML(malId, progress, status, episodes, title) {
|
|
173
|
-
return `
|
|
174
|
-
<anime>
|
|
175
|
-
<series_animedb_id>${malId}</series_animedb_id>
|
|
176
|
-
<series_title><![CDATA[${title}]]></series_title>
|
|
177
|
-
<series_type>""</series_type>
|
|
178
|
-
<series_episodes>${episodes}</series_episodes>
|
|
179
|
-
<my_id>0</my_id>
|
|
180
|
-
<my_watched_episodes>${progress}</my_watched_episodes>
|
|
181
|
-
<my_start_date>0000-00-00</my_start_date>
|
|
182
|
-
<my_finish_date>0000-00-00</my_finish_date>
|
|
183
|
-
<my_score>0</my_score>
|
|
184
|
-
<my_storage_value>0.00</my_storage_value>
|
|
185
|
-
<my_status>${status}</my_status>
|
|
186
|
-
<my_comments><![CDATA[]]></my_comments>
|
|
187
|
-
<my_times_watched>0</my_times_watched>
|
|
188
|
-
<my_rewatch_value></my_rewatch_value>
|
|
189
|
-
<my_priority>LOW</my_priority>
|
|
190
|
-
<my_tags><![CDATA[]]></my_tags>
|
|
191
|
-
<my_rewatching>0</my_rewatching>
|
|
192
|
-
<my_rewatching_ep>0</my_rewatching_ep>
|
|
193
|
-
<my_discuss>0</my_discuss>
|
|
194
|
-
<my_sns>default</my_sns>
|
|
195
|
-
<update_on_import>1</update_on_import>
|
|
176
|
+
return `
|
|
177
|
+
<anime>
|
|
178
|
+
<series_animedb_id>${malId}</series_animedb_id>
|
|
179
|
+
<series_title><![CDATA[${title}]]></series_title>
|
|
180
|
+
<series_type>""</series_type>
|
|
181
|
+
<series_episodes>${episodes}</series_episodes>
|
|
182
|
+
<my_id>0</my_id>
|
|
183
|
+
<my_watched_episodes>${progress}</my_watched_episodes>
|
|
184
|
+
<my_start_date>0000-00-00</my_start_date>
|
|
185
|
+
<my_finish_date>0000-00-00</my_finish_date>
|
|
186
|
+
<my_score>0</my_score>
|
|
187
|
+
<my_storage_value>0.00</my_storage_value>
|
|
188
|
+
<my_status>${status}</my_status>
|
|
189
|
+
<my_comments><![CDATA[]]></my_comments>
|
|
190
|
+
<my_times_watched>0</my_times_watched>
|
|
191
|
+
<my_rewatch_value></my_rewatch_value>
|
|
192
|
+
<my_priority>LOW</my_priority>
|
|
193
|
+
<my_tags><![CDATA[]]></my_tags>
|
|
194
|
+
<my_rewatching>0</my_rewatching>
|
|
195
|
+
<my_rewatching_ep>0</my_rewatching_ep>
|
|
196
|
+
<my_discuss>0</my_discuss>
|
|
197
|
+
<my_sns>default</my_sns>
|
|
198
|
+
<update_on_import>1</update_on_import>
|
|
196
199
|
</anime>`;
|
|
197
200
|
}
|
|
198
201
|
function createMangaXML(malId, progress, status, chapters, title) {
|
|
199
|
-
return `
|
|
200
|
-
<manga>
|
|
201
|
-
<manga_mangadb_id>${malId}</manga_mangadb_id>
|
|
202
|
-
<manga_title><![CDATA[${title ? title : "unknown"}]]></manga_title>
|
|
203
|
-
<manga_volumes>0</manga_volumes>
|
|
204
|
-
<manga_chapters>${chapters ? chapters : 0}</manga_chapters>
|
|
205
|
-
<my_id>0</my_id>
|
|
206
|
-
<my_read_chapters>${progress}</my_read_chapters>
|
|
207
|
-
<my_start_date>0000-00-00</my_start_date>
|
|
208
|
-
<my_finish_date>0000-00-00</my_finish_date>
|
|
209
|
-
<my_score>0</my_score>
|
|
210
|
-
<my_status>${status}</my_status>
|
|
211
|
-
<my_reread_value></my_reread_value>
|
|
212
|
-
<my_priority>LOW</my_priority>
|
|
213
|
-
<my_rereading>0</my_rereading>
|
|
214
|
-
<my_discuss>0</my_discuss>
|
|
215
|
-
<update_on_import>1</update_on_import>
|
|
202
|
+
return `
|
|
203
|
+
<manga>
|
|
204
|
+
<manga_mangadb_id>${malId}</manga_mangadb_id>
|
|
205
|
+
<manga_title><![CDATA[${title ? title : "unknown"}]]></manga_title>
|
|
206
|
+
<manga_volumes>0</manga_volumes>
|
|
207
|
+
<manga_chapters>${chapters ? chapters : 0}</manga_chapters>
|
|
208
|
+
<my_id>0</my_id>
|
|
209
|
+
<my_read_chapters>${progress}</my_read_chapters>
|
|
210
|
+
<my_start_date>0000-00-00</my_start_date>
|
|
211
|
+
<my_finish_date>0000-00-00</my_finish_date>
|
|
212
|
+
<my_score>0</my_score>
|
|
213
|
+
<my_status>${status}</my_status>
|
|
214
|
+
<my_reread_value></my_reread_value>
|
|
215
|
+
<my_priority>LOW</my_priority>
|
|
216
|
+
<my_rereading>0</my_rereading>
|
|
217
|
+
<my_discuss>0</my_discuss>
|
|
218
|
+
<update_on_import>1</update_on_import>
|
|
216
219
|
</manga>`;
|
|
217
220
|
}
|
|
218
221
|
function createAnimeListXML(mediaWithProgress) {
|
|
@@ -224,7 +227,9 @@ function createAnimeListXML(mediaWithProgress) {
|
|
|
224
227
|
PAUSED: MALAnimeStatus.ON_HOLD,
|
|
225
228
|
DROPPED: MALAnimeStatus.DROPPED,
|
|
226
229
|
};
|
|
227
|
-
|
|
230
|
+
// Filter out anime without malId
|
|
231
|
+
const filteredMedia = mediaWithProgress.filter((anime) => anime.malId);
|
|
232
|
+
const xmlEntries = filteredMedia.map((anime) => {
|
|
228
233
|
const malId = anime.malId;
|
|
229
234
|
const progress = anime.progress;
|
|
230
235
|
const episodes = anime.episodes;
|
|
@@ -232,19 +237,19 @@ function createAnimeListXML(mediaWithProgress) {
|
|
|
232
237
|
const status = statusMap[anime.status];
|
|
233
238
|
return createAnimeXML(malId, progress, status, episodes, title);
|
|
234
239
|
});
|
|
235
|
-
return `<myanimelist>
|
|
236
|
-
<myinfo>
|
|
237
|
-
<user_id/>
|
|
238
|
-
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
239
|
-
<user_export_type>1</user_export_type>
|
|
240
|
-
<user_total_anime>0</user_total_anime>
|
|
241
|
-
<user_total_watching>0</user_total_watching>
|
|
242
|
-
<user_total_completed>0</user_total_completed>
|
|
243
|
-
<user_total_onhold>0</user_total_onhold>
|
|
244
|
-
<user_total_dropped>0</user_total_dropped>
|
|
245
|
-
<user_total_plantowatch>0</user_total_plantowatch>
|
|
246
|
-
</myinfo>
|
|
247
|
-
\n${xmlEntries.join("\n")}\n
|
|
240
|
+
return `<myanimelist>
|
|
241
|
+
<myinfo>
|
|
242
|
+
<user_id/>
|
|
243
|
+
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
244
|
+
<user_export_type>1</user_export_type>
|
|
245
|
+
<user_total_anime>0</user_total_anime>
|
|
246
|
+
<user_total_watching>0</user_total_watching>
|
|
247
|
+
<user_total_completed>0</user_total_completed>
|
|
248
|
+
<user_total_onhold>0</user_total_onhold>
|
|
249
|
+
<user_total_dropped>0</user_total_dropped>
|
|
250
|
+
<user_total_plantowatch>0</user_total_plantowatch>
|
|
251
|
+
</myinfo>
|
|
252
|
+
\n${xmlEntries.join("\n")}\n
|
|
248
253
|
</myanimelist>`;
|
|
249
254
|
});
|
|
250
255
|
}
|
|
@@ -257,7 +262,9 @@ function createMangaListXML(mediaWithProgress) {
|
|
|
257
262
|
PAUSED: MALMangaStatus.ON_HOLD,
|
|
258
263
|
DROPPED: MALMangaStatus.DROPPED,
|
|
259
264
|
};
|
|
260
|
-
|
|
265
|
+
// Filter out manga without malId
|
|
266
|
+
const filteredMedia = mediaWithProgress.filter((manga) => manga.malId);
|
|
267
|
+
const xmlEntries = filteredMedia.map((manga) => {
|
|
261
268
|
const malId = manga.malId;
|
|
262
269
|
const progress = manga.progress;
|
|
263
270
|
const chapters = manga.chapters;
|
|
@@ -265,19 +272,19 @@ function createMangaListXML(mediaWithProgress) {
|
|
|
265
272
|
const status = statusMap[manga.status];
|
|
266
273
|
return createMangaXML(malId, progress, status, chapters, title);
|
|
267
274
|
});
|
|
268
|
-
return `<myanimelist>
|
|
269
|
-
<myinfo>
|
|
270
|
-
<user_id/>
|
|
271
|
-
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
272
|
-
<user_export_type>2</user_export_type>
|
|
273
|
-
<user_total_manga>5</user_total_manga>
|
|
274
|
-
<user_total_reading>1</user_total_reading>
|
|
275
|
-
<user_total_completed>1</user_total_completed>
|
|
276
|
-
<user_total_onhold>1</user_total_onhold>
|
|
277
|
-
<user_total_dropped>1</user_total_dropped>
|
|
278
|
-
<user_total_plantoread>1</user_total_plantoread>
|
|
279
|
-
</myinfo>
|
|
280
|
-
\n${xmlEntries.join("\n")}\n
|
|
275
|
+
return `<myanimelist>
|
|
276
|
+
<myinfo>
|
|
277
|
+
<user_id/>
|
|
278
|
+
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
279
|
+
<user_export_type>2</user_export_type>
|
|
280
|
+
<user_total_manga>5</user_total_manga>
|
|
281
|
+
<user_total_reading>1</user_total_reading>
|
|
282
|
+
<user_total_completed>1</user_total_completed>
|
|
283
|
+
<user_total_onhold>1</user_total_onhold>
|
|
284
|
+
<user_total_dropped>1</user_total_dropped>
|
|
285
|
+
<user_total_plantoread>1</user_total_plantoread>
|
|
286
|
+
</myinfo>
|
|
287
|
+
\n${xmlEntries.join("\n")}\n
|
|
281
288
|
</myanimelist>`;
|
|
282
289
|
});
|
|
283
290
|
}
|
|
@@ -287,4 +294,80 @@ function getCurrentPackageVersion() {
|
|
|
287
294
|
const version = packageJson.version;
|
|
288
295
|
return version || null;
|
|
289
296
|
}
|
|
290
|
-
|
|
297
|
+
function timestampToTimeAgo(timestamp) {
|
|
298
|
+
const now = Math.floor(Date.now() / 1000);
|
|
299
|
+
const elapsed = now - timestamp;
|
|
300
|
+
if (elapsed < 60) {
|
|
301
|
+
return `${elapsed} second${elapsed === 1 ? "" : "s"} ago`;
|
|
302
|
+
}
|
|
303
|
+
else if (elapsed < 3600) {
|
|
304
|
+
const minutes = Math.floor(elapsed / 60);
|
|
305
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
306
|
+
}
|
|
307
|
+
else if (elapsed < 86400) {
|
|
308
|
+
const hours = Math.floor(elapsed / 3600);
|
|
309
|
+
return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
310
|
+
}
|
|
311
|
+
else if (elapsed < 2592000) {
|
|
312
|
+
const days = Math.floor(elapsed / 86400);
|
|
313
|
+
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
314
|
+
}
|
|
315
|
+
else if (elapsed < 31536000) {
|
|
316
|
+
const months = Math.floor(elapsed / 2592000);
|
|
317
|
+
return `${months} month${months === 1 ? "" : "s"} ago`;
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
const years = Math.floor(elapsed / 31536000);
|
|
321
|
+
return `${years} year${years === 1 ? "" : "s"} ago`;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function activityBy(activity) {
|
|
325
|
+
var _a, _b, _c, _d;
|
|
326
|
+
if ((_a = activity === null || activity === void 0 ? void 0 : activity.messenger) === null || _a === void 0 ? void 0 : _a.name) {
|
|
327
|
+
return `[${activity.id}]\t${activity.messenger.name} messaged ${activity.recipient.name}`;
|
|
328
|
+
}
|
|
329
|
+
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) {
|
|
330
|
+
if (activity.progress) {
|
|
331
|
+
return `[${activity.id}]\t${activity.user.name} ${activity.status} ${activity.progress} of ${activity.media.title.userPreferred}`;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
return `[${activity.id}]\t${activity.user.name} ${activity.status} ${activity.media.title.userPreferred}`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
else if ((_d = activity === null || activity === void 0 ? void 0 : activity.user) === null || _d === void 0 ? void 0 : _d.name) {
|
|
338
|
+
return `[${activity.id}]\t${activity.user.name}`;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
return `[${activity === null || activity === void 0 ? void 0 : activity.id}] ???`;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const anidbToanilistMapper = (romanjiName, year, englishName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
345
|
+
const fetchAnime = (search) => __awaiter(void 0, void 0, void 0, function* () {
|
|
346
|
+
var _a;
|
|
347
|
+
try {
|
|
348
|
+
const response = yield fetcher(animeSearchQuery, {
|
|
349
|
+
search,
|
|
350
|
+
perPage: 50,
|
|
351
|
+
});
|
|
352
|
+
return ((_a = response.data) === null || _a === void 0 ? void 0 : _a.Page.media) || [];
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
console.error("Error fetching AniList data:", error);
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
// Search using romanjiName first
|
|
360
|
+
let results = yield fetchAnime(romanjiName);
|
|
361
|
+
// If no results, fallback to englishName
|
|
362
|
+
if (!results.length && englishName) {
|
|
363
|
+
results = yield fetchAnime(englishName);
|
|
364
|
+
}
|
|
365
|
+
// Match using year
|
|
366
|
+
for (const anime of results) {
|
|
367
|
+
if (anime.startDate.year === year) {
|
|
368
|
+
return anime.id;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return null;
|
|
372
|
+
});
|
|
373
|
+
export { activityBy, anidbToanilistMapper, aniListEndpoint, createAnimeListXML, createAnimeXML, createMangaListXML, createMangaXML, formatDateObject, getCurrentPackageVersion, getDownloadFolderPath, getFormattedDate, getNextSeasonAndYear, getTitle, redirectUri, removeHtmlAndMarkdown, saveJSONasCSV, saveJSONasJSON, selectFile, timestampToTimeAgo, };
|
package/bin/index.js
CHANGED
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
import { Command } from "commander";
|
|
12
12
|
import process from "process";
|
|
13
|
-
import { Auth } from "./helpers/auth.js";
|
|
13
|
+
import { Auth, Social } from "./helpers/auth.js";
|
|
14
14
|
import { AniList } from "./helpers/lists.js";
|
|
15
15
|
import { getCurrentPackageVersion } from "./helpers/workers.js";
|
|
16
16
|
const cli = new Command();
|
|
@@ -32,7 +32,7 @@ cli
|
|
|
32
32
|
}
|
|
33
33
|
}));
|
|
34
34
|
cli
|
|
35
|
-
.command("
|
|
35
|
+
.command("whoami")
|
|
36
36
|
.description("Get details of the logged in user")
|
|
37
37
|
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
38
|
yield Auth.Myself();
|
|
@@ -88,7 +88,7 @@ cli
|
|
|
88
88
|
.description("Delete entire collections of anime or manga")
|
|
89
89
|
.option("-a, --anime", "For anime list of authenticated user", false)
|
|
90
90
|
.option("-m, --manga", "For manga list of authenticated user", false)
|
|
91
|
-
.option("-
|
|
91
|
+
.option("-s, --activity", "For activity of authenticated user", false)
|
|
92
92
|
.action((_a) => __awaiter(void 0, [_a], void 0, function* ({ anime, manga, activity }) {
|
|
93
93
|
const selectedOptions = [anime, manga, activity].filter(Boolean).length;
|
|
94
94
|
if (selectedOptions === 0) {
|
|
@@ -206,8 +206,39 @@ cli
|
|
|
206
206
|
cli
|
|
207
207
|
.command("autolike")
|
|
208
208
|
.alias("al")
|
|
209
|
+
.option("-2, --v2", "Like the activities", false)
|
|
210
|
+
.option("-c, --count <number>", "Number of activities to like", "25")
|
|
209
211
|
.description("Autolike following or global activities.")
|
|
210
|
-
.action(() => __awaiter(void 0,
|
|
211
|
-
|
|
212
|
+
.action((_a) => __awaiter(void 0, [_a], void 0, function* ({ v2, count }) {
|
|
213
|
+
if (v2) {
|
|
214
|
+
yield Auth.LikeFollowingActivityV2(count);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
yield Auth.AutoLike();
|
|
218
|
+
}
|
|
219
|
+
}));
|
|
220
|
+
cli
|
|
221
|
+
.command("social")
|
|
222
|
+
.alias("sol")
|
|
223
|
+
.description("Automate your process")
|
|
224
|
+
.option("-f, --follow", "Follow the user whos following you.", false)
|
|
225
|
+
.option("-u, --unfollow", "Unfollow the user whos not following you.", false)
|
|
226
|
+
.action((_a) => __awaiter(void 0, [_a], void 0, function* ({ follow, unfollow }) {
|
|
227
|
+
if (!follow && !unfollow) {
|
|
228
|
+
console.error(`\nMust select an option, either --follow or --unfollow`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
if (yield Auth.isLoggedIn()) {
|
|
232
|
+
if (follow) {
|
|
233
|
+
yield Social.follow();
|
|
234
|
+
}
|
|
235
|
+
else if (unfollow) {
|
|
236
|
+
yield Social.unfollow();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
console.error(`\nPlease login to use this feature.`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
212
243
|
}));
|
|
213
244
|
cli.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,80 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@irfanshadikrishad/anilist",
|
|
3
|
-
"description": "Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts",
|
|
4
|
-
"author": "Irfan Shadik Rishad",
|
|
5
|
-
"version": "1.2.
|
|
6
|
-
"main": "./bin/index.js",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"types": "./bin/index.d.ts",
|
|
9
|
-
"bin": {
|
|
10
|
-
"anilist": "./bin/index.js"
|
|
11
|
-
},
|
|
12
|
-
"publishConfig": {
|
|
13
|
-
"access": "public"
|
|
14
|
-
},
|
|
15
|
-
"scripts": {
|
|
16
|
-
"build": "rm -rf ./bin && tsc",
|
|
17
|
-
"buildw": "rm -rf ./bin && tsc -w",
|
|
18
|
-
"format": "prettier . --write",
|
|
19
|
-
"format:check": "prettier . --check",
|
|
20
|
-
"lint": "eslint ./dist",
|
|
21
|
-
"lint:fix": "eslint ./dist --fix",
|
|
22
|
-
"all": "npm run lint && npm run lint:fix && npm run format",
|
|
23
|
-
"test": "jest ./tests"
|
|
24
|
-
},
|
|
25
|
-
"keywords": [
|
|
26
|
-
"anilist",
|
|
27
|
-
"CLI",
|
|
28
|
-
"anime",
|
|
29
|
-
"manga",
|
|
30
|
-
"anime list",
|
|
31
|
-
"manga list",
|
|
32
|
-
"anime tracker",
|
|
33
|
-
"manga tracker",
|
|
34
|
-
"anilist API",
|
|
35
|
-
"anime progress",
|
|
36
|
-
"manga progress",
|
|
37
|
-
"media list",
|
|
38
|
-
"export anime",
|
|
39
|
-
"import anime",
|
|
40
|
-
"export manga",
|
|
41
|
-
"import manga",
|
|
42
|
-
"status tracker",
|
|
43
|
-
"watchlist",
|
|
44
|
-
"reading list",
|
|
45
|
-
"graphql"
|
|
46
|
-
],
|
|
47
|
-
"repository": {
|
|
48
|
-
"type": "git",
|
|
49
|
-
"url": "https://github.com/irfanshadikrishad/anilist"
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://github.com/irfanshadikrishad/anilist",
|
|
52
|
-
"bugs": {
|
|
53
|
-
"url": "https://github.com/irfanshadikrishad/anilist/issues"
|
|
54
|
-
},
|
|
55
|
-
"license": "MPL-2.0",
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"@types/
|
|
60
|
-
"@types/
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@irfanshadikrishad/anilist",
|
|
3
|
+
"description": "Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts",
|
|
4
|
+
"author": "Irfan Shadik Rishad",
|
|
5
|
+
"version": "1.2.1-forbidden.2",
|
|
6
|
+
"main": "./bin/index.js",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"types": "./bin/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"anilist": "./bin/index.js"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "rm -rf ./bin && tsc",
|
|
17
|
+
"buildw": "rm -rf ./bin && tsc -w",
|
|
18
|
+
"format": "prettier . --write",
|
|
19
|
+
"format:check": "prettier . --check",
|
|
20
|
+
"lint": "eslint ./dist",
|
|
21
|
+
"lint:fix": "eslint ./dist --fix",
|
|
22
|
+
"all": "npm run build && npm run lint && npm run lint:fix && npm run format && npm test",
|
|
23
|
+
"test": "jest ./tests"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"anilist",
|
|
27
|
+
"CLI",
|
|
28
|
+
"anime",
|
|
29
|
+
"manga",
|
|
30
|
+
"anime list",
|
|
31
|
+
"manga list",
|
|
32
|
+
"anime tracker",
|
|
33
|
+
"manga tracker",
|
|
34
|
+
"anilist API",
|
|
35
|
+
"anime progress",
|
|
36
|
+
"manga progress",
|
|
37
|
+
"media list",
|
|
38
|
+
"export anime",
|
|
39
|
+
"import anime",
|
|
40
|
+
"export manga",
|
|
41
|
+
"import manga",
|
|
42
|
+
"status tracker",
|
|
43
|
+
"watchlist",
|
|
44
|
+
"reading list",
|
|
45
|
+
"graphql"
|
|
46
|
+
],
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/irfanshadikrishad/anilist"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/irfanshadikrishad/anilist",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/irfanshadikrishad/anilist/issues"
|
|
54
|
+
},
|
|
55
|
+
"license": "MPL-2.0",
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@babel/preset-env": "^7.26.0",
|
|
58
|
+
"@eslint/js": "^9.18.0",
|
|
59
|
+
"@types/jest": "^29.5.14",
|
|
60
|
+
"@types/json2csv": "^5.0.7",
|
|
61
|
+
"@types/node": "^22.10.7",
|
|
62
|
+
"@types/xml2js": "^0.4.14",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
64
|
+
"eslint": "^9.18.0",
|
|
65
|
+
"globals": "^15.14.0",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"prettier": "^3.4.2",
|
|
68
|
+
"prettier-plugin-organize-imports": "^4.1.0",
|
|
69
|
+
"ts-jest": "^29.2.5",
|
|
70
|
+
"ts-node": "^10.9.2",
|
|
71
|
+
"typescript": "^5.7.3"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"commander": "^13.0.0",
|
|
75
|
+
"fast-xml-parser": "^4.5.1",
|
|
76
|
+
"inquirer": "^12.3.2",
|
|
77
|
+
"json2csv": "^6.0.0-alpha.2",
|
|
78
|
+
"jsonrepair": "^3.11.2",
|
|
79
|
+
"node-fetch": "^3.3.2",
|
|
80
|
+
"open": "^10.1.0",
|
|
81
|
+
"tiny-spinner": "^2.0.4",
|
|
82
|
+
"xml2js": "^0.6.2"
|
|
83
|
+
}
|
|
84
|
+
}
|
package/assets/binance.jpg
DELETED
|
Binary file
|