anilink-api-wrapper 1.18.1 → 1.18.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/README.md CHANGED
@@ -108,6 +108,83 @@ List of methods in `anilist.mutation`:
108
108
  - saveMediaListEntry
109
109
  - updateMediaListEntries
110
110
 
111
+ ## Error Handling
112
+
113
+ AniLink will throw an error if the AniList API returns an error. You can catch these errors using a try-catch block.
114
+
115
+ ```typescript
116
+ try {
117
+ const user = await aniLink.anilist.query.user({id: 542244});
118
+ console.log(user);
119
+ } catch (error) {
120
+ console.error(error);
121
+ }
122
+ ```
123
+
124
+ This includes status codes and error messages returned by the AniList API. Here is an example rate limit handler to catch the errors thrown by AniLink:
125
+
126
+ ### Typescript
127
+
128
+ ```typescript
129
+ async function handleRateLimit(apiCall: () => Promise<any>, retryAfter = 60) {
130
+ try {
131
+ let response;
132
+ try {
133
+ response = await apiCall();
134
+ } catch (error) {
135
+ throw error;
136
+ }
137
+ console.log(response.data);
138
+ return response;
139
+ } catch (error: any) {
140
+ if (error.response && error.response.status === 429) {
141
+ console.log('Rate limit exceeded, waiting for 1 minute before retrying...');
142
+ await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
143
+ console.log('Retrying...');
144
+ return handleRateLimit(apiCall, retryAfter);
145
+ } else {
146
+ if (error.response && error.response.data) {
147
+ throw error.response.data;
148
+ } else {
149
+ throw error.response || error;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ ### Javascript
157
+
158
+ ```javascript
159
+ async function handleRateLimit(apiCall, retryAfter = 60) {
160
+ // Same as above
161
+ }
162
+ ```
163
+
164
+ The possible error codes returned by the AniList API are:
165
+ - 400: Bad Request (e.g. missing variables, invalid variables, or invalid query)
166
+ - 401: Unauthorized (e.g. invalid authentication token)
167
+ - 404: Not Found (e.g. user not found)
168
+ - 429: Too Many Requests (e.g. rate limit exceeded)
169
+ - 500: Internal Server Error (e.g. AniList server error)
170
+
171
+ ### Missing or Invalid Variables
172
+
173
+ AniLink will also throw an error if any variables are missing or invalid. For example, if you try to query a user providing a string instead of ID, AniLink will throw an error. Most variables are optional however there a few that are required.
174
+ ```typescript
175
+ try {
176
+ const user = await aniLink.anilist.query.user({id: '542244'});
177
+ console.log(user);
178
+ } catch (error) {
179
+ console.error(error);
180
+ }
181
+ ```
182
+
183
+ Example Error Thrown:
184
+
185
+ ```typescript
186
+ Invalid id: 542244. Expected type: number
187
+ ```
111
188
 
112
189
  ## Examples
113
190
 
@@ -13,6 +13,9 @@ exports.SaveMediaListEntryMutation = void 0;
13
13
  const APIWrapper_1 = require("../../../base/APIWrapper");
14
14
  const RequestHandler_1 = require("../../../base/RequestHandler");
15
15
  const FuzzyDate_1 = require("../interfaces/FuzzyDate");
16
+ const MediaListStatus_1 = require("../types/MediaListStatus");
17
+ const FuzzyDate_2 = require("../types/FuzzyDate");
18
+ const ValidateVariables_1 = require("../../../base/ValidateVariables");
16
19
  /**
17
20
  * `SaveMediaListEntryMutation` is a class representing a mutation to save a media list entry.
18
21
  * It includes a method to save a media list entry.
@@ -30,11 +33,31 @@ class SaveMediaListEntryMutation extends APIWrapper_1.APIWrapper {
30
33
  /**
31
34
  * `saveMediaListEntry` is a method that sends a mutation request to save a media list entry.
32
35
  *
33
- * @param variables - The variables for the mutation.
34
- * @returns The response from the mutation request.
36
+ * @param variables - An object of type `SaveMediaListEntryVariables` representing the variables for the mutation.
37
+ * @returns A Promise that resolves to the response from the mutation request.
38
+ * @throws Will throw an error if the mutation request fails or if the provided variables do not pass the validation checks.
35
39
  */
36
40
  saveMediaListEntry(variables) {
37
41
  return __awaiter(this, void 0, void 0, function* () {
42
+ const variableTypeMappings = {
43
+ id: 'number',
44
+ mediaId: 'number',
45
+ status: MediaListStatus_1.MediaListStatusMappings,
46
+ score: 'number',
47
+ scoreRaw: 'number',
48
+ progress: 'number',
49
+ progressVolumes: 'number',
50
+ repeat: 'number',
51
+ priority: 'number',
52
+ private: 'boolean',
53
+ notes: 'string',
54
+ hiddenFromStatusLists: 'boolean',
55
+ customLists: 'string[]',
56
+ advancedScores: 'number[]',
57
+ startedAt: FuzzyDate_2.FuzzyDateMappings,
58
+ completedAt: FuzzyDate_2.FuzzyDateMappings
59
+ };
60
+ (0, ValidateVariables_1.validateVariables)(variables, variableTypeMappings);
38
61
  const mutation = `
39
62
  mutation ($id: Int, $mediaId: Int, $status: MediaListStatus, $score: Float, $scoreRaw: Int, $progress: Int, $progressVolumes: Int, $repeat: Int, $priority: Int, $private: Boolean, $notes: String, $hiddenFromStatusLists: Boolean, $customLists: [String], $advancedScores: [Float], $startedAt: FuzzyDateInput, $completedAt: FuzzyDateInput) {
40
63
  SaveMediaListEntry(id: $id, mediaId: $mediaId, status: $status, score: $score, scoreRaw: $scoreRaw, progress: $progress, progressVolumes: $progressVolumes, repeat: $repeat, priority: $priority, private: $private, notes: $notes, hiddenFromStatusLists: $hiddenFromStatusLists, customLists: $customLists, advancedScores: $advancedScores, startedAt: $startedAt, completedAt: $completedAt) {
@@ -13,6 +13,9 @@ exports.UpdateMediaListEntriesMutation = void 0;
13
13
  const APIWrapper_1 = require("../../../base/APIWrapper");
14
14
  const RequestHandler_1 = require("../../../base/RequestHandler");
15
15
  const FuzzyDate_1 = require("../interfaces/FuzzyDate");
16
+ const MediaListStatus_1 = require("../types/MediaListStatus");
17
+ const ValidateVariables_1 = require("../../../base/ValidateVariables");
18
+ const FuzzyDate_2 = require("../types/FuzzyDate");
16
19
  /**
17
20
  * `UpdateMediaListEntriesMutation` is a class representing a mutation to update media list entries.
18
21
  * It includes a method to update media list entries.
@@ -30,11 +33,29 @@ class UpdateMediaListEntriesMutation extends APIWrapper_1.APIWrapper {
30
33
  /**
31
34
  * `updateMediaListEntries` is a method that sends a mutation request to update media list entries.
32
35
  *
33
- * @param variables - The variables for the mutation.
34
- * @returns The response from the mutation request.
35
- */
36
+ * @param variables - An object of type `UpdateMediaListEntriesVariables` representing the variables for the mutation.
37
+ * @returns A Promise that resolves to the response from the mutation request.
38
+ * @throws Will throw an error if the mutation request fails or if the provided variables do not pass the validation checks.
39
+ * */
36
40
  updateMediaListEntries(variables) {
37
41
  return __awaiter(this, void 0, void 0, function* () {
42
+ const variableTypeMappings = {
43
+ status: MediaListStatus_1.MediaListStatusMappings,
44
+ score: 'number',
45
+ scoreRaw: 'number',
46
+ progress: 'number',
47
+ progressVolumes: 'number',
48
+ repeat: 'number',
49
+ priority: 'number',
50
+ private: 'boolean',
51
+ notes: 'string',
52
+ hiddenFromStatusLists: 'boolean',
53
+ advancedScores: 'number[]',
54
+ startedAt: FuzzyDate_2.FuzzyDateMappings,
55
+ completedAt: FuzzyDate_2.FuzzyDateMappings,
56
+ ids: 'number[]'
57
+ };
58
+ (0, ValidateVariables_1.validateVariables)(variables, variableTypeMappings);
38
59
  const mutation = `
39
60
  mutation ($status: MediaListStatus, $score: Float, $scoreRaw: Int, $progress: Int, $progressVolumes: Int, $repeat: Int, $priority: Int, $private: Boolean, $notes: String, $hiddenFromStatusLists: Boolean, $advancedScores: [Float], $startedAt: FuzzyDateInput, $completedAt: FuzzyDateInput, $ids: [Int]) {
40
61
  UpdateMediaListEntries(status: $status, score: $score, scoreRaw: $scoreRaw, progress: $progress, progressVolumes: $progressVolumes, repeat: $repeat, priority: $priority, private: $private, notes: $notes, hiddenFromStatusLists: $hiddenFromStatusLists, advancedScores: $advancedScores, startedAt: $startedAt, completedAt: $completedAt, ids: $ids) {
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FuzzyDateMappings = void 0;
4
+ /**
5
+ * `FuzzyDateMappings` is a constant that maps the `FuzzyDateInput` fields to their expected types.
6
+ * The `year`, `month`, and `day` fields are mapped to 'number'.
7
+ */
8
+ exports.FuzzyDateMappings = {
9
+ year: 'number',
10
+ month: 'number',
11
+ day: 'number'
12
+ };
@@ -1,2 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MediaListStatusMappings = void 0;
4
+ /**
5
+ * `MediaListStatusMappings` is a constant that maps the `MediaListStatus` values to their expected types.
6
+ * The values are mapped to 'string'.
7
+ */
8
+ exports.MediaListStatusMappings = [
9
+ 'CURRENT',
10
+ 'PLANNING',
11
+ 'COMPLETED',
12
+ 'DROPPED',
13
+ 'PAUSED',
14
+ 'REPEATING'
15
+ ];
@@ -14,7 +14,14 @@ function validateVariables(variables, variableTypeMappings) {
14
14
  for (const [variable, value] of Object.entries(variables)) {
15
15
  const expectedType = variableTypeMappings[variable];
16
16
  if (expectedType) {
17
- if (Array.isArray(expectedType)) {
17
+ if (typeof expectedType === 'string' && expectedType.endsWith('[]')) {
18
+ // If the expected type is an array, check if the actual value is an array and if its elements are of the correct type
19
+ const elementType = expectedType.slice(0, -2); // Remove the '[]' from the end
20
+ if (!Array.isArray(value) || !value.every((element) => typeof element === elementType)) {
21
+ errors.push(`Invalid ${variable}: ${value}. Expected type: ${expectedType}`);
22
+ }
23
+ }
24
+ else if (Array.isArray(expectedType)) {
18
25
  // If the value is an object, validate its properties
19
26
  if (typeof value === 'object' && value !== null) {
20
27
  for (const [prop, propValue] of Object.entries(value)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anilink-api-wrapper",
3
- "version": "1.18.1",
3
+ "version": "1.18.2",
4
4
  "description": "Anilist API Wrapper",
5
5
  "main": "dist/AniLink.js",
6
6
  "scripts": {