@irfanshadikrishad/anilist 1.0.9 → 1.1.0-forbidden.0
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 +232 -232
- package/bin/helpers/auth.d.ts +3 -0
- package/bin/helpers/auth.js +179 -25
- package/bin/helpers/fetcher.d.ts +1 -1
- package/bin/helpers/fetcher.js +24 -23
- package/bin/helpers/mutations.d.ts +2 -1
- package/bin/helpers/mutations.js +6 -1
- package/bin/helpers/queries.d.ts +6 -3
- package/bin/helpers/queries.js +35 -6
- package/bin/helpers/workers.js +66 -66
- package/bin/index.js +8 -1
- package/package.json +73 -73
package/README.md
CHANGED
|
@@ -1,232 +1,232 @@
|
|
|
1
|
-
#### @irfanshadikrishad/anilist
|
|
2
|
-
|
|
3
|
-
Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts.
|
|
4
|
-
|
|
5
|
-
#### How to install?
|
|
6
|
-
|
|
7
|
-
Make sure [Node.js](https://nodejs.org/en) and [npm](https://www.npmjs.com) are already installed in your system.
|
|
8
|
-
Verify installation using
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
node -v
|
|
12
|
-
npm -v
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
If you see the version then its installed. Otherwise install nodejs and npm should already be installed with nodejs.
|
|
16
|
-
Then install the package by running
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm install -g @irfanshadikrishad/anilist
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
This will install the package globally. And you have to use commands like
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
anilist tr -c 15
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### How to use?
|
|
29
|
-
|
|
30
|
-
Create an API client from [anilist developer setting](https://anilist.co/settings/developer) with an application name and redirect url as `https://anilist.co/api/v2/oauth/pin`. After creating the client you will get `Client ID` and `Client Secret` which is required in order to login from CLI.
|
|
31
|
-
|
|
32
|
-
To login:
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
anilist login -i <client-id> -s <client-secret>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
here `<client-id>` and `<client-secret>` should be replaced by the ones that you recieved from the developer setting.
|
|
39
|
-
|
|
40
|
-
#### CLI Commands Overview
|
|
41
|
-
|
|
42
|
-
| **Command** | **Options** | **Description** |
|
|
43
|
-
| ------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
44
|
-
| **`login`** | `-i, --id` `-s, --secret` | Log in with your AniList credentials |
|
|
45
|
-
| **`logout`** | _None_ | Log out from your AniList account |
|
|
46
|
-
| **`me`** | _None_ | Display information about the logged-in user |
|
|
47
|
-
| **`-V, --version`** | _None_ | Display the current version of the CLI |
|
|
48
|
-
| **`-h, --help`** | _None_ | Display available commands and options |
|
|
49
|
-
| **`trending`** <br> _(alias: `tr`)_ | `-c (default: 10)` | Fetch trending anime (default count is 10) |
|
|
50
|
-
| **`popular`** <br> _(alias: `plr`)_ | `-c (default: 10)` | Fetch popular anime (default count is 10) |
|
|
51
|
-
| **`user`** | `<username>` | Get information about a specific AniList user |
|
|
52
|
-
| **`lists`** <br> _(alias: `ls`)_ | `-a, --anime` <br> `-m, --manga` | Fetch anime or manga lists of the logged-in user |
|
|
53
|
-
| **`delete`** <br> _(alias: `del`)_ | `-a, --anime` <br> `-m, --manga` <br> `-ac, --activity` | Delete collections of anime, manga or activities |
|
|
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 |
|
|
56
|
-
| **`search`** <br> _(alias:`srch`/`find`)_ | `<query>` <br> `-a, --anime` <br> `-m, --manga` <br> `-c (default: 10)` | Get anime/manga search results |
|
|
57
|
-
| **`status`** <br> _(alias: `write`/`post`)_ | `<status>` | Write a status... (text/markdown/html) |
|
|
58
|
-
| **`export`** <br> _(alias: `exp`)_ | `-a, --anime` <br> `-m, --manga` | Export anime or manga list in JSON, CSV or XML (MyAnimeList) |
|
|
59
|
-
| **`import`** <br> _(alias: `imp`)_ | `-a, --anime` <br> `-m, --manga` | Import anime or manga list from exported JSON or MyAnimeList (XML) |
|
|
60
|
-
|
|
61
|
-
#### Command Breakdown:
|
|
62
|
-
|
|
63
|
-
#### `login`:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
anilist login -i <client-id> -s <client-secret>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
- **Options**:
|
|
70
|
-
- `-i, --id`: Specify AniList Client ID
|
|
71
|
-
- `-s, --secret`: Provide the AniList Client Secret
|
|
72
|
-
- **Usage**: Authenticate and log in to AniList using your ID and secret credentials.
|
|
73
|
-
|
|
74
|
-
#### `logout`:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
anilist logout
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
- **Description**: End the current session and log out from your AniList account.
|
|
81
|
-
|
|
82
|
-
#### `me`:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
anilist me
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
- **Description**: Retrieve and display information about the currently logged-in user, including stats and profile details.
|
|
89
|
-
|
|
90
|
-
#### `-V, --version`:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
anilist -V
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
- **Description**: Quickly check which version of the CLI you are running.
|
|
97
|
-
|
|
98
|
-
#### `-h, --help`:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
anilist -h
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
- **Description**: List all available commands and their usage details for quick reference.
|
|
105
|
-
|
|
106
|
-
#### `trending` _(alias: `tr`)_:
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
anilist tr -c 15
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
- **Options**:
|
|
113
|
-
- `-c (count)`: Specify how many trending anime to fetch (default: 10).
|
|
114
|
-
- **Description**: Fetch the current trending anime series, with the option to customize how many results to display.
|
|
115
|
-
|
|
116
|
-
#### `popular` _(alias: `plr`)_:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
anilist popular
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
- **Options**:
|
|
123
|
-
- `-c (count)`: Specify how many popular anime to fetch (default: 10).
|
|
124
|
-
- **Description**: Fetch the most popular anime series, with the option to customize how many results to display.
|
|
125
|
-
|
|
126
|
-
#### `upcoming` _(alias: `up`)_:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
anilist up -c 25
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
- **Options**:
|
|
133
|
-
- `-c (count)`: Specify how many upcoming anime to fetch (default: 10).
|
|
134
|
-
- **Description**: Fetch the upcoming anime series next season, with the option to customize how many results to display.
|
|
135
|
-
|
|
136
|
-
#### `user`:
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
anilist user <username>
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
- **Options**:
|
|
143
|
-
- `<username>`: Specify the AniList username to fetch.
|
|
144
|
-
- **Description**: Retrieve profile information about a specific AniList user.
|
|
145
|
-
|
|
146
|
-
#### `lists` _(alias: `ls`)_:
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
anilist ls -a
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
- **Options**:
|
|
153
|
-
- `-a, --anime`: Fetch the authenticated user's anime list.
|
|
154
|
-
- `-m, --manga`: Fetch the authenticated user's manga list.
|
|
155
|
-
- **Description**: Get the anime or manga lists of the logged-in user.
|
|
156
|
-
|
|
157
|
-
#### `delete` _(alias: `del`)_:
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
anilist del -ac
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
- **Options**:
|
|
164
|
-
- `-a, --anime`: Delete your specific anime collection that you want.
|
|
165
|
-
- `-m, --manga`: Delete your specific manga collection that you want.
|
|
166
|
-
- `-ac, --activity`: Delete all or any type of activities you want.
|
|
167
|
-
- **Description**: Delete the entire anime or manga collection from the logged-in user's profile.
|
|
168
|
-
|
|
169
|
-
#### `anime`
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
anilist anime <anime-id>
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
- **Options**
|
|
176
|
-
- `<anime-id>` _(eg: 21)_ : Id of the anime you want to get details of.
|
|
177
|
-
- **Description**: Get anime details by anime Id.
|
|
178
|
-
|
|
179
|
-
#### `search` _(alias: `srch`/`find`)_:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
anilist search <query> -a -c 20
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
- **Options**:
|
|
186
|
-
- `<query>` : What you want to search (eg: naruto).
|
|
187
|
-
- `-a, --anime`: To get results of anime search.
|
|
188
|
-
- `-m, --manga`: To get results of manga search.
|
|
189
|
-
- `-c (count)`: Specify how many items to fetch (default: 10).
|
|
190
|
-
- **Description**: Get anime/manga search results
|
|
191
|
-
|
|
192
|
-
#### `status` _(alias: `write`/`post`)_:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
anilist write <status>
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
- **Options**:
|
|
199
|
-
- `<status>` : This is what you want to write, It can be HTML, Markdown and/or Text. But wrap it with quotation mark (") else it might get cut-off.
|
|
200
|
-
- **Description**: Get anime/manga search results
|
|
201
|
-
|
|
202
|
-
#### `export` _(alias: `exp`)_:
|
|
203
|
-
|
|
204
|
-
```bash
|
|
205
|
-
anilist export -a
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
- **Options**:
|
|
209
|
-
- `-a, --anime`: To export anime list.
|
|
210
|
-
- `-m, --manga`: To export manga list.
|
|
211
|
-
- **Description**: Export anime or manga list. For `XML (MyAnimeList)` file, to import it on MyAnimeList, go [here](https://myanimelist.net/import.php) and choose `MyAnimeList Import`.
|
|
212
|
-
|
|
213
|
-
#### `import` _(alias: `imp`)_:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
anilist import -m
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
- **Options**:
|
|
220
|
-
- `-a, --anime`: To import anime list.
|
|
221
|
-
- `-m, --manga`: To import manga list.
|
|
222
|
-
- **Description**: Import anime or manga list. If you want to import anime/manga list from MyAnimeList, export the XML from [here](https://myanimelist.net/panel.php?go=export).
|
|
223
|
-
|
|
224
|
-
#### Security
|
|
225
|
-
|
|
226
|
-
Since you are creating your own API client for login no else else can get your credentials and the generated access token will be stored in your own system. So, As long as you don't share your device (in case you do, just logout) you are safe.
|
|
227
|
-
|
|
228
|
-
#### Contribution
|
|
229
|
-
|
|
230
|
-
Want to contribute to the project? Check out complete guideline [here](CONTRIBUTING.md).
|
|
231
|
-
|
|
232
|
-
#### **_Thanks for visiting 💙_**
|
|
1
|
+
#### @irfanshadikrishad/anilist
|
|
2
|
+
|
|
3
|
+
Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts.
|
|
4
|
+
|
|
5
|
+
#### How to install?
|
|
6
|
+
|
|
7
|
+
Make sure [Node.js](https://nodejs.org/en) and [npm](https://www.npmjs.com) are already installed in your system.
|
|
8
|
+
Verify installation using
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
node -v
|
|
12
|
+
npm -v
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If you see the version then its installed. Otherwise install nodejs and npm should already be installed with nodejs.
|
|
16
|
+
Then install the package by running
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @irfanshadikrishad/anilist
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This will install the package globally. And you have to use commands like
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
anilist tr -c 15
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### How to use?
|
|
29
|
+
|
|
30
|
+
Create an API client from [anilist developer setting](https://anilist.co/settings/developer) with an application name and redirect url as `https://anilist.co/api/v2/oauth/pin`. After creating the client you will get `Client ID` and `Client Secret` which is required in order to login from CLI.
|
|
31
|
+
|
|
32
|
+
To login:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
anilist login -i <client-id> -s <client-secret>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
here `<client-id>` and `<client-secret>` should be replaced by the ones that you recieved from the developer setting.
|
|
39
|
+
|
|
40
|
+
#### CLI Commands Overview
|
|
41
|
+
|
|
42
|
+
| **Command** | **Options** | **Description** |
|
|
43
|
+
| ------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
44
|
+
| **`login`** | `-i, --id` `-s, --secret` | Log in with your AniList credentials |
|
|
45
|
+
| **`logout`** | _None_ | Log out from your AniList account |
|
|
46
|
+
| **`me`** | _None_ | Display information about the logged-in user |
|
|
47
|
+
| **`-V, --version`** | _None_ | Display the current version of the CLI |
|
|
48
|
+
| **`-h, --help`** | _None_ | Display available commands and options |
|
|
49
|
+
| **`trending`** <br> _(alias: `tr`)_ | `-c (default: 10)` | Fetch trending anime (default count is 10) |
|
|
50
|
+
| **`popular`** <br> _(alias: `plr`)_ | `-c (default: 10)` | Fetch popular anime (default count is 10) |
|
|
51
|
+
| **`user`** | `<username>` | Get information about a specific AniList user |
|
|
52
|
+
| **`lists`** <br> _(alias: `ls`)_ | `-a, --anime` <br> `-m, --manga` | Fetch anime or manga lists of the logged-in user |
|
|
53
|
+
| **`delete`** <br> _(alias: `del`)_ | `-a, --anime` <br> `-m, --manga` <br> `-ac, --activity` | Delete collections of anime, manga or activities |
|
|
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 |
|
|
56
|
+
| **`search`** <br> _(alias:`srch`/`find`)_ | `<query>` <br> `-a, --anime` <br> `-m, --manga` <br> `-c (default: 10)` | Get anime/manga search results |
|
|
57
|
+
| **`status`** <br> _(alias: `write`/`post`)_ | `<status>` | Write a status... (text/markdown/html) |
|
|
58
|
+
| **`export`** <br> _(alias: `exp`)_ | `-a, --anime` <br> `-m, --manga` | Export anime or manga list in JSON, CSV or XML (MyAnimeList) |
|
|
59
|
+
| **`import`** <br> _(alias: `imp`)_ | `-a, --anime` <br> `-m, --manga` | Import anime or manga list from exported JSON or MyAnimeList (XML) |
|
|
60
|
+
|
|
61
|
+
#### Command Breakdown:
|
|
62
|
+
|
|
63
|
+
#### `login`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
anilist login -i <client-id> -s <client-secret>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- **Options**:
|
|
70
|
+
- `-i, --id`: Specify AniList Client ID
|
|
71
|
+
- `-s, --secret`: Provide the AniList Client Secret
|
|
72
|
+
- **Usage**: Authenticate and log in to AniList using your ID and secret credentials.
|
|
73
|
+
|
|
74
|
+
#### `logout`:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
anilist logout
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- **Description**: End the current session and log out from your AniList account.
|
|
81
|
+
|
|
82
|
+
#### `me`:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
anilist me
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **Description**: Retrieve and display information about the currently logged-in user, including stats and profile details.
|
|
89
|
+
|
|
90
|
+
#### `-V, --version`:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
anilist -V
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **Description**: Quickly check which version of the CLI you are running.
|
|
97
|
+
|
|
98
|
+
#### `-h, --help`:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
anilist -h
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- **Description**: List all available commands and their usage details for quick reference.
|
|
105
|
+
|
|
106
|
+
#### `trending` _(alias: `tr`)_:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
anilist tr -c 15
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- **Options**:
|
|
113
|
+
- `-c (count)`: Specify how many trending anime to fetch (default: 10).
|
|
114
|
+
- **Description**: Fetch the current trending anime series, with the option to customize how many results to display.
|
|
115
|
+
|
|
116
|
+
#### `popular` _(alias: `plr`)_:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
anilist popular
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- **Options**:
|
|
123
|
+
- `-c (count)`: Specify how many popular anime to fetch (default: 10).
|
|
124
|
+
- **Description**: Fetch the most popular anime series, with the option to customize how many results to display.
|
|
125
|
+
|
|
126
|
+
#### `upcoming` _(alias: `up`)_:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
anilist up -c 25
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- **Options**:
|
|
133
|
+
- `-c (count)`: Specify how many upcoming anime to fetch (default: 10).
|
|
134
|
+
- **Description**: Fetch the upcoming anime series next season, with the option to customize how many results to display.
|
|
135
|
+
|
|
136
|
+
#### `user`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
anilist user <username>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- **Options**:
|
|
143
|
+
- `<username>`: Specify the AniList username to fetch.
|
|
144
|
+
- **Description**: Retrieve profile information about a specific AniList user.
|
|
145
|
+
|
|
146
|
+
#### `lists` _(alias: `ls`)_:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
anilist ls -a
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **Options**:
|
|
153
|
+
- `-a, --anime`: Fetch the authenticated user's anime list.
|
|
154
|
+
- `-m, --manga`: Fetch the authenticated user's manga list.
|
|
155
|
+
- **Description**: Get the anime or manga lists of the logged-in user.
|
|
156
|
+
|
|
157
|
+
#### `delete` _(alias: `del`)_:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
anilist del -ac
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
- **Options**:
|
|
164
|
+
- `-a, --anime`: Delete your specific anime collection that you want.
|
|
165
|
+
- `-m, --manga`: Delete your specific manga collection that you want.
|
|
166
|
+
- `-ac, --activity`: Delete all or any type of activities you want.
|
|
167
|
+
- **Description**: Delete the entire anime or manga collection from the logged-in user's profile.
|
|
168
|
+
|
|
169
|
+
#### `anime`
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
anilist anime <anime-id>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- **Options**
|
|
176
|
+
- `<anime-id>` _(eg: 21)_ : Id of the anime you want to get details of.
|
|
177
|
+
- **Description**: Get anime details by anime Id.
|
|
178
|
+
|
|
179
|
+
#### `search` _(alias: `srch`/`find`)_:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
anilist search <query> -a -c 20
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- **Options**:
|
|
186
|
+
- `<query>` : What you want to search (eg: naruto).
|
|
187
|
+
- `-a, --anime`: To get results of anime search.
|
|
188
|
+
- `-m, --manga`: To get results of manga search.
|
|
189
|
+
- `-c (count)`: Specify how many items to fetch (default: 10).
|
|
190
|
+
- **Description**: Get anime/manga search results
|
|
191
|
+
|
|
192
|
+
#### `status` _(alias: `write`/`post`)_:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
anilist write <status>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
- **Options**:
|
|
199
|
+
- `<status>` : This is what you want to write, It can be HTML, Markdown and/or Text. But wrap it with quotation mark (") else it might get cut-off.
|
|
200
|
+
- **Description**: Get anime/manga search results
|
|
201
|
+
|
|
202
|
+
#### `export` _(alias: `exp`)_:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
anilist export -a
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
- **Options**:
|
|
209
|
+
- `-a, --anime`: To export anime list.
|
|
210
|
+
- `-m, --manga`: To export manga list.
|
|
211
|
+
- **Description**: Export anime or manga list. For `XML (MyAnimeList)` file, to import it on MyAnimeList, go [here](https://myanimelist.net/import.php) and choose `MyAnimeList Import`.
|
|
212
|
+
|
|
213
|
+
#### `import` _(alias: `imp`)_:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
anilist import -m
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
- **Options**:
|
|
220
|
+
- `-a, --anime`: To import anime list.
|
|
221
|
+
- `-m, --manga`: To import manga list.
|
|
222
|
+
- **Description**: Import anime or manga list. If you want to import anime/manga list from MyAnimeList, export the XML from [here](https://myanimelist.net/panel.php?go=export).
|
|
223
|
+
|
|
224
|
+
#### Security
|
|
225
|
+
|
|
226
|
+
Since you are creating your own API client for login no else else can get your credentials and the generated access token will be stored in your own system. So, As long as you don't share your device (in case you do, just logout) you are safe.
|
|
227
|
+
|
|
228
|
+
#### Contribution
|
|
229
|
+
|
|
230
|
+
Want to contribute to the project? Check out complete guideline [here](CONTRIBUTING.md).
|
|
231
|
+
|
|
232
|
+
#### **_Thanks for visiting 💙_**
|
package/bin/helpers/auth.d.ts
CHANGED
|
@@ -19,5 +19,8 @@ declare class Auth {
|
|
|
19
19
|
static Write(status: string): Promise<void>;
|
|
20
20
|
static callAnimeImporter(): Promise<void>;
|
|
21
21
|
static callMangaImporter(): Promise<void>;
|
|
22
|
+
private static Like;
|
|
23
|
+
private static LikeSpecificUser;
|
|
24
|
+
static AutoLike(): Promise<void>;
|
|
22
25
|
}
|
|
23
26
|
export { Auth };
|
package/bin/helpers/auth.js
CHANGED
|
@@ -15,8 +15,8 @@ import os from "os";
|
|
|
15
15
|
import path from "path";
|
|
16
16
|
import { fetcher } from "./fetcher.js";
|
|
17
17
|
import { AniList, MyAnimeList } from "./lists.js";
|
|
18
|
-
import { deleteActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
19
|
-
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, userActivityQuery, } from "./queries.js";
|
|
18
|
+
import { deleteActivityMutation, likeActivityMutation, saveTextActivityMutation, } from "./mutations.js";
|
|
19
|
+
import { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, specificUserActivitiesQuery, userActivityQuery, userQuery, } from "./queries.js";
|
|
20
20
|
import { aniListEndpoint, getTitle, redirectUri } from "./workers.js";
|
|
21
21
|
const home_dir = os.homedir();
|
|
22
22
|
const save_path = path.join(home_dir, ".anilist_token");
|
|
@@ -130,28 +130,28 @@ class Auth {
|
|
|
130
130
|
perPage: 10,
|
|
131
131
|
});
|
|
132
132
|
const activities = (_b = (_a = activiResponse === null || activiResponse === void 0 ? void 0 : activiResponse.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities;
|
|
133
|
-
console.log(`
|
|
134
|
-
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
135
|
-
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
136
|
-
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
137
|
-
profileColor: ${(_c = user === null || user === void 0 ? void 0 : user.options) === null || _c === void 0 ? void 0 : _c.profileColor}
|
|
138
|
-
timeZone: ${(_d = user === null || user === void 0 ? void 0 : user.options) === null || _d === void 0 ? void 0 : _d.timezone}
|
|
139
|
-
activityMergeTime: ${(_e = user === null || user === void 0 ? void 0 : user.options) === null || _e === void 0 ? void 0 : _e.activityMergeTime}
|
|
140
|
-
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
141
|
-
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
142
|
-
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
143
|
-
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
144
|
-
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
145
|
-
|
|
146
|
-
Statistics (Anime):
|
|
147
|
-
Count: ${(_g = (_f = user === null || user === void 0 ? void 0 : user.statistics) === null || _f === void 0 ? void 0 : _f.anime) === null || _g === void 0 ? void 0 : _g.count}
|
|
148
|
-
Mean Score: ${(_j = (_h = user === null || user === void 0 ? void 0 : user.statistics) === null || _h === void 0 ? void 0 : _h.anime) === null || _j === void 0 ? void 0 : _j.meanScore}
|
|
149
|
-
Minutes Watched: ${(_l = (_k = user === null || user === void 0 ? void 0 : user.statistics) === null || _k === void 0 ? void 0 : _k.anime) === null || _l === void 0 ? void 0 : _l.minutesWatched}
|
|
150
|
-
|
|
151
|
-
Statistics (Manga):
|
|
152
|
-
Count: ${(_o = (_m = user === null || user === void 0 ? void 0 : user.statistics) === null || _m === void 0 ? void 0 : _m.manga) === null || _o === void 0 ? void 0 : _o.count}
|
|
153
|
-
Chapters Read: ${(_q = (_p = user === null || user === void 0 ? void 0 : user.statistics) === null || _p === void 0 ? void 0 : _p.manga) === null || _q === void 0 ? void 0 : _q.chaptersRead}
|
|
154
|
-
Volumes Read: ${(_s = (_r = user === null || user === void 0 ? void 0 : user.statistics) === null || _r === void 0 ? void 0 : _r.manga) === null || _s === void 0 ? void 0 : _s.volumesRead}
|
|
133
|
+
console.log(`
|
|
134
|
+
ID: ${user === null || user === void 0 ? void 0 : user.id}
|
|
135
|
+
Name: ${user === null || user === void 0 ? void 0 : user.name}
|
|
136
|
+
siteUrl: ${user === null || user === void 0 ? void 0 : user.siteUrl}
|
|
137
|
+
profileColor: ${(_c = user === null || user === void 0 ? void 0 : user.options) === null || _c === void 0 ? void 0 : _c.profileColor}
|
|
138
|
+
timeZone: ${(_d = user === null || user === void 0 ? void 0 : user.options) === null || _d === void 0 ? void 0 : _d.timezone}
|
|
139
|
+
activityMergeTime: ${(_e = user === null || user === void 0 ? void 0 : user.options) === null || _e === void 0 ? void 0 : _e.activityMergeTime}
|
|
140
|
+
donatorTier: ${user === null || user === void 0 ? void 0 : user.donatorTier}
|
|
141
|
+
donatorBadge: ${user === null || user === void 0 ? void 0 : user.donatorBadge}
|
|
142
|
+
unreadNotificationCount:${user === null || user === void 0 ? void 0 : user.unreadNotificationCount}
|
|
143
|
+
Account Created: ${new Date((user === null || user === void 0 ? void 0 : user.createdAt) * 1000).toUTCString()}
|
|
144
|
+
Account Updated: ${new Date((user === null || user === void 0 ? void 0 : user.updatedAt) * 1000).toUTCString()}
|
|
145
|
+
|
|
146
|
+
Statistics (Anime):
|
|
147
|
+
Count: ${(_g = (_f = user === null || user === void 0 ? void 0 : user.statistics) === null || _f === void 0 ? void 0 : _f.anime) === null || _g === void 0 ? void 0 : _g.count}
|
|
148
|
+
Mean Score: ${(_j = (_h = user === null || user === void 0 ? void 0 : user.statistics) === null || _h === void 0 ? void 0 : _h.anime) === null || _j === void 0 ? void 0 : _j.meanScore}
|
|
149
|
+
Minutes Watched: ${(_l = (_k = user === null || user === void 0 ? void 0 : user.statistics) === null || _k === void 0 ? void 0 : _k.anime) === null || _l === void 0 ? void 0 : _l.minutesWatched}
|
|
150
|
+
|
|
151
|
+
Statistics (Manga):
|
|
152
|
+
Count: ${(_o = (_m = user === null || user === void 0 ? void 0 : user.statistics) === null || _m === void 0 ? void 0 : _m.manga) === null || _o === void 0 ? void 0 : _o.count}
|
|
153
|
+
Chapters Read: ${(_q = (_p = user === null || user === void 0 ? void 0 : user.statistics) === null || _p === void 0 ? void 0 : _p.manga) === null || _q === void 0 ? void 0 : _q.chaptersRead}
|
|
154
|
+
Volumes Read: ${(_s = (_r = user === null || user === void 0 ? void 0 : user.statistics) === null || _r === void 0 ? void 0 : _r.manga) === null || _s === void 0 ? void 0 : _s.volumesRead}
|
|
155
155
|
`);
|
|
156
156
|
console.log(`\nRecent Activities:`);
|
|
157
157
|
if (activities.length > 0) {
|
|
@@ -194,10 +194,11 @@ Statistics (Manga):
|
|
|
194
194
|
static Logout() {
|
|
195
195
|
return __awaiter(this, void 0, void 0, function* () {
|
|
196
196
|
try {
|
|
197
|
+
const username = yield Auth.MyUserName();
|
|
197
198
|
if (fs.existsSync(save_path)) {
|
|
198
199
|
try {
|
|
199
200
|
fs.unlinkSync(save_path);
|
|
200
|
-
console.log(`\nLogout successful. See you soon, ${
|
|
201
|
+
console.log(`\nLogout successful. See you soon, ${username}.`);
|
|
201
202
|
}
|
|
202
203
|
catch (error) {
|
|
203
204
|
console.error("\nError logging out:", error);
|
|
@@ -624,5 +625,158 @@ Statistics (Manga):
|
|
|
624
625
|
}
|
|
625
626
|
});
|
|
626
627
|
}
|
|
628
|
+
static Like(type) {
|
|
629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
var _a, _b, _c, _d;
|
|
631
|
+
try {
|
|
632
|
+
let page = 1;
|
|
633
|
+
let hasMoreActivities = true;
|
|
634
|
+
let activity = type === 0
|
|
635
|
+
? followingActivitiesQuery
|
|
636
|
+
: type === 1
|
|
637
|
+
? globalActivitiesQuery
|
|
638
|
+
: followingActivitiesQuery;
|
|
639
|
+
while (hasMoreActivities) {
|
|
640
|
+
const activities = yield fetcher(activity, {
|
|
641
|
+
page,
|
|
642
|
+
perPage: 50,
|
|
643
|
+
});
|
|
644
|
+
if (activities && ((_b = (_a = activities === null || activities === void 0 ? void 0 : activities.data) === null || _a === void 0 ? void 0 : _a.Page) === null || _b === void 0 ? void 0 : _b.activities.length) > 0) {
|
|
645
|
+
const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
646
|
+
for (let activ of activiti) {
|
|
647
|
+
if (!activ.isLiked && activ.id) {
|
|
648
|
+
try {
|
|
649
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
650
|
+
activityId: activ.id,
|
|
651
|
+
});
|
|
652
|
+
// const ToggleLike = like?.data?.ToggleLike
|
|
653
|
+
console.info(`[${activ.id}] liked ${activ.user.name}`);
|
|
654
|
+
}
|
|
655
|
+
catch (error) {
|
|
656
|
+
console.error(`Activity possibly deleted.`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
console.log(`[${activ === null || activ === void 0 ? void 0 : activ.id}] ${activ.user.name} already-liked`);
|
|
661
|
+
}
|
|
662
|
+
// avoiding rate-limit
|
|
663
|
+
yield new Promise((resolve) => {
|
|
664
|
+
setTimeout(resolve, 2000);
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
page++;
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
// No more activities to like
|
|
671
|
+
console.log(`\nProbably the end of activities.`);
|
|
672
|
+
console.info(activities);
|
|
673
|
+
hasMoreActivities = false;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
console.error(`\nError from likeFollowing. ${error.message}`);
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
static LikeSpecificUser() {
|
|
683
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
684
|
+
var _a, _b, _c, _d, _e, _f;
|
|
685
|
+
try {
|
|
686
|
+
const { username } = yield inquirer.prompt([
|
|
687
|
+
{
|
|
688
|
+
type: "input",
|
|
689
|
+
name: "username",
|
|
690
|
+
message: "Username of the user:",
|
|
691
|
+
},
|
|
692
|
+
]);
|
|
693
|
+
const userDetails = yield fetcher(userQuery, { username: username });
|
|
694
|
+
if (userDetails) {
|
|
695
|
+
let page = 1;
|
|
696
|
+
const perPage = 50;
|
|
697
|
+
const userId = (_b = (_a = userDetails === null || userDetails === void 0 ? void 0 : userDetails.data) === null || _a === void 0 ? void 0 : _a.User) === null || _b === void 0 ? void 0 : _b.id;
|
|
698
|
+
if (userId) {
|
|
699
|
+
while (true) {
|
|
700
|
+
const activities = yield fetcher(specificUserActivitiesQuery, {
|
|
701
|
+
page,
|
|
702
|
+
perPage,
|
|
703
|
+
userId,
|
|
704
|
+
});
|
|
705
|
+
const activiti = (_d = (_c = activities === null || activities === void 0 ? void 0 : activities.data) === null || _c === void 0 ? void 0 : _c.Page) === null || _d === void 0 ? void 0 : _d.activities;
|
|
706
|
+
// Break the loop if no more activities are found
|
|
707
|
+
if (!activiti || activiti.length === 0) {
|
|
708
|
+
console.log("No more activities found.");
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
for (let activ of activiti) {
|
|
712
|
+
if (!activ.isLiked && activ.id) {
|
|
713
|
+
try {
|
|
714
|
+
const like = yield fetcher(likeActivityMutation, {
|
|
715
|
+
activityId: activ.id,
|
|
716
|
+
});
|
|
717
|
+
console.info(`[${activ.id}] liked ${(_e = activ.user) === null || _e === void 0 ? void 0 : _e.name}`);
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
console.error(`Activity possibly deleted.`);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
console.log(`[${activ === null || activ === void 0 ? void 0 : activ.id}] ${(_f = activ.user) === null || _f === void 0 ? void 0 : _f.name} already liked`);
|
|
725
|
+
}
|
|
726
|
+
// Avoiding rate limit
|
|
727
|
+
yield new Promise((resolve) => {
|
|
728
|
+
setTimeout(resolve, 2000);
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
// Go to the next page
|
|
732
|
+
page += 1;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
catch (error) {
|
|
738
|
+
console.error(`\nError from LikeSpecificUser. ${error.message}`);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
static AutoLike() {
|
|
743
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
744
|
+
try {
|
|
745
|
+
if (!(yield Auth.isLoggedIn())) {
|
|
746
|
+
console.error(`\nPlease login to use this feature.`);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
const { activityType } = yield inquirer.prompt([
|
|
750
|
+
{
|
|
751
|
+
type: "list",
|
|
752
|
+
name: "activityType",
|
|
753
|
+
message: "Select activity type:",
|
|
754
|
+
choices: [
|
|
755
|
+
{ name: "Following", value: 1 },
|
|
756
|
+
{ name: "Global", value: 2 },
|
|
757
|
+
{ name: "Specific User", value: 3 },
|
|
758
|
+
],
|
|
759
|
+
pageSize: 10,
|
|
760
|
+
},
|
|
761
|
+
]);
|
|
762
|
+
switch (activityType) {
|
|
763
|
+
case 1:
|
|
764
|
+
yield this.Like(0);
|
|
765
|
+
break;
|
|
766
|
+
case 2:
|
|
767
|
+
yield this.Like(1);
|
|
768
|
+
break;
|
|
769
|
+
case 3:
|
|
770
|
+
yield this.LikeSpecificUser();
|
|
771
|
+
break;
|
|
772
|
+
default:
|
|
773
|
+
console.error(`\nInvalid choice. (${activityType})`);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
catch (error) {
|
|
777
|
+
console.error(`\nError from autolike. ${error.message}`);
|
|
778
|
+
}
|
|
779
|
+
});
|
|
780
|
+
}
|
|
627
781
|
}
|
|
628
782
|
export { Auth };
|
package/bin/helpers/fetcher.d.ts
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
* @param {object} variables - An object containing the variables for the query.
|
|
9
9
|
* @returns {Promise<object|null>} The response from the API as a JSON object if successful; otherwise, null.
|
|
10
10
|
*/
|
|
11
|
-
declare function fetcher(query: string, variables
|
|
11
|
+
declare function fetcher(query: string, variables?: object): Promise<any | null>;
|
|
12
12
|
export { fetcher };
|
package/bin/helpers/fetcher.js
CHANGED
|
@@ -9,7 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import fetch from "node-fetch";
|
|
11
11
|
import { Auth } from "./auth.js";
|
|
12
|
-
import { aniListEndpoint } from "./workers.js";
|
|
13
12
|
/**
|
|
14
13
|
* Sends a GraphQL request to the AniList API.
|
|
15
14
|
*
|
|
@@ -22,32 +21,34 @@ import { aniListEndpoint } from "./workers.js";
|
|
|
22
21
|
*/
|
|
23
22
|
function fetcher(query, variables) {
|
|
24
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
const headers = {
|
|
25
|
+
"content-type": "application/json",
|
|
26
|
+
};
|
|
27
|
+
if (yield Auth.isLoggedIn()) {
|
|
28
|
+
headers["Authorization"] = `Bearer ${yield Auth.RetriveAccessToken()}`;
|
|
29
|
+
}
|
|
30
|
+
const response = yield fetch("https://graphql.anilist.co", {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: headers,
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
query,
|
|
35
|
+
variables,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
// Check if the response is successful
|
|
39
|
+
if (response.status !== 200) {
|
|
40
|
+
// If the status is 429, handle the rate limit
|
|
41
|
+
if (response.status === 429) {
|
|
42
|
+
console.warn("Rate limit hit. Waiting for 1 minute before retrying...");
|
|
43
|
+
yield new Promise((resolve) => setTimeout(resolve, 60000)); // Wait for 1 minute
|
|
44
|
+
return fetcher(query, variables); // Retry the request
|
|
41
45
|
}
|
|
42
46
|
else {
|
|
43
|
-
|
|
44
|
-
return null;
|
|
47
|
+
throw new Error(`\nError fetching data: ${response.statusText}`);
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
50
|
+
const data = yield response.json();
|
|
51
|
+
return data;
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
export { fetcher };
|
|
@@ -4,4 +4,5 @@ declare const deleteActivityMutation = "\nmutation($id: Int!) {\n DeleteActivit
|
|
|
4
4
|
declare const saveTextActivityMutation = "\nmutation SaveTextActivity($status: String!) {\n SaveTextActivity(text: $status) { id text userId createdAt }\n}\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
|
-
|
|
7
|
+
declare const likeActivityMutation = "\nmutation($activityId: Int!) {\n ToggleLike(id: $activityId, type: ACTIVITY) { id }\n}\n";
|
|
8
|
+
export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
|
package/bin/helpers/mutations.js
CHANGED
|
@@ -35,4 +35,9 @@ mutation ($mediaId: Int, $progress: Int, $status: MediaListStatus, $hiddenFromSt
|
|
|
35
35
|
) { id progress hiddenFromStatusLists private }
|
|
36
36
|
}
|
|
37
37
|
`;
|
|
38
|
-
|
|
38
|
+
const likeActivityMutation = `
|
|
39
|
+
mutation($activityId: Int!) {
|
|
40
|
+
ToggleLike(id: $activityId, type: ACTIVITY) { id }
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
export { addAnimeToListMutation, addMangaToListMutation, deleteActivityMutation, likeActivityMutation, saveAnimeWithProgressMutation, saveMangaWithProgressMutation, saveTextActivityMutation, };
|
package/bin/helpers/queries.d.ts
CHANGED
|
@@ -17,6 +17,9 @@ declare const activityMangaListQuery = "query ($userId: Int, $page: Int, $perPag
|
|
|
17
17
|
declare const activityMessageQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, type: MESSAGE, sort: ID_DESC) {\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
|
|
18
18
|
declare const activityAllQuery = "query ($userId: Int, $page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(userId: $userId, sort: ID_DESC) {\n ... on TextActivity { id type text createdAt user { id name } }\n ... on ListActivity { id type status progress createdAt media { id title { romaji english native } } }\n ... on MessageActivity { id type message recipient { id name } createdAt }\n }\n }\n}";
|
|
19
19
|
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}";
|
|
20
|
-
declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) {
|
|
21
|
-
declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) {
|
|
22
|
-
|
|
20
|
+
declare const malIdToAnilistAnimeId = "query ($malId: Int) {\n Media(idMal: $malId, type: ANIME) { id title { romaji english } } }\n";
|
|
21
|
+
declare const malIdToAnilistMangaId = "query ($malId: Int) {\n Media(idMal: $malId, type: MANGA) { id title { romaji english } } }\n";
|
|
22
|
+
declare const followingActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(isFollowing: true, sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
23
|
+
declare const globalActivitiesQuery = "\nquery ($page: Int, $perPage: Int) {\n Page(page: $page, perPage: $perPage) {\n activities(sort: ID_DESC) {\n ... on TextActivity { id type isLiked createdAt user { id name } }\n ... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }\n ... on MessageActivity { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
24
|
+
declare const specificUserActivitiesQuery = "\nquery ($page: Int, $perPage: Int, $userId: Int) {\n Page(page: $page, perPage: $perPage) {\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 { id type isLiked message createdAt recipient { id name } }\n }\n }\n}\n";
|
|
25
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, };
|
package/bin/helpers/queries.js
CHANGED
|
@@ -120,13 +120,42 @@ const activityMediaList = `query ($userId: Int, $page: Int, $perPage: Int, $type
|
|
|
120
120
|
}
|
|
121
121
|
}`;
|
|
122
122
|
const malIdToAnilistAnimeId = `query ($malId: Int) {
|
|
123
|
-
Media(idMal: $malId, type: ANIME) {
|
|
124
|
-
id title { romaji english } }
|
|
125
|
-
}
|
|
123
|
+
Media(idMal: $malId, type: ANIME) { id title { romaji english } } }
|
|
126
124
|
`;
|
|
127
125
|
const malIdToAnilistMangaId = `query ($malId: Int) {
|
|
128
|
-
Media(idMal: $malId, type: MANGA) {
|
|
129
|
-
|
|
126
|
+
Media(idMal: $malId, type: MANGA) { id title { romaji english } } }
|
|
127
|
+
`;
|
|
128
|
+
const followingActivitiesQuery = `
|
|
129
|
+
query ($page: Int, $perPage: Int) {
|
|
130
|
+
Page(page: $page, perPage: $perPage) {
|
|
131
|
+
activities(isFollowing: true, sort: ID_DESC) {
|
|
132
|
+
... on TextActivity { id type isLiked createdAt user { id name } }
|
|
133
|
+
... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
|
|
134
|
+
... on MessageActivity { id type isLiked message createdAt recipient { id name } }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
const globalActivitiesQuery = `
|
|
140
|
+
query ($page: Int, $perPage: Int) {
|
|
141
|
+
Page(page: $page, perPage: $perPage) {
|
|
142
|
+
activities(sort: ID_DESC) {
|
|
143
|
+
... on TextActivity { id type isLiked createdAt user { id name } }
|
|
144
|
+
... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
|
|
145
|
+
... on MessageActivity { id type isLiked message createdAt recipient { id name } }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
`;
|
|
150
|
+
const specificUserActivitiesQuery = `
|
|
151
|
+
query ($page: Int, $perPage: Int, $userId: Int) {
|
|
152
|
+
Page(page: $page, perPage: $perPage) {
|
|
153
|
+
activities(userId: $userId, sort: ID_DESC) {
|
|
154
|
+
... on TextActivity { id type isLiked createdAt user { id name } }
|
|
155
|
+
... on ListActivity { id type isLiked status progress media { title { userPreferred } } createdAt user { id name } }
|
|
156
|
+
... on MessageActivity { id type isLiked message createdAt recipient { id name } }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
130
159
|
}
|
|
131
160
|
`;
|
|
132
|
-
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, };
|
|
161
|
+
export { activityAllQuery, activityAnimeListQuery, activityMangaListQuery, activityMediaList, activityMessageQuery, activityTextQuery, animeDetailsQuery, animeSearchQuery, currentUserAnimeList, currentUserMangaList, currentUserQuery, deleteMangaEntryMutation, deleteMediaEntryMutation, followingActivitiesQuery, globalActivitiesQuery, malIdToAnilistAnimeId, malIdToAnilistMangaId, mangaSearchQuery, popularQuery, specificUserActivitiesQuery, trendingQuery, upcomingAnimesQuery, userActivityQuery, userQuery, };
|
package/bin/helpers/workers.js
CHANGED
|
@@ -168,49 +168,49 @@ function selectFile(fileType) {
|
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
170
|
function createAnimeXML(malId, progress, status, episodes, title) {
|
|
171
|
-
return `
|
|
172
|
-
<anime>
|
|
173
|
-
<series_animedb_id>${malId}</series_animedb_id>
|
|
174
|
-
<series_title><![CDATA[${title}]]></series_title>
|
|
175
|
-
<series_type>""</series_type>
|
|
176
|
-
<series_episodes>${episodes}</series_episodes>
|
|
177
|
-
<my_id>0</my_id>
|
|
178
|
-
<my_watched_episodes>${progress}</my_watched_episodes>
|
|
179
|
-
<my_start_date>0000-00-00</my_start_date>
|
|
180
|
-
<my_finish_date>0000-00-00</my_finish_date>
|
|
181
|
-
<my_score>0</my_score>
|
|
182
|
-
<my_storage_value>0.00</my_storage_value>
|
|
183
|
-
<my_status>${status}</my_status>
|
|
184
|
-
<my_comments><![CDATA[]]></my_comments>
|
|
185
|
-
<my_times_watched>0</my_times_watched>
|
|
186
|
-
<my_rewatch_value></my_rewatch_value>
|
|
187
|
-
<my_priority>LOW</my_priority>
|
|
188
|
-
<my_tags><![CDATA[]]></my_tags>
|
|
189
|
-
<my_rewatching>0</my_rewatching>
|
|
190
|
-
<my_rewatching_ep>0</my_rewatching_ep>
|
|
191
|
-
<my_discuss>0</my_discuss>
|
|
192
|
-
<my_sns>default</my_sns>
|
|
193
|
-
<update_on_import>1</update_on_import>
|
|
171
|
+
return `
|
|
172
|
+
<anime>
|
|
173
|
+
<series_animedb_id>${malId}</series_animedb_id>
|
|
174
|
+
<series_title><![CDATA[${title}]]></series_title>
|
|
175
|
+
<series_type>""</series_type>
|
|
176
|
+
<series_episodes>${episodes}</series_episodes>
|
|
177
|
+
<my_id>0</my_id>
|
|
178
|
+
<my_watched_episodes>${progress}</my_watched_episodes>
|
|
179
|
+
<my_start_date>0000-00-00</my_start_date>
|
|
180
|
+
<my_finish_date>0000-00-00</my_finish_date>
|
|
181
|
+
<my_score>0</my_score>
|
|
182
|
+
<my_storage_value>0.00</my_storage_value>
|
|
183
|
+
<my_status>${status}</my_status>
|
|
184
|
+
<my_comments><![CDATA[]]></my_comments>
|
|
185
|
+
<my_times_watched>0</my_times_watched>
|
|
186
|
+
<my_rewatch_value></my_rewatch_value>
|
|
187
|
+
<my_priority>LOW</my_priority>
|
|
188
|
+
<my_tags><![CDATA[]]></my_tags>
|
|
189
|
+
<my_rewatching>0</my_rewatching>
|
|
190
|
+
<my_rewatching_ep>0</my_rewatching_ep>
|
|
191
|
+
<my_discuss>0</my_discuss>
|
|
192
|
+
<my_sns>default</my_sns>
|
|
193
|
+
<update_on_import>1</update_on_import>
|
|
194
194
|
</anime>`;
|
|
195
195
|
}
|
|
196
196
|
function createMangaXML(malId, progress, status, chapters, title) {
|
|
197
|
-
return `
|
|
198
|
-
<manga>
|
|
199
|
-
<manga_mangadb_id>${malId}</manga_mangadb_id>
|
|
200
|
-
<manga_title><![CDATA[${title ? title : "unknown"}]]></manga_title>
|
|
201
|
-
<manga_volumes>0</manga_volumes>
|
|
202
|
-
<manga_chapters>${chapters ? chapters : 0}</manga_chapters>
|
|
203
|
-
<my_id>0</my_id>
|
|
204
|
-
<my_read_chapters>${progress}</my_read_chapters>
|
|
205
|
-
<my_start_date>0000-00-00</my_start_date>
|
|
206
|
-
<my_finish_date>0000-00-00</my_finish_date>
|
|
207
|
-
<my_score>0</my_score>
|
|
208
|
-
<my_status>${status}</my_status>
|
|
209
|
-
<my_reread_value></my_reread_value>
|
|
210
|
-
<my_priority>LOW</my_priority>
|
|
211
|
-
<my_rereading>0</my_rereading>
|
|
212
|
-
<my_discuss>0</my_discuss>
|
|
213
|
-
<update_on_import>1</update_on_import>
|
|
197
|
+
return `
|
|
198
|
+
<manga>
|
|
199
|
+
<manga_mangadb_id>${malId}</manga_mangadb_id>
|
|
200
|
+
<manga_title><![CDATA[${title ? title : "unknown"}]]></manga_title>
|
|
201
|
+
<manga_volumes>0</manga_volumes>
|
|
202
|
+
<manga_chapters>${chapters ? chapters : 0}</manga_chapters>
|
|
203
|
+
<my_id>0</my_id>
|
|
204
|
+
<my_read_chapters>${progress}</my_read_chapters>
|
|
205
|
+
<my_start_date>0000-00-00</my_start_date>
|
|
206
|
+
<my_finish_date>0000-00-00</my_finish_date>
|
|
207
|
+
<my_score>0</my_score>
|
|
208
|
+
<my_status>${status}</my_status>
|
|
209
|
+
<my_reread_value></my_reread_value>
|
|
210
|
+
<my_priority>LOW</my_priority>
|
|
211
|
+
<my_rereading>0</my_rereading>
|
|
212
|
+
<my_discuss>0</my_discuss>
|
|
213
|
+
<update_on_import>1</update_on_import>
|
|
214
214
|
</manga>`;
|
|
215
215
|
}
|
|
216
216
|
function createAnimeListXML(mediaWithProgress) {
|
|
@@ -230,19 +230,19 @@ function createAnimeListXML(mediaWithProgress) {
|
|
|
230
230
|
const status = statusMap[anime.status];
|
|
231
231
|
return createAnimeXML(malId, progress, status, episodes, title);
|
|
232
232
|
});
|
|
233
|
-
return `<myanimelist>
|
|
234
|
-
<myinfo>
|
|
235
|
-
<user_id/>
|
|
236
|
-
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
237
|
-
<user_export_type>1</user_export_type>
|
|
238
|
-
<user_total_anime>0</user_total_anime>
|
|
239
|
-
<user_total_watching>0</user_total_watching>
|
|
240
|
-
<user_total_completed>0</user_total_completed>
|
|
241
|
-
<user_total_onhold>0</user_total_onhold>
|
|
242
|
-
<user_total_dropped>0</user_total_dropped>
|
|
243
|
-
<user_total_plantowatch>0</user_total_plantowatch>
|
|
244
|
-
</myinfo>
|
|
245
|
-
\n${xmlEntries.join("\n")}\n
|
|
233
|
+
return `<myanimelist>
|
|
234
|
+
<myinfo>
|
|
235
|
+
<user_id/>
|
|
236
|
+
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
237
|
+
<user_export_type>1</user_export_type>
|
|
238
|
+
<user_total_anime>0</user_total_anime>
|
|
239
|
+
<user_total_watching>0</user_total_watching>
|
|
240
|
+
<user_total_completed>0</user_total_completed>
|
|
241
|
+
<user_total_onhold>0</user_total_onhold>
|
|
242
|
+
<user_total_dropped>0</user_total_dropped>
|
|
243
|
+
<user_total_plantowatch>0</user_total_plantowatch>
|
|
244
|
+
</myinfo>
|
|
245
|
+
\n${xmlEntries.join("\n")}\n
|
|
246
246
|
</myanimelist>`;
|
|
247
247
|
});
|
|
248
248
|
}
|
|
@@ -263,19 +263,19 @@ function createMangaListXML(mediaWithProgress) {
|
|
|
263
263
|
const status = statusMap[manga.status];
|
|
264
264
|
return createMangaXML(malId, progress, status, chapters, title);
|
|
265
265
|
});
|
|
266
|
-
return `<myanimelist>
|
|
267
|
-
<myinfo>
|
|
268
|
-
<user_id/>
|
|
269
|
-
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
270
|
-
<user_export_type>2</user_export_type>
|
|
271
|
-
<user_total_manga>5</user_total_manga>
|
|
272
|
-
<user_total_reading>1</user_total_reading>
|
|
273
|
-
<user_total_completed>1</user_total_completed>
|
|
274
|
-
<user_total_onhold>1</user_total_onhold>
|
|
275
|
-
<user_total_dropped>1</user_total_dropped>
|
|
276
|
-
<user_total_plantoread>1</user_total_plantoread>
|
|
277
|
-
</myinfo>
|
|
278
|
-
\n${xmlEntries.join("\n")}\n
|
|
266
|
+
return `<myanimelist>
|
|
267
|
+
<myinfo>
|
|
268
|
+
<user_id/>
|
|
269
|
+
<user_name>${yield Auth.MyUserName()}</user_name>
|
|
270
|
+
<user_export_type>2</user_export_type>
|
|
271
|
+
<user_total_manga>5</user_total_manga>
|
|
272
|
+
<user_total_reading>1</user_total_reading>
|
|
273
|
+
<user_total_completed>1</user_total_completed>
|
|
274
|
+
<user_total_onhold>1</user_total_onhold>
|
|
275
|
+
<user_total_dropped>1</user_total_dropped>
|
|
276
|
+
<user_total_plantoread>1</user_total_plantoread>
|
|
277
|
+
</myinfo>
|
|
278
|
+
\n${xmlEntries.join("\n")}\n
|
|
279
279
|
</myanimelist>`;
|
|
280
280
|
});
|
|
281
281
|
}
|
package/bin/index.js
CHANGED
|
@@ -16,7 +16,7 @@ const cli = new Command();
|
|
|
16
16
|
cli
|
|
17
17
|
.name("anilist")
|
|
18
18
|
.description("Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts.")
|
|
19
|
-
.version("1.0.
|
|
19
|
+
.version("1.0.0-forbidden.0");
|
|
20
20
|
cli
|
|
21
21
|
.command("login")
|
|
22
22
|
.description("Login with AniList")
|
|
@@ -202,4 +202,11 @@ cli
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
}));
|
|
205
|
+
cli
|
|
206
|
+
.command("autolike")
|
|
207
|
+
.alias("al")
|
|
208
|
+
.description("Autolike following or global activities.")
|
|
209
|
+
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
210
|
+
yield Auth.AutoLike();
|
|
211
|
+
}));
|
|
205
212
|
cli.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@irfanshadikrishad/anilist",
|
|
3
|
-
"description": "Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts",
|
|
4
|
-
"author": "Irfan Shadik Rishad",
|
|
5
|
-
"version": "1.0.
|
|
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 -w",
|
|
17
|
-
"format": "prettier . --write",
|
|
18
|
-
"format:check": "prettier . --check",
|
|
19
|
-
"lint": "eslint ./dist",
|
|
20
|
-
"lint:fix": "eslint ./dist --fix",
|
|
21
|
-
"all": "npm run lint && npm run lint:fix && npm run format"
|
|
22
|
-
},
|
|
23
|
-
"keywords": [
|
|
24
|
-
"anilist",
|
|
25
|
-
"CLI",
|
|
26
|
-
"anime",
|
|
27
|
-
"manga",
|
|
28
|
-
"anime list",
|
|
29
|
-
"manga list",
|
|
30
|
-
"anime tracker",
|
|
31
|
-
"manga tracker",
|
|
32
|
-
"anilist API",
|
|
33
|
-
"anime progress",
|
|
34
|
-
"manga progress",
|
|
35
|
-
"media list",
|
|
36
|
-
"export anime",
|
|
37
|
-
"import anime",
|
|
38
|
-
"export manga",
|
|
39
|
-
"import manga",
|
|
40
|
-
"status tracker",
|
|
41
|
-
"watchlist",
|
|
42
|
-
"reading list",
|
|
43
|
-
"graphql"
|
|
44
|
-
],
|
|
45
|
-
"repository": {
|
|
46
|
-
"type": "git",
|
|
47
|
-
"url": "https://github.com/irfanshadikrishad/anilist"
|
|
48
|
-
},
|
|
49
|
-
"homepage": "https://github.com/irfanshadikrishad/anilist",
|
|
50
|
-
"bugs": {
|
|
51
|
-
"url": "https://github.com/irfanshadikrishad/anilist/issues"
|
|
52
|
-
},
|
|
53
|
-
"license": "MPL-2.0",
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@eslint/js": "^9.13.0",
|
|
56
|
-
"@types/json2csv": "^5.0.7",
|
|
57
|
-
"@types/node": "^22.
|
|
58
|
-
"eslint": "^9.13.0",
|
|
59
|
-
"globals": "^15.11.0",
|
|
60
|
-
"prettier": "^3.3.3",
|
|
61
|
-
"prettier-plugin-organize-imports": "^4.1.0",
|
|
62
|
-
"typescript": "^5.6.3",
|
|
63
|
-
"typescript-eslint": "^8.11.0"
|
|
64
|
-
},
|
|
65
|
-
"dependencies": {
|
|
66
|
-
"commander": "^12.1.0",
|
|
67
|
-
"fast-xml-parser": "^4.5.0",
|
|
68
|
-
"inquirer": "^12.0.
|
|
69
|
-
"json2csv": "^6.0.0-alpha.2",
|
|
70
|
-
"node-fetch": "^3.3.2",
|
|
71
|
-
"open": "^10.1.0"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@irfanshadikrishad/anilist",
|
|
3
|
+
"description": "Minimalist unofficial AniList CLI for Anime and Manga Enthusiasts",
|
|
4
|
+
"author": "Irfan Shadik Rishad",
|
|
5
|
+
"version": "1.1.0-forbidden.0",
|
|
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 -w",
|
|
17
|
+
"format": "prettier . --write",
|
|
18
|
+
"format:check": "prettier . --check",
|
|
19
|
+
"lint": "eslint ./dist",
|
|
20
|
+
"lint:fix": "eslint ./dist --fix",
|
|
21
|
+
"all": "npm run lint && npm run lint:fix && npm run format"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"anilist",
|
|
25
|
+
"CLI",
|
|
26
|
+
"anime",
|
|
27
|
+
"manga",
|
|
28
|
+
"anime list",
|
|
29
|
+
"manga list",
|
|
30
|
+
"anime tracker",
|
|
31
|
+
"manga tracker",
|
|
32
|
+
"anilist API",
|
|
33
|
+
"anime progress",
|
|
34
|
+
"manga progress",
|
|
35
|
+
"media list",
|
|
36
|
+
"export anime",
|
|
37
|
+
"import anime",
|
|
38
|
+
"export manga",
|
|
39
|
+
"import manga",
|
|
40
|
+
"status tracker",
|
|
41
|
+
"watchlist",
|
|
42
|
+
"reading list",
|
|
43
|
+
"graphql"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/irfanshadikrishad/anilist"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/irfanshadikrishad/anilist",
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/irfanshadikrishad/anilist/issues"
|
|
52
|
+
},
|
|
53
|
+
"license": "MPL-2.0",
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@eslint/js": "^9.13.0",
|
|
56
|
+
"@types/json2csv": "^5.0.7",
|
|
57
|
+
"@types/node": "^22.8.1",
|
|
58
|
+
"eslint": "^9.13.0",
|
|
59
|
+
"globals": "^15.11.0",
|
|
60
|
+
"prettier": "^3.3.3",
|
|
61
|
+
"prettier-plugin-organize-imports": "^4.1.0",
|
|
62
|
+
"typescript": "^5.6.3",
|
|
63
|
+
"typescript-eslint": "^8.11.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"commander": "^12.1.0",
|
|
67
|
+
"fast-xml-parser": "^4.5.0",
|
|
68
|
+
"inquirer": "^12.0.1",
|
|
69
|
+
"json2csv": "^6.0.0-alpha.2",
|
|
70
|
+
"node-fetch": "^3.3.2",
|
|
71
|
+
"open": "^10.1.0"
|
|
72
|
+
}
|
|
73
|
+
}
|