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 +16 -0
- package/.gitattributes +1 -0
- package/README.md +5 -3
- package/dist/apis/anilist/mutation/SaveMediaListEntry.js +3 -0
- package/dist/apis/anilist/mutation/UpdateMediaListEntries.js +3 -0
- package/dist/apis/anilist/query/Activity.js +36 -0
- package/dist/apis/anilist/query/ActivityReply.js +10 -0
- package/dist/apis/anilist/query/AiringSchedule.js +28 -0
- package/dist/apis/anilist/types/ActivityType.js +14 -0
- package/dist/apis/anilist/types/Sort.js +26 -0
- package/dist/base/RequestHandler.js +1 -0
- package/dist/base/ValidateVariables.js +17 -16
- package/package.json +6 -2
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
|
-
|
|
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
|
-
|
|
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 (
|
|
18
|
-
// If the expected type is an array, check if the
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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.
|
|
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"
|