anilink-api-wrapper 1.18.2 → 1.18.4

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/.eslintrc.js ADDED
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ extends: 'standard-with-typescript',
3
+ parserOptions: {
4
+ project: './tsconfig.json'
5
+ },
6
+ rules: {
7
+ '@typescript-eslint/consistent-type-definitions': 'off'
8
+ },
9
+ ignorePatterns: ['**/*.js'],
10
+ overrides: [
11
+ {
12
+ extends: ['plugin:@typescript-eslint/disable-type-checked'],
13
+ files: ['./**/*.ts']
14
+ },
15
+ ],
16
+ }
package/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ *.js linguist-vendored
package/README.md CHANGED
@@ -110,6 +110,8 @@ List of methods in `anilist.mutation`:
110
110
 
111
111
  ## Error Handling
112
112
 
113
+ ### Anilist Errors
114
+
113
115
  AniLink will throw an error if the AniList API returns an error. You can catch these errors using a try-catch block.
114
116
 
115
117
  ```typescript
@@ -123,7 +125,7 @@ try {
123
125
 
124
126
  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
127
 
126
- ### Typescript
128
+ #### Typescript
127
129
 
128
130
  ```typescript
129
131
  async function handleRateLimit(apiCall: () => Promise<any>, retryAfter = 60) {
@@ -153,7 +155,7 @@ async function handleRateLimit(apiCall: () => Promise<any>, retryAfter = 60) {
153
155
  }
154
156
  ```
155
157
 
156
- ### Javascript
158
+ #### Javascript
157
159
 
158
160
  ```javascript
159
161
  async function handleRateLimit(apiCall, retryAfter = 60) {
@@ -170,7 +172,7 @@ The possible error codes returned by the AniList API are:
170
172
 
171
173
  ### Missing or Invalid Variables
172
174
 
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.
175
+ 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 a number for ID, AniLink will throw an error. Most variables are optional however there a few that are required.
174
176
  ```typescript
175
177
  try {
176
178
  const user = await aniLink.anilist.query.user({id: '542244'});
@@ -39,6 +39,9 @@ class SaveMediaListEntryMutation extends APIWrapper_1.APIWrapper {
39
39
  */
40
40
  saveMediaListEntry(variables) {
41
41
  return __awaiter(this, void 0, void 0, function* () {
42
+ if (variables.mediaId === undefined) {
43
+ throw new Error('mediaId is required for SaveMediaListEntryMutation');
44
+ }
42
45
  const variableTypeMappings = {
43
46
  id: 'number',
44
47
  mediaId: 'number',
@@ -39,6 +39,9 @@ class UpdateMediaListEntriesMutation extends APIWrapper_1.APIWrapper {
39
39
  * */
40
40
  updateMediaListEntries(variables) {
41
41
  return __awaiter(this, void 0, void 0, function* () {
42
+ if (!variables.ids || variables.ids.length === 0) {
43
+ throw new Error('ids must be an array of at least one number');
44
+ }
42
45
  const variableTypeMappings = {
43
46
  status: MediaListStatus_1.MediaListStatusMappings,
44
47
  score: 'number',
@@ -13,6 +13,9 @@ exports.ActivityQuery = void 0;
13
13
  const APIWrapper_1 = require("../../../base/APIWrapper");
14
14
  const RequestHandler_1 = require("../../../base/RequestHandler");
15
15
  const Activity_1 = require("../interfaces/Activity");
16
+ const ValidateVariables_1 = require("../../../base/ValidateVariables");
17
+ const Sort_1 = require("../types/Sort");
18
+ const ActivityType_1 = require("../types/ActivityType");
16
19
  /**
17
20
  * `ActivityQuery` is a class representing a query for activities.
18
21
  * It includes a method to get activities.
@@ -35,6 +38,39 @@ class ActivityQuery extends APIWrapper_1.APIWrapper {
35
38
  */
36
39
  activity(variables) {
37
40
  return __awaiter(this, void 0, void 0, function* () {
41
+ if (variables.id === undefined) {
42
+ throw new Error('The id variable is required');
43
+ }
44
+ const variableTypeMappings = {
45
+ id: 'number',
46
+ userId: 'number',
47
+ messengerId: 'number',
48
+ mediaId: 'number',
49
+ type: ActivityType_1.ActivityTypeMappings,
50
+ isFollowing: 'boolean',
51
+ hasReplies: 'boolean',
52
+ hasRepliesOrTypeText: 'boolean',
53
+ createdAt: 'number',
54
+ id_not: 'number',
55
+ id_in: 'number[]',
56
+ id_not_in: 'number[]',
57
+ userId_not: 'number',
58
+ userId_in: 'number[]',
59
+ userId_not_in: 'number[]',
60
+ messengerId_not: 'number',
61
+ messengerId_in: 'number[]',
62
+ messengerId_not_in: 'number[]',
63
+ mediaId_not: 'number',
64
+ mediaId_in: 'number[]',
65
+ mediaId_not_in: 'number[]',
66
+ type_not: ActivityType_1.ActivityTypeMappings,
67
+ type_in: ActivityType_1.ActivityTypeMappings,
68
+ type_not_in: ActivityType_1.ActivityTypeMappings,
69
+ createdAt_greater: 'number',
70
+ sort: Sort_1.ActivitySortMappings,
71
+ asHtml: 'boolean'
72
+ };
73
+ (0, ValidateVariables_1.validateVariables)(variables, variableTypeMappings);
38
74
  const query = `
39
75
  query ($id: Int, $userId: Int, $messengerId: Int, $mediaId: Int, $type: ActivityType, $isFollowing: Boolean, $hasReplies: Boolean, $hasRepliesOrTypeText: Boolean, $createdAt: Int, $id_not: Int, $id_in: [Int], $id_not_in: [Int], $userId_not: Int, $userId_in: [Int], $userId_not_in: [Int], $messengerId_not: Int, $messengerId_in: [Int], $messengerId_not_in: [Int], $mediaId_not: Int, $mediaId_in: [Int], $mediaId_not_in: [Int], $type_not: ActivityType, $type_in: [ActivityType], $type_not_in: [ActivityType], $createdAt_greater: Int, $sort: [ActivitySort], $asHtml: Boolean) {
40
76
  Activity (id: $id, userId: $userId, messengerId: $messengerId, mediaId: $mediaId, type: $type, isFollowing: $isFollowing, hasReplies: $hasReplies, hasRepliesOrTypeText: $hasRepliesOrTypeText, createdAt: $createdAt, id_not: $id_not, id_in: $id_in, id_not_in: $id_not_in, userId_not: $userId_not, userId_in: $userId_in, userId_not_in: $userId_not_in, messengerId_not: $messengerId_not, messengerId_in: $messengerId_in, messengerId_not_in: $messengerId_not_in, mediaId_not: $mediaId_not, mediaId_in: $mediaId_in, mediaId_not_in: $mediaId_not_in, type_not: $type_not, type_in: $type_in, type_not_in: $type_not_in, createdAt_greater: $createdAt_greater, sort: $sort) {
@@ -13,6 +13,7 @@ exports.ActivityReplyQuery = void 0;
13
13
  const APIWrapper_1 = require("../../../base/APIWrapper");
14
14
  const RequestHandler_1 = require("../../../base/RequestHandler");
15
15
  const ActivityReply_1 = require("../interfaces/ActivityReply");
16
+ const ValidateVariables_1 = require("../../../base/ValidateVariables");
16
17
  /**
17
18
  * `ActivityReplyQuery` is a class representing a query for activity replies.
18
19
  * It includes a method to get activity replies.
@@ -35,6 +36,15 @@ class ActivityReplyQuery extends APIWrapper_1.APIWrapper {
35
36
  */
36
37
  activityReply(variables) {
37
38
  return __awaiter(this, void 0, void 0, function* () {
39
+ if (variables.id === undefined) {
40
+ throw new Error('The id is required');
41
+ }
42
+ const variableTypeMappings = {
43
+ id: 'number',
44
+ activityId: 'number',
45
+ asHtml: 'boolean'
46
+ };
47
+ (0, ValidateVariables_1.validateVariables)(variables, variableTypeMappings);
38
48
  const query = `
39
49
  query ($id: Int, $activityId: Int, $asHtml: Boolean) {
40
50
  ActivityReply (id: $id, activityId: $activityId) {
@@ -13,6 +13,8 @@ exports.AiringScheduleQuery = void 0;
13
13
  const APIWrapper_1 = require("../../../base/APIWrapper");
14
14
  const RequestHandler_1 = require("../../../base/RequestHandler");
15
15
  const AiringSchedule_1 = require("../interfaces/responses/query/AiringSchedule");
16
+ const Sort_1 = require("../types/Sort");
17
+ const ValidateVariables_1 = require("../../../base/ValidateVariables");
16
18
  /**
17
19
  * `AiringScheduleQuery` is a class representing a query for airing schedules.
18
20
  * It includes a method to get airing schedules.
@@ -35,6 +37,32 @@ class AiringScheduleQuery extends APIWrapper_1.APIWrapper {
35
37
  */
36
38
  airingSchedule(variables) {
37
39
  return __awaiter(this, void 0, void 0, function* () {
40
+ if (!variables.id || !variables.mediaId) {
41
+ throw new Error('The id or mediaId variables are required');
42
+ }
43
+ const variableTypeMappings = {
44
+ id: 'number',
45
+ mediaId: 'number',
46
+ episode: 'number',
47
+ airingAt: 'number',
48
+ notYetAired: 'boolean',
49
+ id_not: 'number',
50
+ id_in: 'number[]',
51
+ id_not_in: 'number[]',
52
+ mediaId_not: 'number',
53
+ mediaId_in: 'number[]',
54
+ mediaId_not_in: 'number[]',
55
+ episode_not: 'number',
56
+ episode_in: 'number[]',
57
+ episode_not_in: 'number[]',
58
+ episode_greater: 'number',
59
+ episode_lesser: 'number',
60
+ airingAt_greater: 'number',
61
+ airingAt_lesser: 'number',
62
+ sort: Sort_1.AiringSortMappings,
63
+ asHtml: 'boolean'
64
+ };
65
+ (0, ValidateVariables_1.validateVariables)(variables, variableTypeMappings);
38
66
  const query = `
39
67
  query ($id: Int, $mediaId: Int, $episode: Int, $airingAt: Int, $notYetAired: Boolean, $id_not: Int, $id_in: [Int], $id_not_in: [Int], $mediaId_not: Int, $mediaId_in: [Int], $mediaId_not_in: [Int], $episode_not: Int, $episode_in: [Int], $episode_not_in: [Int], $episode_greater: Int, $episode_lesser: Int, $airingAt_greater: Int, $airingAt_lesser: Int, $sort: [AiringSort], $asHtml: Boolean) {
40
68
  AiringSchedule (id: $id, mediaId: $mediaId, episode: $episode, airingAt: $airingAt, notYetAired: $notYetAired, id_not: $id_not, id_in: $id_in, id_not_in: $id_not_in, mediaId_not: $mediaId_not, mediaId_in: $mediaId_in, mediaId_not_in: $mediaId_not_in, episode_not: $episode_not, episode_in: $episode_in, episode_not_in: $episode_not_in, episode_greater: $episode_greater, episode_lesser: $episode_lesser, airingAt_greater: $airingAt_greater, airingAt_lesser: $airingAt_lesser, sort: $sort) {
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityTypeMappings = void 0;
4
+ /**
5
+ * `ActivityTypeMappings` is a mapping of `ActivityType` enum values to their corresponding string values.
6
+ * It can be one of the following: 'TEXT', 'ANIME_LIST', 'MANGA_LIST', 'MESSAGE', 'MEDIA_LIST'.
7
+ */
8
+ exports.ActivityTypeMappings = [
9
+ 'TEXT',
10
+ 'ANIME_LIST',
11
+ 'MANGA_LIST',
12
+ 'MESSAGE',
13
+ 'MEDIA_LIST'
14
+ ];
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AiringSortMappings = exports.ActivitySortMappings = void 0;
4
+ /**
5
+ * `ActivitySortMappings` is a mapping of `ActivitySort` enum values to their corresponding string values.
6
+ * It can be one of the following: 'ID', 'ID_DESC', 'PINNED'.
7
+ */
8
+ exports.ActivitySortMappings = [
9
+ 'ID',
10
+ 'ID_DESC',
11
+ 'PINNED'
12
+ ];
13
+ /**
14
+ * `AiringSortMappings` is a mapping of `AiringSort` enum values to their corresponding string values.
15
+ * It can be one of the following: 'ID', 'ID_DESC', 'MEDIA_ID', 'MEDIA_ID_DESC', 'TIME', 'TIME_DESC', 'EPISODE', 'EPISODE_DESC'.
16
+ */
17
+ exports.AiringSortMappings = [
18
+ 'ID',
19
+ 'ID_DESC',
20
+ 'MEDIA_ID',
21
+ 'MEDIA_ID_DESC',
22
+ 'TIME',
23
+ 'TIME_DESC',
24
+ 'EPISODE',
25
+ 'EPISODE_DESC'
26
+ ];
@@ -31,6 +31,7 @@ const sendRequest = (url, method, data, token) => __awaiter(void 0, void 0, void
31
31
  if (token !== null && token !== undefined && token !== '') {
32
32
  headers.Authorization = `Bearer ${token}`;
33
33
  }
34
+ /* eslint-disable no-useless-catch */
34
35
  try {
35
36
  const response = yield (0, axios_1.default)({
36
37
  url,
@@ -10,32 +10,33 @@ exports.validateVariables = void 0;
10
10
  * @throws Will throw an error if any of the variables do not match their expected types. The error message will include the names of the invalid variables and their expected types.
11
11
  */
12
12
  function validateVariables(variables, variableTypeMappings) {
13
+ if (Object.keys(variables).length === 0) {
14
+ throw new Error('No variables were provided');
15
+ }
13
16
  const errors = [];
14
17
  for (const [variable, value] of Object.entries(variables)) {
15
18
  const expectedType = variableTypeMappings[variable];
16
19
  if (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)) {
25
- // If the value is an object, validate its properties
26
- if (typeof value === 'object' && value !== null) {
27
- for (const [prop, propValue] of Object.entries(value)) {
28
- const expectedPropType = expectedType[prop];
29
- if (expectedPropType && !expectedPropType.includes(propValue)) {
30
- errors.push(`Invalid ${variable}.${prop}: ${propValue}. Expected one of: ${expectedPropType.join(', ')}`);
20
+ if (Array.isArray(expectedType)) {
21
+ // If the expected type is an array, check if the value or its elements are included in the array
22
+ if (Array.isArray(value)) {
23
+ value.forEach((item, index) => {
24
+ if (!expectedType.includes(item)) {
25
+ errors.push(`Invalid ${variable}[${index}]: ${item}. Expected one of: ${expectedType.join(', ')}`);
31
26
  }
32
- }
27
+ });
33
28
  }
34
29
  else if (!expectedType.includes(value)) {
35
- // If the value is not an object, check if it is one of the array values
36
30
  errors.push(`Invalid ${variable}: ${value}. Expected one of: ${expectedType.join(', ')}`);
37
31
  }
38
32
  }
33
+ else if (typeof expectedType === 'string' && expectedType.endsWith('[]')) {
34
+ // If the expected type is an array type, check if the actual value is an array and if its elements are of the correct type
35
+ const elementType = expectedType.slice(0, -2); // Remove the '[]' from the end
36
+ if (!Array.isArray(value) || !value.every((element) => typeof element === elementType)) {
37
+ errors.push(`Invalid ${variable}: ${value}. Expected type: ${expectedType}`);
38
+ }
39
+ }
39
40
  else if (typeof expectedType === 'object') {
40
41
  // If the expected type is an object, validate its properties
41
42
  if (Array.isArray(value)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anilink-api-wrapper",
3
- "version": "1.18.2",
3
+ "version": "1.18.4",
4
4
  "description": "Anilist API Wrapper",
5
5
  "main": "dist/AniLink.js",
6
6
  "scripts": {
@@ -21,10 +21,14 @@
21
21
  "@types/jest": "^29.5.12",
22
22
  "babel-jest": "^29.7.0",
23
23
  "dotenv": "^16.4.5",
24
+ "eslint": "^8.57.0",
25
+ "eslint-config-standard-with-typescript": "^43.0.1",
26
+ "eslint-plugin-import": "^2.29.1",
27
+ "eslint-plugin-n": "^15.7.0",
28
+ "eslint-plugin-promise": "^6.1.1",
24
29
  "jest": "^29.7.0",
25
30
  "standard": "^17.1.0",
26
31
  "ts-jest": "^29.1.2",
27
- "ts-standard": "^12.0.2",
28
32
  "typedoc": "^0.25.13",
29
33
  "typedoc-theme-hierarchy": "^4.1.2",
30
34
  "typescript": "^5.4.5"