nekosia.js 0.1.4 β 0.2.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 +33 -19
- package/examples/dynamicCategoryFetch.js +2 -1
- package/examples/{basicUsage.js β fetchCategoryImages.js} +2 -2
- package/examples/fetchImages.js +6 -0
- package/examples/fetchTags.js +6 -0
- package/examples/version.js +4 -2
- package/index.js +23 -20
- package/package.json +64 -60
- package/services/https.js +29 -25
- package/test/api.test.js +13 -14
- package/test/integration.test.js +6 -6
- package/types/index.d.ts +189 -59
- package/types/tags.ts +3 -3
- package/examples/fetchShadowImages.js +0 -6
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
</div>
|
|
4
4
|
|
|
5
5
|
Nekosia.js is a Node.js module that provides easy access to the Nekosia API, a rich source of anime-themed images.
|
|
6
|
-
The API offers a wide range of categories, allowing you to quickly and flexibly search for images
|
|
7
|
-
You
|
|
6
|
+
The API offers a wide range of categories, allowing you to quickly and flexibly search for images based on your preferences and needs.
|
|
7
|
+
You have full control over the images you retrieve, which sets our API apart from others.
|
|
8
8
|
|
|
9
|
-
But that's not all! The API also supports sessions (based on user ID or IP address), helping to
|
|
9
|
+
But that's not all! The API also supports sessions (based on user ID or IP address), helping to prevent repeated images.
|
|
10
10
|
|
|
11
11
|
<div align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/nekosia.js">
|
|
@@ -24,18 +24,18 @@ But that's not all! The API also supports sessions (based on user ID or IP addre
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
## π Key Features of the API
|
|
27
|
-
- **Wide range of categories:** Nekosia API offers [virtually every kind of anime graphic](https://nekosia.cat/documentation?page=api-endpoints#main-categories), not
|
|
28
|
-
- **High image quality:** All images are carefully selected and checked for quality and appropriateness.
|
|
29
|
-
- **Sessions:** The API supports sessions (based on ID or IP address),
|
|
27
|
+
- **Wide range of categories:** Nekosia API offers [virtually every kind of anime graphic](https://nekosia.cat/documentation?page=api-endpoints#main-categories), not just neko images.
|
|
28
|
+
- **High image quality:** All images are carefully selected and checked for both quality and appropriateness.
|
|
29
|
+
- **Sessions:** The API supports sessions (based on ID or IP address), helping to avoid duplicate images.
|
|
30
30
|
- **Dominant colors:** The API returns a palette of dominant colors for each image.
|
|
31
|
-
- **Image compression:** JSON responses include a link to a compressed image
|
|
32
|
-
- **Security:** Nekosia API
|
|
31
|
+
- **Image compression:** JSON responses include a link to a compressed image with a significantly reduced file size compared to the original. This ensures faster load times on client devices without sacrificing quality.
|
|
32
|
+
- **Security:** Nekosia API guarantees that all content is free from NSFW material, making it one of the most trusted sources for anime-themed images.
|
|
33
33
|
|
|
34
34
|
...and thatβs not all!
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
## π Best Anime Booru
|
|
38
|
-
Nekosia also offers its own [Booru](https://nekosia.cat/booru), allowing you to browse images returned by the API.
|
|
38
|
+
Nekosia also offers its own [Booru](https://nekosia.cat/booru), allowing you to browse images returned by the API.
|
|
39
39
|
Users can edit image information, such as tags, which are crucial for us.
|
|
40
40
|
|
|
41
41
|
|
|
@@ -47,7 +47,7 @@ Check out the [official documentation](https://nekosia.cat/documentation) to lea
|
|
|
47
47
|
To install the Nekosia.js module, use the following command:
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
npm install
|
|
50
|
+
npm install nekosia.js
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
|
|
@@ -63,20 +63,24 @@ The full list of tags is available [on the Booru site](https://nekosia.cat/booru
|
|
|
63
63
|
const { NekosiaAPI } = require('nekosia.js');
|
|
64
64
|
|
|
65
65
|
(async () => {
|
|
66
|
-
const
|
|
67
|
-
console.log(
|
|
66
|
+
const response1 = await NekosiaAPI.fetchCategoryImages('catgirl');
|
|
67
|
+
console.log(response1);
|
|
68
|
+
|
|
69
|
+
const response2 = await NekosiaAPI.fetchImages({ session: 'ip', count: 1, tags: ['cute', 'blue-hair'], blacklist: ['yellow-hair'] });
|
|
70
|
+
console.log(response2);
|
|
71
|
+
|
|
72
|
+
// https://nekosia.cat/documentation?page=api-endpoints#example-response
|
|
68
73
|
})();
|
|
69
74
|
```
|
|
70
75
|
|
|
71
|
-
|
|
72
76
|
### IP-based Sessions
|
|
73
|
-
In this example, we used an IP-based session. What does this mean? Thanks to this solution, a user with a specific IP address will not encounter
|
|
77
|
+
In this example, we used an IP-based session. What does this mean? Thanks to this solution, a user with a specific IP address will not encounter duplicate images when selecting them randomly.
|
|
74
78
|
|
|
75
79
|
```js
|
|
76
80
|
const { NekosiaAPI } = require('nekosia.js');
|
|
77
81
|
|
|
78
82
|
(async () => {
|
|
79
|
-
const response = await NekosiaAPI.
|
|
83
|
+
const response = await NekosiaAPI.fetchCategoryImages('catgirl', {
|
|
80
84
|
session: 'ip',
|
|
81
85
|
count: 1,
|
|
82
86
|
additionalTags: [],
|
|
@@ -88,13 +92,13 @@ const { NekosiaAPI } = require('nekosia.js');
|
|
|
88
92
|
```
|
|
89
93
|
|
|
90
94
|
### ID-based Sessions
|
|
91
|
-
You can also use `id`, but this
|
|
95
|
+
You can also use `id`, but this requires providing a user identifier (e.g., from Discord). Pass this information in `id` as a string.
|
|
92
96
|
|
|
93
97
|
```js
|
|
94
98
|
const { NekosiaAPI } = require('nekosia.js');
|
|
95
99
|
|
|
96
100
|
(async () => {
|
|
97
|
-
const response = await NekosiaAPI.
|
|
101
|
+
const response = await NekosiaAPI.fetchCategoryImages('catgirl', {
|
|
98
102
|
session: 'id',
|
|
99
103
|
id: '561621386765971781',
|
|
100
104
|
count: 1,
|
|
@@ -110,6 +114,16 @@ const { NekosiaAPI } = require('nekosia.js');
|
|
|
110
114
|
https://github.com/Nekosia-API/nekosia.js/tree/main/examples
|
|
111
115
|
|
|
112
116
|
|
|
117
|
+
## Tags
|
|
118
|
+
```js
|
|
119
|
+
const { NekosiaAPI } = require('nekosia.js');
|
|
120
|
+
|
|
121
|
+
(async () => {
|
|
122
|
+
console.log(await NekosiaAPI.fetchTags()); // Simply returns all available tags, etc.
|
|
123
|
+
})();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
|
|
113
127
|
## Versions
|
|
114
128
|
```js
|
|
115
129
|
const { NekosiaVersion } = require('nekosia.js');
|
|
@@ -122,8 +136,8 @@ const { NekosiaVersion } = require('nekosia.js');
|
|
|
122
136
|
|
|
123
137
|
|
|
124
138
|
## β Β» Thanks
|
|
125
|
-
If you find the API or this module useful, consider giving a star to the [repository](https://github.com/
|
|
126
|
-
If you have questions or issues, create a new [Issue](https://github.com/Nekosia-API/nekosia.js/issues/new) or join the [Discord server](https://discord.gg/pba76vJhcP).
|
|
139
|
+
If you find the API or this module useful, consider giving a star to the [repository](https://github.com/Nekosia-API/nekosia.js).
|
|
140
|
+
If you have any questions or issues, create a new [Issue](https://github.com/Nekosia-API/nekosia.js/issues/new) or join the [Discord server](https://discord.gg/pba76vJhcP).
|
|
127
141
|
|
|
128
142
|
|
|
129
143
|
## π Β» MIT License
|
|
@@ -2,7 +2,7 @@ const { NekosiaAPI } = require('../index.js');
|
|
|
2
2
|
|
|
3
3
|
const fetchImages = async (category, options = {}) => {
|
|
4
4
|
try {
|
|
5
|
-
const response = await NekosiaAPI.
|
|
5
|
+
const response = await NekosiaAPI.fetchCategoryImages(category, options);
|
|
6
6
|
console.log(`${category.toUpperCase()}:`, response);
|
|
7
7
|
} catch (err) {
|
|
8
8
|
console.error(`Error fetching ${category} images:`, err);
|
|
@@ -12,4 +12,5 @@ const fetchImages = async (category, options = {}) => {
|
|
|
12
12
|
(async () => {
|
|
13
13
|
await fetchImages('catgirl');
|
|
14
14
|
await fetchImages('foxgirl', { session: 'id', id: 'user123', count: 2 });
|
|
15
|
+
await fetchImages('catgirl', { tags: 'animal-ears' });
|
|
15
16
|
})();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const { NekosiaAPI } = require('../index.js');
|
|
2
2
|
|
|
3
3
|
(async () => {
|
|
4
|
-
const response = await NekosiaAPI.
|
|
4
|
+
const response = await NekosiaAPI.fetchCategoryImages('foxgirl', {
|
|
5
5
|
session: 'ip',
|
|
6
6
|
count: 1,
|
|
7
7
|
additionalTags: ['cute', 'sakura', 'cherry-blossom'],
|
|
8
|
-
blacklistedTags: ['beret']
|
|
8
|
+
blacklistedTags: ['beret'],
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
console.log(response);
|
package/examples/version.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const { NekosiaVersion } = require('../index.js');
|
|
2
2
|
|
|
3
3
|
(async () => {
|
|
4
|
-
console.log(NekosiaVersion.module);
|
|
5
|
-
|
|
4
|
+
console.log(`Nekosia.js: v${NekosiaVersion.module}`);
|
|
5
|
+
|
|
6
|
+
const data = await NekosiaVersion.api();
|
|
7
|
+
console.log(`API: v${data.version}`);
|
|
6
8
|
})();
|
package/index.js
CHANGED
|
@@ -25,9 +25,9 @@ class NekosiaAPI {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
async
|
|
28
|
+
async fetchCategoryImages(category, options = {}) {
|
|
29
29
|
if (!category) {
|
|
30
|
-
throw new Error('The image category is required. For example, use
|
|
30
|
+
throw new Error('The image category is required. For example, use fetchCategoryImages(\'catgirl\').');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (options.session && !['id', 'ip'].includes(options.session)) {
|
|
@@ -38,24 +38,29 @@ class NekosiaAPI {
|
|
|
38
38
|
throw new Error('`id` is not required if the session is `null` or `undefined`');
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
session: null,
|
|
43
|
-
id: null,
|
|
44
|
-
count: 1,
|
|
45
|
-
additionalTags: [],
|
|
46
|
-
blacklistedTags: [],
|
|
47
|
-
...options
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return this.makeHttpRequest(`${API_URL}/images/${category}?${queryString}`);
|
|
41
|
+
return this.makeHttpRequest(`${API_URL}/images/${category}?${this.buildQueryParams(options)}`);
|
|
51
42
|
}
|
|
52
43
|
|
|
53
|
-
async
|
|
54
|
-
if (!Array.isArray(options.
|
|
55
|
-
throw new Error('`
|
|
44
|
+
async fetchImages(options = {}) {
|
|
45
|
+
if (!Array.isArray(options.tags) || options.tags.length === 0) {
|
|
46
|
+
throw new Error('`tags` must be a non-empty array');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (Array.isArray(options.blacklistedTags)) {
|
|
50
|
+
throw new Error('Unexpected `blacklistedTags` in `fetchImages()`, use `blacklist` instead');
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
return this.
|
|
53
|
+
return this.fetchCategoryImages('nothing', {
|
|
54
|
+
session: options.session,
|
|
55
|
+
id: options.id,
|
|
56
|
+
count: options.count,
|
|
57
|
+
additionalTags: options.tags,
|
|
58
|
+
blacklistedTags: options.blacklist,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async fetchTags() {
|
|
63
|
+
return this.makeHttpRequest(`${API_URL}/tags`);
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
async fetchById(id) {
|
|
@@ -67,12 +72,10 @@ class NekosiaAPI {
|
|
|
67
72
|
|
|
68
73
|
const NekosiaVersion = {
|
|
69
74
|
module: https.version,
|
|
70
|
-
api: async () =>
|
|
71
|
-
return await https.get(BASE_URL);
|
|
72
|
-
}
|
|
75
|
+
api: async () => https.get(BASE_URL),
|
|
73
76
|
};
|
|
74
77
|
|
|
75
78
|
module.exports = {
|
|
76
79
|
NekosiaAPI: new NekosiaAPI(),
|
|
77
|
-
NekosiaVersion
|
|
80
|
+
NekosiaVersion,
|
|
78
81
|
};
|
package/package.json
CHANGED
|
@@ -1,60 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "nekosia.js",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A simple wrapper for the Nekosia API that
|
|
5
|
-
"keywords": [
|
|
6
|
-
"anime api",
|
|
7
|
-
"anime art",
|
|
8
|
-
"anime
|
|
9
|
-
"anime
|
|
10
|
-
"anime
|
|
11
|
-
"anime
|
|
12
|
-
"anime
|
|
13
|
-
"anime",
|
|
14
|
-
"anime
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
"url": "
|
|
46
|
-
},
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "nekosia.js",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A simple wrapper for the Nekosia API that offers seamless access to random anime images. Add a touch of anime magic and feline charm to your projects, meow~~! Find out why Nekosia is the purrfect choice!",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"anime api",
|
|
7
|
+
"anime art",
|
|
8
|
+
"anime catgirls",
|
|
9
|
+
"anime characters",
|
|
10
|
+
"anime gifs",
|
|
11
|
+
"anime images",
|
|
12
|
+
"anime library",
|
|
13
|
+
"anime nekos",
|
|
14
|
+
"anime wallpaper",
|
|
15
|
+
"anime",
|
|
16
|
+
"anime-api",
|
|
17
|
+
"api wrapper",
|
|
18
|
+
"api-wrapper",
|
|
19
|
+
"cat ears",
|
|
20
|
+
"cat",
|
|
21
|
+
"catgirl",
|
|
22
|
+
"catgirls",
|
|
23
|
+
"cute animals",
|
|
24
|
+
"cute nekos",
|
|
25
|
+
"feline",
|
|
26
|
+
"girl",
|
|
27
|
+
"girls",
|
|
28
|
+
"image api",
|
|
29
|
+
"javascript",
|
|
30
|
+
"js library",
|
|
31
|
+
"kawaii",
|
|
32
|
+
"manga",
|
|
33
|
+
"moe",
|
|
34
|
+
"neko girls",
|
|
35
|
+
"neko",
|
|
36
|
+
"nekos",
|
|
37
|
+
"nekosia api",
|
|
38
|
+
"nekosia",
|
|
39
|
+
"otaku",
|
|
40
|
+
"random anime",
|
|
41
|
+
"waifu"
|
|
42
|
+
],
|
|
43
|
+
"homepage": "https://nekosia.cat",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/Nekosia-API/nekosia.js/issues"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/Nekosia-API/nekosia.js.git"
|
|
50
|
+
},
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"author": "Sefinek <contact@sefinek.net> (https://sefinek.net)",
|
|
53
|
+
"main": "index.js",
|
|
54
|
+
"types": "types/index.d.ts",
|
|
55
|
+
"scripts": {
|
|
56
|
+
"test": "jest",
|
|
57
|
+
"up": "ncu -u && npm install && npm update && npm audit fix"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^9.17.0",
|
|
61
|
+
"globals": "^15.13.0",
|
|
62
|
+
"jest": "^29.7.0"
|
|
63
|
+
}
|
|
64
|
+
}
|
package/services/https.js
CHANGED
|
@@ -7,39 +7,43 @@ const headers = {
|
|
|
7
7
|
'Content-Type': 'application/json',
|
|
8
8
|
'Cache-Control': 'no-cache',
|
|
9
9
|
'Connection': 'keep-alive',
|
|
10
|
-
'DNT': '1'
|
|
10
|
+
'DNT': '1',
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
const req = https.get(url, { headers, timeout: 9000 }, res => {
|
|
15
|
-
let data = '';
|
|
13
|
+
const timeout = 25000;
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
15
|
+
const get = async url => {
|
|
16
|
+
if (!url || typeof url !== 'string') throw new Error('Missing URL, expected a string.');
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const req = https.get(url, { headers, timeout }, res => {
|
|
20
|
+
const { statusCode } = res;
|
|
21
|
+
if ((statusCode < 200 || statusCode >= 300) && statusCode !== 400) {
|
|
22
|
+
req.destroy();
|
|
23
|
+
return reject(new Error(`Unexpected HTTP Status Code: ${statusCode || 'unknown'}`));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
let data = '';
|
|
27
|
+
res.on('data', chunk => data += chunk);
|
|
28
|
+
res.on('end', () => {
|
|
29
|
+
try {
|
|
30
|
+
resolve(JSON.parse(data));
|
|
31
|
+
} catch (err) {
|
|
32
|
+
reject(err);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
32
35
|
});
|
|
33
|
-
});
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
req.on('error', err => {
|
|
38
|
+
req.destroy();
|
|
39
|
+
reject(err);
|
|
40
|
+
});
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
req.on('timeout', () => {
|
|
43
|
+
req.destroy();
|
|
44
|
+
reject(new Error(`Request timed out after ${timeout} ms.`));
|
|
45
|
+
});
|
|
40
46
|
});
|
|
47
|
+
};
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
module.exports = { get: makeRequest, version };
|
|
49
|
+
module.exports = { get, version };
|
package/test/api.test.js
CHANGED
|
@@ -2,9 +2,9 @@ const { NekosiaAPI } = require('../index.js');
|
|
|
2
2
|
|
|
3
3
|
describe('NekosiaAPI (API Tests)', () => {
|
|
4
4
|
|
|
5
|
-
describe('
|
|
5
|
+
describe('fetchCategoryImages', () => {
|
|
6
6
|
it('should fetch images for the given category', async () => {
|
|
7
|
-
const res = await NekosiaAPI.
|
|
7
|
+
const res = await NekosiaAPI.fetchCategoryImages('catgirl', { count: 1 });
|
|
8
8
|
|
|
9
9
|
expect(res).toBeInstanceOf(Object);
|
|
10
10
|
expect(res.success).toBe(true);
|
|
@@ -43,48 +43,47 @@ describe('NekosiaAPI (API Tests)', () => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('should return an error for an invalid category', async () => {
|
|
46
|
-
const res = await NekosiaAPI.
|
|
46
|
+
const res = await NekosiaAPI.fetchCategoryImages('invalid-category', { count: 1 });
|
|
47
47
|
|
|
48
48
|
expect(res.success).toBe(false);
|
|
49
49
|
expect(res.status).toBe(400);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
it('should return a specified number of images', async () => {
|
|
53
|
-
const res = await NekosiaAPI.
|
|
53
|
+
const res = await NekosiaAPI.fetchCategoryImages('catgirl', { count: 3 });
|
|
54
54
|
|
|
55
55
|
expect(res).toBeInstanceOf(Object);
|
|
56
56
|
expect(res.success).toBe(true);
|
|
57
57
|
expect(res.status).toBe(200);
|
|
58
|
-
expect(res.count).toBe(3);
|
|
59
58
|
expect(res).toHaveProperty('images');
|
|
60
59
|
expect(res.images).toBeInstanceOf(Array);
|
|
61
60
|
expect(res.images.length).toBe(3);
|
|
62
61
|
});
|
|
63
62
|
});
|
|
64
63
|
|
|
65
|
-
describe('
|
|
66
|
-
it('should handle no images found for
|
|
67
|
-
const res = await NekosiaAPI.
|
|
64
|
+
describe('fetchImages', () => {
|
|
65
|
+
it('should handle no images found for nothing category with additional tags', async () => {
|
|
66
|
+
const res = await NekosiaAPI.fetchImages({ count: 1, tags: ['wTbf8J0TirS6a4fO5uyKcRazZOlO5h6o', 'xX9f9pwDAgsM3Li1LwsJ3tXQfGKW4WA0'] });
|
|
68
67
|
|
|
69
68
|
expect(res.success).toBe(false);
|
|
70
69
|
expect(res.status).toBe(400);
|
|
71
70
|
});
|
|
72
71
|
|
|
73
72
|
it('should throw an error if additionalTagsArray is empty', async () => {
|
|
74
|
-
await expect(NekosiaAPI.
|
|
73
|
+
await expect(NekosiaAPI.fetchImages([])).rejects.toThrow('`tags` must be a non-empty array');
|
|
75
74
|
});
|
|
76
75
|
|
|
77
76
|
it('should return an error response for invalid count parameter', async () => {
|
|
78
|
-
const res = await NekosiaAPI.
|
|
77
|
+
const res = await NekosiaAPI.fetchCategoryImages('catgirl', { count: 'invalid' });
|
|
79
78
|
expect(res.success).toBe(false);
|
|
80
79
|
expect(res.status).toBe(400);
|
|
81
|
-
expect(res.message).toBe('Invalid count parameter. Expected a number between 1 and 48.');
|
|
80
|
+
expect(res.message).toBe('Invalid count parameter. Expected a number between 1 and 48 (>48).');
|
|
82
81
|
});
|
|
83
82
|
});
|
|
84
83
|
|
|
85
84
|
describe('fetchById', () => {
|
|
86
85
|
it('should fetch an image by ID if it exists', async () => {
|
|
87
|
-
const res = await NekosiaAPI.
|
|
86
|
+
const res = await NekosiaAPI.fetchCategoryImages('catgirl', { count: 1 });
|
|
88
87
|
|
|
89
88
|
if (res.success && res.id) {
|
|
90
89
|
const id = res.id;
|
|
@@ -100,10 +99,10 @@ describe('NekosiaAPI (API Tests)', () => {
|
|
|
100
99
|
});
|
|
101
100
|
|
|
102
101
|
it('should return an error response for invalid ID format', async () => {
|
|
103
|
-
const res = await NekosiaAPI.
|
|
102
|
+
const res = await NekosiaAPI.fetchCategoryImages('12345');
|
|
104
103
|
expect(res.success).toBe(false);
|
|
105
104
|
expect(res.status).toBe(400);
|
|
106
|
-
expect(res.message).toBe('
|
|
105
|
+
expect(res.message).toBe('No images matching the specified criteria were found. See https://nekosia.cat/documentation?page=api-endpoints#tags-and-categories');
|
|
107
106
|
});
|
|
108
107
|
});
|
|
109
108
|
|
package/test/integration.test.js
CHANGED
|
@@ -43,30 +43,30 @@ describe('NekosiaAPI', () => {
|
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
describe('
|
|
46
|
+
describe('fetchCategoryImages', () => {
|
|
47
47
|
it('should build correct endpoint and make request for given category', async () => {
|
|
48
48
|
const mockResponse = { data: { results: [] } };
|
|
49
49
|
https.get.mockResolvedValue(mockResponse);
|
|
50
50
|
|
|
51
51
|
const expectedEndpoint = 'https://api.nekosia.cat/api/v1/images/catgirl?count=2&additionalTags=cute';
|
|
52
|
-
const res = await NekosiaAPI.
|
|
52
|
+
const res = await NekosiaAPI.fetchCategoryImages('catgirl', { count: 2, additionalTags: 'cute' });
|
|
53
53
|
|
|
54
54
|
expect(res).toEqual(mockResponse);
|
|
55
55
|
expect(https.get).toHaveBeenCalledWith(expectedEndpoint);
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
describe('
|
|
59
|
+
describe('fetchImages', () => {
|
|
60
60
|
it('should throw an error if additionalTags is empty', async () => {
|
|
61
|
-
await expect(NekosiaAPI.
|
|
61
|
+
await expect(NekosiaAPI.fetchImages({})).rejects.toThrow('`tags` must be a non-empty array');
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
it('should correctly call fetchImages with additionalTags', async () => {
|
|
65
65
|
const mockResponse = { data: { results: [] } };
|
|
66
66
|
https.get.mockResolvedValue(mockResponse);
|
|
67
67
|
|
|
68
|
-
const expectedEndpoint = 'https://api.nekosia.cat/api/v1/images/
|
|
69
|
-
const res = await NekosiaAPI.
|
|
68
|
+
const expectedEndpoint = 'https://api.nekosia.cat/api/v1/images/nothing?count=1&additionalTags=dark,shadow';
|
|
69
|
+
const res = await NekosiaAPI.fetchImages({ count: 1, tags: ['dark', 'shadow'] });
|
|
70
70
|
|
|
71
71
|
expect(res).toEqual(mockResponse);
|
|
72
72
|
expect(https.get).toHaveBeenCalledWith(expectedEndpoint);
|
package/types/index.d.ts
CHANGED
|
@@ -5,43 +5,48 @@ declare module 'nekosia.js' {
|
|
|
5
5
|
type AllTagsList = typeof TAGS[number];
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Configuration options for the `
|
|
8
|
+
* Configuration options for the `fetchCategoryImages` function.
|
|
9
9
|
*/
|
|
10
|
-
interface
|
|
10
|
+
interface FetchImagesCategoryOptions {
|
|
11
11
|
/**
|
|
12
12
|
* Session type:
|
|
13
|
-
* - `id` - Session identified by
|
|
13
|
+
* - `id` - Session identified by its `id` value (requires the `id` field to be set).
|
|
14
14
|
* - `ip` - Session identified by the user's IP address.
|
|
15
|
+
* @type String
|
|
15
16
|
* @default undefined
|
|
16
17
|
*/
|
|
17
18
|
session?: 'id' | 'ip';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Identifier of the fetched image.
|
|
21
|
-
* @
|
|
22
|
+
* @type String
|
|
23
|
+
* @example "66ae26a07886f165901e8a3f"
|
|
22
24
|
*/
|
|
23
25
|
id?: string;
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
|
-
* The number of images to fetch. WARNING! The higher the number, the more data the server will need to process,
|
|
28
|
+
* The number of images to fetch. WARNING! The higher the number, the more data the server will need to process, leading to longer response times.
|
|
27
29
|
*
|
|
28
30
|
* - Minimum - 1
|
|
29
31
|
* - Maximum - 48
|
|
32
|
+
* @type Number
|
|
30
33
|
* @default 1
|
|
31
34
|
*/
|
|
32
35
|
count?: number;
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
38
|
* Additional tags to include in the image search.
|
|
36
|
-
* This can be a single string
|
|
39
|
+
* This can be a single string representing one tag or an array of strings for multiple tags.
|
|
40
|
+
* @type Array
|
|
37
41
|
* @example ["cute", "sakura", "cherry-blossom"]
|
|
38
42
|
* @default []
|
|
39
43
|
*/
|
|
40
44
|
additionalTags?: AllTagsList | AllTagsList[];
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
|
-
* Tags to exclude
|
|
44
|
-
* This can be a single string
|
|
47
|
+
* Tags to exclude from the image search.
|
|
48
|
+
* This can be a single string representing one tag or an array of strings for multiple tags.
|
|
49
|
+
* @type Array
|
|
45
50
|
* @example ["beret", "hat", "short-hair"]
|
|
46
51
|
* @default []
|
|
47
52
|
*/
|
|
@@ -53,10 +58,76 @@ declare module 'nekosia.js' {
|
|
|
53
58
|
*
|
|
54
59
|
* Possible values:
|
|
55
60
|
* - `safe`: Suitable for all audiences, contains no explicit or questionable content.
|
|
56
|
-
* - `questionable`:
|
|
61
|
+
* - `questionable`: May contain content sensitive or inappropriate for younger audiences, but not explicit.
|
|
57
62
|
* - `nsfw`: Contains explicit content, not safe for work (NSFW).
|
|
58
63
|
*
|
|
59
64
|
* The default value is ALWAYS `safe`.
|
|
65
|
+
* @type String
|
|
66
|
+
* @example safe
|
|
67
|
+
* @default safe
|
|
68
|
+
*/
|
|
69
|
+
rating?: 'safe' | 'questionable' | 'nsfw';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Configuration options for the `fetchImages` function.
|
|
74
|
+
*/
|
|
75
|
+
interface FetchImagesOptions {
|
|
76
|
+
/**
|
|
77
|
+
* Session type:
|
|
78
|
+
* - `id` - Session identified by its `id` value (requires the `id` field to be set).
|
|
79
|
+
* - `ip` - Session identified by the user's IP address.
|
|
80
|
+
* @type String
|
|
81
|
+
* @default undefined
|
|
82
|
+
*/
|
|
83
|
+
session?: 'id' | 'ip';
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Identifier of the fetched image.
|
|
87
|
+
* @type String
|
|
88
|
+
* @example "66ae26a07886f165901e8a3f"
|
|
89
|
+
*/
|
|
90
|
+
id?: string;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The number of images to fetch. WARNING! The higher the number, the more data the server will need to process, leading to longer response times.
|
|
94
|
+
*
|
|
95
|
+
* - Minimum - 1
|
|
96
|
+
* - Maximum - 48
|
|
97
|
+
* @type Number
|
|
98
|
+
* @default 1
|
|
99
|
+
*/
|
|
100
|
+
count?: number;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Additional tags to include in the image search.
|
|
104
|
+
* This can be a single string representing one tag or an array of strings for multiple tags.
|
|
105
|
+
* @type Array
|
|
106
|
+
* @example ["cute", "sakura", "cherry-blossom"]
|
|
107
|
+
* @default []
|
|
108
|
+
*/
|
|
109
|
+
tags?: AllTagsList | AllTagsList[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Tags to exclude from the image search.
|
|
113
|
+
* This can be a single string representing one tag or an array of strings for multiple tags.
|
|
114
|
+
* @type Array
|
|
115
|
+
* @example ["beret", "hat", "short-hair"]
|
|
116
|
+
* @default []
|
|
117
|
+
*/
|
|
118
|
+
blacklist?: AllTagsList | AllTagsList[];
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Defines the content rating of an image.
|
|
122
|
+
* The rating indicates the appropriateness of the content, specifying whether the image is suitable for all audiences or contains content that may be sensitive or inappropriate for certain viewers.
|
|
123
|
+
*
|
|
124
|
+
* Possible values:
|
|
125
|
+
* - `safe`: Suitable for all audiences, contains no explicit or questionable content.
|
|
126
|
+
* - `questionable`: May contain content sensitive or inappropriate for younger audiences, but not explicit.
|
|
127
|
+
* - `nsfw`: Contains explicit content, not safe for work (NSFW).
|
|
128
|
+
*
|
|
129
|
+
* The default value is ALWAYS `safe`.
|
|
130
|
+
* @type String
|
|
60
131
|
* @example safe
|
|
61
132
|
* @default safe
|
|
62
133
|
*/
|
|
@@ -68,14 +139,16 @@ declare module 'nekosia.js' {
|
|
|
68
139
|
*/
|
|
69
140
|
interface ImageDetails {
|
|
70
141
|
/**
|
|
71
|
-
* URL
|
|
142
|
+
* URL of the image.
|
|
143
|
+
* @type String
|
|
72
144
|
* @example https://cdn.nekosia.cat/images/maid-uniform/66bc6b7481a59a1cf2c79db5.png
|
|
73
145
|
*/
|
|
74
146
|
url: string;
|
|
75
147
|
|
|
76
148
|
/**
|
|
77
149
|
* Image file extension.
|
|
78
|
-
* @
|
|
150
|
+
* @type String
|
|
151
|
+
* @example `png`, `jpg`, etc.
|
|
79
152
|
*/
|
|
80
153
|
extension: string;
|
|
81
154
|
}
|
|
@@ -86,38 +159,44 @@ declare module 'nekosia.js' {
|
|
|
86
159
|
interface ImageMetadata {
|
|
87
160
|
/**
|
|
88
161
|
* Image width in pixels.
|
|
162
|
+
* @type Number
|
|
89
163
|
* @example 1447
|
|
90
164
|
*/
|
|
91
165
|
width: number;
|
|
92
166
|
|
|
93
167
|
/**
|
|
94
168
|
* Image height in pixels.
|
|
169
|
+
* @type Number
|
|
95
170
|
* @example 2046
|
|
96
171
|
*/
|
|
97
172
|
height: number;
|
|
98
173
|
|
|
99
174
|
/**
|
|
100
175
|
* Image size in bytes.
|
|
176
|
+
* @type Number
|
|
101
177
|
* @example 1001991
|
|
102
178
|
*/
|
|
103
179
|
size: number;
|
|
104
180
|
|
|
105
181
|
/**
|
|
106
182
|
* Image file extension.
|
|
107
|
-
* @
|
|
183
|
+
* @type String
|
|
184
|
+
* @example png
|
|
108
185
|
*/
|
|
109
186
|
extension: string;
|
|
110
187
|
}
|
|
111
188
|
|
|
112
189
|
interface ImageColors {
|
|
113
190
|
/**
|
|
114
|
-
*
|
|
191
|
+
* The main dominant color of the image in hexadecimal format.
|
|
192
|
+
* @type String
|
|
115
193
|
* @example #00FF00
|
|
116
194
|
*/
|
|
117
195
|
main: HexColor;
|
|
118
196
|
|
|
119
197
|
/**
|
|
120
|
-
*
|
|
198
|
+
* A palette of the 14 most dominant colors in the image, represented in hexadecimal format.
|
|
199
|
+
* @type Array
|
|
121
200
|
* @example ["#9D78CD", "#454FC0", "#909AEB", "#F5E3F0", "#94498B", "#BEC1EE", "#CD7D67", "#CC98D5", "#E2AE9E", "#F0B4DB", "#2B1C3E", "#4E8DCB", "#F2DABF", "#5CB6C0"]
|
|
122
201
|
*/
|
|
123
202
|
palette: HexColor[];
|
|
@@ -126,37 +205,43 @@ declare module 'nekosia.js' {
|
|
|
126
205
|
interface ImageAnime {
|
|
127
206
|
/**
|
|
128
207
|
* The title of the anime from which the image originates. `null` if not applicable.
|
|
129
|
-
* @
|
|
208
|
+
* @type String
|
|
209
|
+
* @example "Satsuriku no Tenshi"
|
|
130
210
|
*/
|
|
131
211
|
title: string | null;
|
|
132
212
|
|
|
133
213
|
/**
|
|
134
214
|
* The name of the character depicted in the image. `null` if not applicable.
|
|
135
|
-
* @
|
|
215
|
+
* @type String
|
|
216
|
+
* @example "Rachel Gardner"
|
|
136
217
|
*/
|
|
137
218
|
character: string | null;
|
|
138
219
|
}
|
|
139
220
|
|
|
140
221
|
interface ImageSource {
|
|
141
222
|
/**
|
|
142
|
-
* URL of the source page where the image originates. `null` if not applicable.
|
|
223
|
+
* The URL of the source page where the image originates. `null` if not applicable.
|
|
224
|
+
* @type String
|
|
143
225
|
*/
|
|
144
226
|
url: string | null;
|
|
145
227
|
|
|
146
228
|
/**
|
|
147
|
-
*
|
|
229
|
+
* The direct link to the image. `null` if not applicable.
|
|
230
|
+
* @type String
|
|
148
231
|
*/
|
|
149
232
|
direct: string | null;
|
|
150
233
|
}
|
|
151
234
|
|
|
152
235
|
interface ArtistDetails {
|
|
153
236
|
/**
|
|
154
|
-
*
|
|
237
|
+
* The artist's username. `null` if not applicable.
|
|
238
|
+
* @type String
|
|
155
239
|
*/
|
|
156
240
|
username: string | null;
|
|
157
241
|
|
|
158
242
|
/**
|
|
159
|
-
*
|
|
243
|
+
* The link to the artist's profile. `null` if not applicable.
|
|
244
|
+
* @type String
|
|
160
245
|
*/
|
|
161
246
|
profile: string | null;
|
|
162
247
|
}
|
|
@@ -164,11 +249,13 @@ declare module 'nekosia.js' {
|
|
|
164
249
|
interface ImageAttribution {
|
|
165
250
|
/**
|
|
166
251
|
* Information about the artist.
|
|
252
|
+
* @type Object
|
|
167
253
|
*/
|
|
168
254
|
artist: ArtistDetails;
|
|
169
255
|
|
|
170
256
|
/**
|
|
171
|
-
*
|
|
257
|
+
* The copyright of the artwork. `null` if not applicable.
|
|
258
|
+
* @type String
|
|
172
259
|
*/
|
|
173
260
|
copyright: string | null;
|
|
174
261
|
}
|
|
@@ -179,99 +266,125 @@ declare module 'nekosia.js' {
|
|
|
179
266
|
interface ImageResponse {
|
|
180
267
|
/**
|
|
181
268
|
* Indicates whether the operation was successful.
|
|
269
|
+
* @type Boolean
|
|
182
270
|
* @example true
|
|
183
271
|
*/
|
|
184
272
|
success: boolean;
|
|
185
273
|
|
|
186
274
|
/**
|
|
187
275
|
* HTTP status code of the response.
|
|
276
|
+
* @type Number
|
|
188
277
|
* @example 200
|
|
189
278
|
*/
|
|
190
279
|
status: number;
|
|
191
280
|
|
|
192
281
|
/**
|
|
193
282
|
* Session key, if applicable, otherwise `null`.
|
|
283
|
+
* @type String
|
|
194
284
|
*/
|
|
195
285
|
key: string | null;
|
|
196
286
|
|
|
197
287
|
/**
|
|
198
288
|
* Number of images included in the response.
|
|
289
|
+
* @type Number
|
|
199
290
|
*/
|
|
200
291
|
count: number;
|
|
201
292
|
|
|
202
293
|
/**
|
|
203
|
-
*
|
|
294
|
+
* Unique identifier for the image.
|
|
295
|
+
* @type String
|
|
204
296
|
*/
|
|
205
297
|
id: string;
|
|
206
298
|
|
|
207
299
|
/**
|
|
208
|
-
*
|
|
300
|
+
* Object containing the dominant colors of the fetched image.
|
|
301
|
+
* @type Object
|
|
209
302
|
*/
|
|
210
303
|
colors: ImageColors;
|
|
211
304
|
|
|
212
305
|
/**
|
|
213
|
-
*
|
|
306
|
+
* Object containing details about both the original and compressed images.
|
|
214
307
|
*/
|
|
215
308
|
image: {
|
|
216
309
|
/**
|
|
217
|
-
*
|
|
310
|
+
* The original uncompressed image. Includes EXIF data to credit the artist.
|
|
311
|
+
* @type Object
|
|
218
312
|
*/
|
|
219
313
|
original: ImageDetails;
|
|
220
314
|
|
|
221
315
|
/**
|
|
222
|
-
*
|
|
316
|
+
* The compressed version of the image, reduced in size without quality loss. Includes EXIF data to credit the artist.
|
|
317
|
+
* @type Object
|
|
223
318
|
*/
|
|
224
319
|
compressed: ImageDetails;
|
|
225
320
|
};
|
|
226
321
|
|
|
227
322
|
/**
|
|
228
|
-
* Metadata
|
|
323
|
+
* Metadata for both the original and compressed images.
|
|
324
|
+
* @type Object
|
|
229
325
|
*/
|
|
230
|
-
metadata: { original: ImageMetadata; compressed: ImageMetadata
|
|
326
|
+
metadata: { original: ImageMetadata; compressed: ImageMetadata };
|
|
231
327
|
|
|
232
328
|
/**
|
|
233
|
-
*
|
|
234
|
-
* @
|
|
329
|
+
* The category the image belongs to.
|
|
330
|
+
* @type String
|
|
331
|
+
* @example "catgirl"
|
|
235
332
|
*/
|
|
236
333
|
category: string;
|
|
237
334
|
|
|
238
335
|
/**
|
|
239
|
-
* Tags
|
|
336
|
+
* Tags associated with the image.
|
|
337
|
+
* @type Array
|
|
240
338
|
*/
|
|
241
339
|
tags: string[];
|
|
242
340
|
|
|
243
341
|
/**
|
|
244
342
|
* Content rating of the image.
|
|
245
343
|
*
|
|
246
|
-
* `safe` - Image safe
|
|
344
|
+
* `safe` - Image safe for all audiences.
|
|
247
345
|
*
|
|
248
|
-
* `questionable` - Image may contain content
|
|
346
|
+
* `questionable` - Image may contain content unsuitable for some viewers.
|
|
249
347
|
*
|
|
250
|
-
* `nsfw` - Image contains content
|
|
348
|
+
* `nsfw` - Image contains adult content (Not Safe For Work).
|
|
251
349
|
*
|
|
350
|
+
* @type String
|
|
252
351
|
* @output 'safe' | 'questionable' | 'nsfw'
|
|
253
352
|
*/
|
|
254
353
|
rating: 'safe' | 'questionable' | 'nsfw';
|
|
255
354
|
|
|
256
355
|
/**
|
|
257
|
-
* Information about the anime (
|
|
356
|
+
* Information about the anime (or related media) the image may be associated with.
|
|
357
|
+
* @type Object
|
|
258
358
|
*/
|
|
259
359
|
anime: ImageAnime;
|
|
260
360
|
|
|
261
361
|
/**
|
|
262
|
-
*
|
|
362
|
+
* Details about the source of the image.
|
|
363
|
+
* @type Object
|
|
263
364
|
*/
|
|
264
365
|
source: ImageSource;
|
|
265
366
|
|
|
266
367
|
/**
|
|
267
|
-
*
|
|
368
|
+
* Information about the artist and the associated copyright of the image.
|
|
369
|
+
* @type Object
|
|
268
370
|
*/
|
|
269
371
|
attribution: ImageAttribution;
|
|
270
372
|
}
|
|
271
373
|
|
|
374
|
+
/**
|
|
375
|
+
* GET https://api.nekosia.cat/api/v1/tags
|
|
376
|
+
*/
|
|
377
|
+
interface TagsResponse {
|
|
378
|
+
status: number,
|
|
379
|
+
success: boolean,
|
|
380
|
+
tags: string[],
|
|
381
|
+
anime: string[],
|
|
382
|
+
characters: string[]
|
|
383
|
+
}
|
|
384
|
+
|
|
272
385
|
/**
|
|
273
386
|
* Nekosia API class, containing methods for fetching images.
|
|
274
|
-
* All methods are asynchronous and return a Promise
|
|
387
|
+
* All methods are asynchronous and return a Promise resolving to an `ImageResponse`.
|
|
275
388
|
*/
|
|
276
389
|
export class NekosiaAPI {
|
|
277
390
|
/**
|
|
@@ -280,73 +393,88 @@ declare module 'nekosia.js' {
|
|
|
280
393
|
* @param options - Configuration options for the request (optional).
|
|
281
394
|
* @example
|
|
282
395
|
* const { NekosiaAPI } = require('nekosia.js');
|
|
283
|
-
* await NekosiaAPI.
|
|
396
|
+
* await NekosiaAPI.fetchCategoryImages('catgirl', {
|
|
284
397
|
* count: 1,
|
|
285
398
|
* additionalTags: ['cute', 'sakura', 'cherry-blossom'],
|
|
286
399
|
* blacklistedTags: ['beret']
|
|
287
400
|
* });
|
|
288
|
-
* @
|
|
401
|
+
* @type Object
|
|
402
|
+
* @returns A Promise resolving to an `ImageResponse`.
|
|
289
403
|
*/
|
|
290
|
-
|
|
404
|
+
static fetchCategoryImages(category: AllTagsList, options?: FetchImagesCategoryOptions): Promise<ImageResponse>;
|
|
291
405
|
|
|
292
406
|
/**
|
|
293
407
|
* Fetches images based solely on the tags provided by the user. The main category does not affect the image selection as it is not provided here.
|
|
294
408
|
* @param options - Configuration options for the request (optional).
|
|
295
409
|
* @example
|
|
296
410
|
* const { NekosiaAPI } = require('nekosia.js');
|
|
297
|
-
* await NekosiaAPI.
|
|
411
|
+
* await NekosiaAPI.fetchImages({
|
|
298
412
|
* count: 1,
|
|
299
|
-
*
|
|
300
|
-
*
|
|
413
|
+
* tags: ['catgirl', 'foxgirl'],
|
|
414
|
+
* blacklist: ['dog-girl']
|
|
301
415
|
* });
|
|
302
|
-
* @
|
|
416
|
+
* @type Object
|
|
417
|
+
* @returns A Promise resolving to an `ImageResponse`.
|
|
418
|
+
*/
|
|
419
|
+
static fetchImages(options?: FetchImagesOptions): Promise<ImageResponse>;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Fetches the latest array with tags, anime titles, and characters
|
|
423
|
+
* @returns A Promise resolving to an `ImageResponse`.
|
|
303
424
|
*/
|
|
304
|
-
|
|
425
|
+
static fetchTags(id: string): Promise<TagsResponse>;
|
|
305
426
|
|
|
306
427
|
/**
|
|
307
428
|
* Fetches an image by its identifier.
|
|
308
429
|
* @param id - The image identifier (e.g., `66ae26a07886f165901e8a3f`).
|
|
309
|
-
* @
|
|
430
|
+
* @type Object
|
|
431
|
+
* @returns A Promise resolving to an `ImageResponse`.
|
|
310
432
|
*/
|
|
311
|
-
fetchById(id: string): Promise<ImageResponse>;
|
|
433
|
+
static fetchById(id: string): Promise<ImageResponse>;
|
|
312
434
|
}
|
|
313
435
|
|
|
314
436
|
/**
|
|
315
|
-
* JSON object response from the API
|
|
437
|
+
* JSON object response from the API containing information about the current version and related details.
|
|
316
438
|
*/
|
|
317
439
|
interface APIVersion {
|
|
318
440
|
/**
|
|
319
441
|
* HTTP status code of the response.
|
|
442
|
+
* @type Number
|
|
320
443
|
* @example 200
|
|
321
444
|
*/
|
|
322
445
|
status: number;
|
|
323
446
|
|
|
324
447
|
/**
|
|
325
448
|
* Indicates whether the request was successful.
|
|
449
|
+
* @type Boolean
|
|
326
450
|
* @example true
|
|
327
451
|
*/
|
|
328
452
|
success: boolean;
|
|
329
453
|
|
|
330
454
|
/**
|
|
331
455
|
* The current version of the API.
|
|
332
|
-
* @
|
|
456
|
+
* @type String
|
|
457
|
+
* @example "1.0.0"
|
|
333
458
|
*/
|
|
334
459
|
version: string;
|
|
335
460
|
|
|
336
461
|
/**
|
|
337
462
|
* URL to the API documentation.
|
|
338
|
-
* @
|
|
463
|
+
* @type String
|
|
464
|
+
* @example "https://nekosia.cat/documentation"
|
|
339
465
|
*/
|
|
340
466
|
documentation: string;
|
|
341
467
|
|
|
342
468
|
/**
|
|
343
|
-
* Contact email.
|
|
344
|
-
* @
|
|
469
|
+
* Contact email for inquiries.
|
|
470
|
+
* @type String
|
|
471
|
+
* @example "contact@nekosia.cat"
|
|
345
472
|
*/
|
|
346
473
|
contact: string;
|
|
347
474
|
|
|
348
475
|
/**
|
|
349
|
-
* List of available API
|
|
476
|
+
* List of available API versions.
|
|
477
|
+
* @type Array
|
|
350
478
|
* @example [1]
|
|
351
479
|
*/
|
|
352
480
|
apis: number[];
|
|
@@ -357,15 +485,17 @@ declare module 'nekosia.js' {
|
|
|
357
485
|
*/
|
|
358
486
|
export const NekosiaVersion: {
|
|
359
487
|
/**
|
|
360
|
-
*
|
|
361
|
-
* @example 1.1.0
|
|
362
|
-
* @
|
|
488
|
+
* Retrieves the current version of the module.
|
|
489
|
+
* @example "1.1.0"
|
|
490
|
+
* @type String
|
|
491
|
+
* @returns A string representing the module version.
|
|
363
492
|
*/
|
|
364
493
|
module: string;
|
|
365
494
|
|
|
366
495
|
/**
|
|
367
|
-
*
|
|
368
|
-
* @
|
|
496
|
+
* Fetches the current API version and related information.
|
|
497
|
+
* @type Object
|
|
498
|
+
* @returns A Promise that resolves to an `APIVersion` object.
|
|
369
499
|
*/
|
|
370
500
|
api(): Promise<APIVersion>;
|
|
371
501
|
};
|
package/types/tags.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const TAGS = [
|
|
2
|
-
'absolute-territory', 'after-the-rain', 'afternoon-tea', 'ahoge', 'air-comiket', 'ajitani-hifumi', 'akazukin', 'aksktrpg', 'akura', 'alice-in-wonderland', 'alice-margatroid', 'alice-tendou', 'alllisso', 'alluring-face', 'alone', 'amamine', 'amamineko-cafe', 'amashiro-natsuki', 'ame-nochi-yuki', 'ameto-yuki', 'angel', 'angry', 'angry-face', 'apex', 'apple', 'apple-pie', 'apron-dress', 'aqua', 'aquarium', 'areola-slip', 'aria-tsukushi', 'arknights', 'arknights-battle-illustration-contest', 'armed-girls', 'armpits', 'ashen-hair', 'ass', 'assault-rifle', 'autumn', 'autumn-leaves', 'axillary-costume', 'azki', 'azkiart', 'azur-lane', 'azur-lane-fleet', 'baby-face', 'babydoll', 'background', 'balloon', 'balloons', 'bandages', 'bandaid', 'bangtail', 'bare-feet', 'bare-soles', 'barefoot', 'barefoot-school-uniform', 'basketball', 'basketball-uniform', 'bath-time', 'bath-towel', 'beach', 'beach-ball', 'beast-girl', 'beautiful', 'beautiful-breasts', 'beautiful-reimu', 'bed', 'bed-hair', 'bedroom', 'belly', 'belly-glimpse', 'bellybutton', 'bench', 'beret', 'bewitching-thighs', 'big-breasts', 'bikini', 'bikini-top', 'birthday', 'black-and-white', 'black-bikini', 'black-dress', 'black-hair', 'black-hair-with-red-eyes', 'black-knee-high-socks', 'black-ribbon', 'black-sailor-uniform', 'black-shoes', 'black-stockings', 'black-thigh-high-socks', 'black-thigh-highs', 'black-tights', 'black-twintails', 'blazer', 'blonde', 'bloomers', 'blue', 'blue-archive', 'blue-eues', 'blue-eyes', 'blue-hair', 'blue-ribbon', 'blue-ribbono', 'blue-shoes', 'blue-skirt', 'blue-sky', 'bluearchive', 'blushing', 'bocchi-chan', 'botamochi', 'bottomless', 'bouquet', 'boy-cut', 'bra', 'braid', 'breast-hold', 'breasts', 'bride', 'brown-hair', 'bubble-tea', 'bubblegum', 'bue-eyes', 'bunny-ears', 'bunny-girl', 'butterfly', 'by-the-window', 'cable-knitting', 'cake', 'cameltoe', 'camisole', 'camisole-dress', 'canal', 'candy', 'candy-apple', 'car', 'cardigan', 'cardigan-uniform', 'casual-wear', 'cat', 'cat-and-girl', 'cat-ears', 'cat-ears-hat', 'cat-ears-headphones', 'cat-ears-hoodie', 'cat-ears-maid', 'cat-lingerie', 'cat-mouth', 'cat-pose', 'cat-tail', 'catgirl', 'celia-claire', 'celica', 'cheeks', 'cheerleader', 'chericot-rozel', 'cherry', 'cherry-blossom', 'cherry-petals', 'chest-outline', 'chibi', 'chihuahua', 'chin-resting', 'china-dress', 'chinese-lolita', 'chinese-style', 'chino', 'chino-kafuu', 'chitosezaka-suzu', 'chiyu', 'chocolate', 'chocolate-mint', 'choker', 'christmas', 'chuuni', 'classroom', 'cloak', 'closed-eyes', 'clouds', 'coffee', 'collar', 'collarbone', 'comic-treasure', 'confused', 'cookie', 'corset', 'cosmos', 'costume-change', 'crossed-legs', 'crying', 'cuite', 'cutaway-shoulder', 'cute', 'cute-cat', 'cuteness-is-justice', 'cyber', 'dakimakura-cover', 'dango', 'detexted', 'dnf', 'dog-and-girl', 'dog-ears', 'dog-girl', 'doggirl', 'donut', 'doujin', 'drawers', 'drawing-a-sword', 'dress', 'dress-shirt', 'dungeon-fighter-online', 'dvdart', 'ear-cleaning', 'elementary-school-student', 'elevator', 'enticing-brassiere', 'epic-seven', 'epic-seven-fan-art-illustration-contest', 'exposed-back', 'eye-mask', 'eyepatch', 'fairy-eye', 'fairy-tale', 'fallenshadow', 'fan-work', 'fantasy', 'fantasy-girl', 'feather-ears', 'feet', 'felicia-lulufleur', 'festival-of-white', 'fishnets', 'flare-skirt', 'flared-bikini', 'flat-chest', 'flower', 'flowers-and-girls', 'footwear', 'forest', 'fox-ears', 'fox-mask', 'fox-shrine-maiden', 'foxgirl', 'frills', 'fubuki-shiragami', 'fubuki-shiragami-fanart', 'futaba-sharo', 'fuwamoco', 'fuwawa', 'fuwawa-abyssgard', 'fuyoyo', 'fuzzy', 'fwmcpix', 'game', 'game-pad', 'gamer', 'gamer-girl', 'ganbare-ganbare', 'garter', 'garter-ring', 'garter-stockings', 'garterbelt', 'gawr-gura', 'gawrgura', 'gawrt', 'genshin-impact', 'gensokyo-in-spring', 'getting-dressed', 'gijinka', 'girl', 'girls', 'girls-frontline', 'glasses', 'gloves', 'gothic-lolita', 'greek-foot', 'green-eyes', 'green-hair', 'green-ribbon', 'guildcq', 'guitar', 'gun', 'gym-uniform', 'hairdressing', 'hairpin', 'hairstyle-change', 'hakui-koyori', 'half-pants', 'half-pigtails', 'half-up-hairstyle', 'halloween', 'halo', 'hamico', 'hammann', 'han-costume', 'hanami', 'hand-held-pigtails', 'hand-on-crotch', 'handcuffs', 'hands-forming-a-heart', 'harness', 'haruhara-shun', 'hayate-hisakawa', 'hazakura-chikori', 'headband', 'headboard-angle', 'headdress', 'headphone', 'headphones', 'headset', 'heart', 'heart-eyes', 'heartbreak', 'hearts', 'hedgehog', 'heels', 'heterochromia', 'hibiki', 'hibiscus', 'high-angle', 'high-leg-panties', 'high-school-girl', 'high-waisted-skirt', 'hiiro', 'hikaru', 'himura-moritaka', 'hirakata-kana', 'hizuki-miu', 'hizuki-rurufu', 'holding-hands-with-fingers-interlocked', 'holding-ice-in-mouth', 'holoadvent', 'hololive', 'hololive-en', 'hololive-english', 'hololiveen', 'holox', 'hong', 'hood', 'hoodie', 'hoshi', 'hoshino', 'hoshizora-no-memoria', 'hot-pants', 'hot-spring', 'houzuki-michiru', 'hu-tao', 'hutao', 'hyerang', 'ice-cream', 'ichigori-ena', 'idol', 'illumination', 'in-the-train', 'incredibly-cute', 'indie-virtual-youtuber', 'infamous-left-foot-defense', 'inflatable-pool', 'inner-color', 'inugami-korone', 'iochi-mari', 'itigori-ena', 'itou-yuna', 'izayoi-nonomi', 'jagged-sclera', 'japanese-clothes', 'japanese-maid', 'japanese-style', 'japanese-style-maid', 'japanese-umbrella', 'jersey', 'jk', 'joint-work', 'jumper-skirt', 'just-woke-up', 'kabashima-hana', 'kamiko-kana', 'kamioka-chiroru', 'kamisato-ayaka', 'kamiyama-shiki', 'kancolle', 'kantai-collection', 'kanzaki-ririka', 'karyl', 'katana', 'katcolle', 'kazari-rua', 'kigurumi', 'kimono', 'kimono-dress', 'kindergarten-pupil', 'kingdom', 'kirakira-monstars', 'kiryuu-kikyou', 'kitchen', 'knee-high-socks', 'kneeling', 'knockout-knockers', 'koahri', 'kohaku-nene', 'koharu', 'koiko-irori', 'koito-amuno', 'kokoro-amamiya', 'korie-riko', 'korone', 'koyori-hakui', 'koyori-sketch', 'kuda-izuna', 'kuro-namako', 'kuromi-serika', 'kuroneko', 'kurose-kiri', 'kyaru', 'lancat', 'lanmewko', 'lap-pillow', 'laplus-darkness', 'large-breasts', 'lattice-tower', 'leaning-forward', 'left-foot-shield', 'legato', 'leggings', 'lemon', 'leo', 'lifted-clothing', 'lily-of-the-valley', 'lime', 'lingerie', 'little-devil', 'lolicon-bait', 'lolipop-complete', 'lolita', 'lolita-fashion', 'lollipop', 'long-black-hair', 'long-blond-hair', 'long-gloves', 'long-hair', 'long-pink-hair', 'long-red-hair', 'long-white-gloves', 'long-white-hair', 'loungewear', 'lying-down', 'lying-on-one-side', 'macaron', 'machikaze-fuuna', 'mad', 'magical-girl', 'mahiro-oyama', 'maid', 'maid-bikini', 'maid-day', 'maid-uniform', 'makeup', 'mari-iochi', 'marie', 'marine-day', 'marine-look', 'maruro', 'mascot', 'matsumiya-kiseri', 'mayoi-shigure', 'mea-kagura', 'medium-hair', 'metaljelly', 'mf-bunko-j', 'middle-school-student', 'midriff', 'mihoshi-mei', 'miike-chan', 'mika', 'mika-misono', 'mikeneko', 'mikeneko-fanart', 'miko', 'minami-kotone', 'mini-hakama', 'miniskirt', 'miniskirt-miko', 'mirror', 'miu-channel', 'miu-hizuki', 'mizuki', 'mizukiart', 'mococo', 'mococo-abyssgard', 'mofumies', 'mole-under-the-eye', 'moon', 'msi', 'murasaki-shion', 'myoya', 'nachoneko', 'nagi-hisakawa', 'nail-polish', 'naked-navel', 'nap', 'natori-sana', 'navel-piercing', 'necktie', 'necomi', 'needs-to-be-appreciated-more', 'negligee', 'nekoha-shizuku', 'nekokobushi', 'nekomata-okayu', 'new-year', 'newsboy-cap', 'night', 'night-sky', 'nijisanji', 'nikke', 'nine-tailed', 'nkshoujo', 'no-game-no-life', 'noire', 'nolan', 'nonaka-yuu', 'not-wearing-any-panties', 'nurse', 'off-shoulder', 'off-shoulder-dress', 'okomeillust', 'okusora-ayane', 'old-fashioned-school-swimsuit', 'older-girl', 'omochi-box', 'omochi-monaka', 'one-eye-covered', 'one-piece', 'one-piece-swimsuit', 'ookami-mio', 'open-shirt', 'orange-ribbon', 'otokonoko', 'overalls', 'overly-long-sleeves', 'pajama', 'pajamas', 'panchira', 'panties', 'pantsu', 'panty-peek', 'pantyhose', 'parasol', 'parfait', 'patting', 'paw-pads', 'peace-sign', 'pee-holding', 'pekora-usada-fanart', 'personification-of-drinks', 'photo-editing', 'photoshop', 'piink', 'pillow', 'pinching-garments', 'pink', 'pink-eyes', 'pink-hair', 'pink-ribbon', 'pink-shoes', 'pink-skirt', 'pink-sweater', 'pink-twintails', 'plaid-pattern', 'plaid-skirt', 'plastic-bottle', 'platform', 'playing-cards', 'plump-thighs', 'plushie', 'pocky-day', 'pointy-ears', 'ponytail', 'pool', 'pool-at-night', 'porch', 'present', 'princess-connect', 'prone-position', 'psycho', 'purple-ears', 'purple-eyes', 'purple-hair', 'purple-ribbon', 'queen-of-hearts', 'rabbit-girl', 'ragna-doll', 'railroad-crossing', 'railway', 'rain', 'rainy-season', 'ramune', 'randoseru', 'rawr', 're-oekaki', 'red-and-blue', 'red-eyes', 'red-hair', 'red-pigtails', 'red-ribbon', 'red-shoes', 'red-skirt', 'reflected-glare', 'reimu-hakurei', 'remilia-scarlet', 'remiliacn', 'rena-yorumi', 'reverse-sitting', 'rhodes', 'ribbed-fabric', 'ribbon', 'ribbonos', 'ribbons', 'ringo-chan', 'roar', 'rocket-launcher', 'roxanne', 'rribbon', 'rubbib', 'rucaco', 'rukako', 'ruki-roki', 'rumi', 'runa-shinomiya', 'rushia-uruha', 'sad', 'saekiya-sabou', 'saiba-midori', 'saiba-momoi', 'sailor', 'sailor-dress', 'sailor-one-piece', 'sailor-swimsuit', 'sailor-uniform', 'sakamata-chloe', 'sakura', 'sakura-miko', 'sakuraba-moeka', 'sakurai-hana', 'sand', 'sandals', 'santa', 'santa-cosplay', 'sassy-loli', 'scared', 'scarf', 'scenery', 'sch', 'school-girl', 'school-swimsuit', 'school-uniform', 'school-uniform-cardigan', 'school-uniform-hoodie', 'schoolgirl', 'sea', 'see-through', 'selfie', 'serena-hanazono', 'setokane', 'shano-hiyori', 'shanoa-asmr', 'shigure', 'shimapan', 'shiori', 'shirakami-fubuki', 'shirakawa-yumea', 'shirasu-azusa', 'shiroko-terror', 'shiromichan', 'short-boots', 'short-haircut', 'short-pants', 'short-white-hair', 'shouu-kun', 'showgirl', 'side-string-bikini', 'side-tie-panty', 'silver-hair', 'silver-long-hair', 'singer', 'sisters', 'sitting', 'sitting-on-feet', 'sitting-with-hands-around-knees', 'skirt', 'skirt-lift', 'sleep', 'sleep-wear', 'sleeping-face', 'sleepy', 'sleepy-face', 'sleeveless', 'sleeveless-dress', 'sleeveless-parka', 'small-breasts', 'small-fangs', 'smile', 'snack-nili', 'snow', 'snow-leopard', 'snowman', 'socks', 'sofa', 'sole', 'somna', 'sotis', 'spiked-bat', 'spiral-eyes', 'splashes', 'spring', 'squirrel', 'stairs', 'standing-picture', 'starlight-stage', 'starry-sky', 'starry-sky-dress', 'steamed-bun-with-meat-filling', 'stirrup-leggings', 'stockings', 'straight-fringe', 'strap-shoes', 'strapless', 'straw-hat', 'strawberries', 'strawberry', 'string-ribbon', 'striped-bikini', 'striped-knee-highs', 'striped-thigh-high-socks', 'subculture', 'sukumizu', 'summer', 'summer-dress', 'summer-kimono', 'summer-pockets', 'summer-sky', 'sunaookami-shiroko', 'sunflower', 'sunflowers', 'sunglasses', 'sunohara-kokona', 'sunset', 'supine', 'suspender-skirt', 'suzuho-hotaru', 'sweat', 'sweater', 'swim-ring', 'swimsuit', 'swimsuit-parka', 'swimwear', 'sword', 't-shirt', 'tail', 'tail-from-under-skirt', 'tail-with-ribbon', 'taiwan', 'takanashi-hoshino', 'tattoo', 'tea', 'tea-time', 'tears', 'teary-eyed', 'teary-eyes', 'teketi', 'telephone', 'tenshinoikenie', 'the-person-behind', 'the-soles-of-feet-in-socks', 'theriantrope', 'thick-eyebrows', 'thigh-high-socks', 'thigh-highs', 'thighhighs', 'thighs', 'tie-side-bikini', 'tiger', 'tight', 'tired', 'toes', 'tokoshibyra', 'tongue-out', 'touhou', 'touhou-project', 'towel', 'transparency', 'tropical-fish', 'tsugiri-noa', 'tsurara', 'twin-pig-tails', 'twin-ponytails', 'twins', 'twintails', 'two-shot', 'uise-iu', 'umbrella', 'underwater', 'uniform', 'upwards-gaze', 'uruha-rushia-fanart', 'usada-pekora', 'usagigo', 'valentine', 'vampire', 'vdonburi', 'verslll', 'virtual', 'virtual-esports-project', 'vrchat', 'vtuber', 'w-sitting', 'waitress', 'wallpaper', 'water', 'water-surface', 'watermelon', 'wearing-only-a-shirt', 'wedding-dress', 'wet', 'wet-see-through', 'what-is-this-cuteness', 'white', 'white-bikini', 'white-cat', 'white-day', 'white-dress', 'white-hair', 'white-hairpin', 'white-high-socks', 'white-knee-high-socks', 'white-ribbon', 'white-sailor-uniform', 'white-school-swimsuit', 'white-socks', 'white-stockings', 'white-swimsuit', 'white-thigh-high-socks', 'white-tiger', 'white-tights', 'wide-brim-hat', 'wind-chime', 'winer', 'wings', 'wink', 'winter', 'witch', 'wolf-ears', 'wolf-girl', 'women-in-parka', 'yandere', 'yawn', 'year-of-the-tiger', 'yellow-bikini', 'yellow-eyes', 'yellow-hair', 'yellow-ribbon', 'yoko', 'young-girl', 'youtuber', 'yozuki-mofu', 'yuika-shiina', 'yukata', 'yukihana-lamy', 'yukikaze', 'yutori-natsu'
|
|
3
|
-
|
|
1
|
+
export const TAGS = ['absolute-territory','after-the-rain','afternoon-tea','ahoge','ajitani-hifumi','akazukin','aksktrpg','akura','alice-in-wonderland','alice-margatroid','alice-tendou','alllisso','alluring-face','alona','alone','amamine','amamineko-cafe','amashiro-natsuki','ame-nochi-yuki','ameto-yuki','angel','angry-face','animal-ears','apex','apple','apple-caramel','apple-pie','apron-dress','aqua','aquarium','areola-slip','aria-tsukushi','arknights','arknights-battle-illustration-contest','armed-girls','armpits','ashen-hair','assault-rifle','autumn','autumn-leaves','axillary-costume','azki','azkiart','azur-lane','babydoll','back-alley','background','balloon','balloons','bandages','bandaid','bangtail','bare-feet','bare-soles','barefoot','basketball','basketball-uniform','bath-time','bath-towel','beach','beach-ball','bear-ears','beargirl','beast-girl','beautiful','beautiful-reimu','bed','bed-hair','bedroom','belly','belly-glimpse','bellybutton','bench','beret','bewitching-thighs','bikini','bikini-top','birthday','black-and-white','black-bikini','black-dress','black-hair','black-hair-with-red-eyes','black-knee-high-socks','black-ribbon','black-sailor-uniform','black-shoes','black-skirt','black-stockings','black-thigh-high-socks','black-thigh-highs','black-tights','blazer','blonde','bloomers','blue-archive','blue-eues','blue-eyes','blue-hair','blue-ribbon','blue-shoes','blue-skirt','blue-sky','blushing','bocchi-chan','bondage','botamochi','bottomless','boy-cut','bra','braid','breast-hold','breasts','bride','brown-hair','bubble-tea','bunny-ears','bunny-girl','butterfly','by-the-window','cable-knitting','cake','cameltoe','camisole','camisole-dress','canal','candy','candy-apple','car','cardigan','cardigan-uniform','casual-wear','cat','cat-and-girl','cat-ears','cat-ears-hat','cat-ears-headphones','cat-ears-hoodie','cat-ears-maid','cat-mouth','cat-paws','cat-pose','cat-tail','catboy','catgirl','cats','celia-claire','celica','cheeks','cheerleader','chericot-rozel','cherry','cherry-blossom','cherry-petals','chess','chest-outline','chibi','chihuahua','chin-resting','chinese-lolita','chinese-style','chino','chino-kafuu','chitosezaka-suzu','chiyu','chocolate','chocolate-mint','choker','christmas','chuuni','classroom','cloak','closed-eyes','clouds','cocoa-hoto','coffee','collar','comic-treasure','confused','cookie','corset','cosmos','costume-change','cross-halter-bikini','crossed-legs','crying','cuite','cutaway-shoulder','cute','cute-cat','cuteness-is-justice','dakimakura-cover','dango','detexted','dog-and-girl','dog-ears','dog-girl','doll','donut','doujin','drawers','drawmei','dress','dress-shirt','dvdart','elementary-school-student','elevator','enticing-brassiere','epic-seven','exposed-back','eye-mask','eyepatch','fairy-eye','fairy-tale','fallenshadow','fantasy','fantasy-girl','feather-ears','feet','felicia-lulufleur','festival-of-white','firefly','fishnets','flare-skirt','flared-bikini','flat-chest','floral-playing-cards','flower','flowers-and-girls','forest','fox','fox-ears','fox-mask','fox-shrine-maiden','foxgirl','frills','fubuki-shiragami','fubuki-shiragami-fanart','fuwamoco','fuwawa-abyssgard','fuyoyo','fuzzy','fwmcpix','game','game-pad','gamer','gamer-girl','ganbare-ganbare','garter','garterbelt','gawr-gura','genshin-impact','gensokyo-in-spring','getting-dressed','gijinka','girl','girls','girls-frontline','glasses','gloves','gothic-lolita','greek-foot','green-eyes','green-hair','green-ribbon','guildcq','guitar','gun','gym-uniform','hairdressing','hairpin','hairstyle-change','hajime-todoroki','hakui-koyori','half-pants','half-pigtails','half-up-hairstyle','halloween','halo','hamico','hammock','han-costume','hanami','hands-forming-a-heart','harness','haruhara-shun','hayate-hisakawa','hazakura-chikori','headband','headboard-angle','headdress','headphone','headphones','headset','heart','heart-eyes','heartbreak','hearts','hedgehog','heels','herta','heterochromia','hibiki','hibiscus','high-angle','high-school-girl','high-waisted-skirt','hiiro','hikaru','himura-moritaka','hizuki-miu','hizuki-rurufu','holding-hands-with-fingers-interlocked','holding-ice-in-mouth','hololive','hololive-en','hololive-english','hololiveen','holox','hong','honkaistarrail','hood','hoodie','hoshi','hoshino','hoshitsuki-neiro','hoshizora-no-memoria','hot-spring','houzuki-michiru','hu-tao','hutao','hydrangea','ice-cream','ichigo','ichigori-ena','idol','illumination','in-the-train','incredibly-cute','indie-virtual-youtuber','indie-vtuber','indoor-shoes','infamous-left-foot-defense','inflatable-pool','inner-color','inugami-korone','itigori-ena','itou-yuna','izayoi-nonomi','jagged-sclera','japanese-clothes','japanese-maid','japanese-style','japanese-style-maid','japanese-umbrella','jersey','jk','jumper-skirt','jumpy','just-woke-up','kabashima-hana','kamiko-kana','kamioka-chiroru','kamisato-ayaka','kamiyama-shiki','kanade-otonose','kancolle','kantai-collection','kanzaki-ririka','karin','karyl','katana','katcolle','kazari-rua','kazueru','kazusa-kyoyama','kigurumi','kimono','kimono-dress','kindergarten-pupil','kingdom','kirakira-monstars','kiryuu-kikyou','kitchen','klee','knee-high-socks','kneeling','knockout-knockers','kohaku-nene','koharu','koiko-irori','koito-amuno','kokoro-amamiya','korie-riko','koyori-hakui','koyori-sketch','kuda-izuna','kuro-namako','kuromi-serika','kuroneko','kyaru','kyouyama-kazusa','lancat','lanmewko','lap-pillow','laplus-darkness','large-breasts','lattice-tower','left-foot-shield','legato','leggings','legs','lemon','leo','lily-of-the-valley','lime','lingerie','little-devil','lolipop-complete','lolita','lolita-fashion','lollipop','long-black-hair','long-blond-hair','long-gloves','long-hair','long-pink-hair','long-red-hair','long-white-gloves','long-white-hair','loungewear','lying-down','lying-on-one-side','macaron','machikaze-fuuna','mad','magical-girl','maid','maid-bikini','maid-uniform','makeup','mari-iochi','marie','marine','marine-day','marine-look','maruro','mascot','matsumiya-kiseri','mayoi-shigure','mea-kagura','medium-hair','mf-bunko-j','middle-school-student','midori-matsukaze','midriff','mihoshi-mei','miike-chan','mika','mika-misono','mikeneko','miko','miku-maekawa','minami-kotone','minato-aqua','mini-hakama','miniskirt','miniskirt-miko','mint','mirror','miu-channel','miu-hizuki','mizukiart','mococo','mococo-abyssgard','mole-under-the-eye','moon','murasaki-shion','muryo','myoya','nachoneko','nagi-hisakawa','nahida','nail-polish','nanashi-mumei','nap','natori-sana','necktie','necomi','needs-to-be-appreciated-more','negligee','nekoha-shizuku','nekomata-okayu','nene-kusanagi','new-year','newsboy-cap','night','night-sky','nijisanji','nikke','nine-tailed','nintendo-switch','nintendoswitch','no-game-no-life','noire','nolan','nonaka-yuu','nurse','off-shoulder','off-shoulder-dress','okomeillust','okusora-ayane','old-fashioned-school-swimsuit','older-girl','omochi-box','omochi-monaka','one-eye-covered','one-piece','one-piece-swimsuit','ookami-mio','open-shirt','orange-hair','orange-ribbon','otokonoko','overalls','overly-long-sleeves','pajamas','panchira','panda-ears','panties','pants','parasol','park','patting','paw-pads','peace-sign','pekora-usada-fanart','personification-of-drinks','photo-editing','pigtails','pillow','pinching-garments','pink','pink-eyes','pink-hair','pink-ribbon','pink-shoes','pink-skirt','pink-sweater','pink-twintails','plaid-pattern','plaid-skirt','plastic-bottle','platform','playing-cards','plump-thighs','plushie','pocky','pointy-ears','polar-bear','ponytail','pool','pool-at-night','porch','present','princess-connect','project-sekai','prone-position','psycho','pu-ht','purple-ears','purple-eyes','purple-hair','purple-ribbon','purple-skirt','queen-of-hearts','rabbit-girl','ragna-doll','railroad-crossing','railway','rain','rainy-season','ramune','randoseru','rawr','re-oekaki','red-and-blue','red-eyes','red-hair','red-pigtails','red-ribbon','red-ribbons','red-skirt','reflected-glare','regloss','reimu-hakurei','reisa-uzawa','remilia-scarlet','rena-yorumi','reverse-sitting','rhodes','ribbed-fabric','ribbon','ribbonos','ribbons','ringo-chan','roar','rocket-launcher','roxanne','rribbon','rubbib','rucaco','rukako','ruki-roki','rumi','runa-shinomiya','rurudo','rurudo-lion','rushia-uruha','sad','saekiya-sabou','saiba-midori','saiba-momoi','sailor','sailor-dress','sailor-one-piece','sailor-swimsuit','sailor-uniform','sakamata-chloe','sakura','sakura-miko','sakuraba-moeka','sakurada-hane','sakuradahane','sakurai-hana','sand','santa','santa-cosplay','sassy-loli','scared','scarf','scenery','school-swimsuit','school-uniform','school-uniform-cardigan','school-uniform-hoodie','schoolgirl','scornful-eyes','sea','see-through','selfie','setokane','shano-hiyori','shanoa-asmr','shigure','shiori','shirai-tanuki','shirakami-fubuki','shirakawa-yumea','shirasu-azusa','shiroko','shiroko-terror','shiromichan','shooting-star','short-boots','short-haircut','short-pants','short-white-hair','shouu-kun','showgirl','shy','side-string-bikini','side-tie-panty','silver-hair','silver-long-hair','singer','sisters','sitting','sitting-on-feet','sitting-with-hands-around-knees','skirt','skirt-lift','skirtm','sleep','sleep-wear','sleeping-face','sleepy','sleepy-face','sleeveless','sleeveless-dress','sleeveless-parka','small-breasts','small-fangs','smile','snack-nili','sneakers','snow','snow-leopard','snowman','snowy-landscape','socks','sofa','sole','somna','sorasaki-hina','spiral-eyes','splashes','spring','squirrel','stairs','standing-picture','starlight-stage','starry-sky','starry-sky-dress','steamed-bun-with-meat-filling','stockings','straight-fringe','strap-shoes','straw-hat','strawberries','strawberry','streaked-hair','string-ribbon','striped-bikini','striped-thigh-high-socks','sukumizu','summer','summer-dress','summer-kimono','summer-pockets','sunaookami-shiroko','sunflowers','sunglasses','sunohara-kokona','sunset','supine','suspender-skirt','suzuho-hotaru','sweat','sweater','sweets','swim-ring','swimsuit','swimsuit-parka','swimwear','swing','sword','t-shirt','tail','tail-from-under-skirt','tail-holding','tail-with-ribbon','taiwan','takanashi','takanashi-hoshino','tattoo','tea','tea-time','tears','teary-eyed','teary-eyes','telephone','tenshinoikenie','test','the-person-behind','the-soles-of-feet-in-socks','theriantrope','thick-eyebrows','thigh-high-socks','thigh-highs','thighhighs','thighs','tie-side-bikini','tiered-dress','tiger','tights','tired','tobu-railway','toes','tokoshibyra','tongue-out','touhou','touhou-project','towel','transparency','trick-or-treat','tropical-fish','tsugiri-noa','twins','twintails','uise-iu','umbrella','underwater','uniform','upwards-gaze','uruha-rushia-fanart','usada-pekora','usagigo','valentine','vampire','vdonburi','vrchat','vtuber','w-sitting','wa-lolita','waitress','wallpaper','water','water-surface','watermelon','weapon','wearing-only-a-shirt','wedding-dress','wet','wet-see-through','white-bikini','white-cat','white-day','white-dress','white-hair','white-hairpin','white-hait','white-high-socks','white-knee-high-socks','white-ribbon','white-sailor-uniform','white-school-swimsuit','white-skirt','white-socks','white-stockings','white-swimsuit','white-thigh-high-socks','white-tiger','white-tights','white-twintails','wings','wink','winter','witch','wolf-ears','wolf-girl','yandere','yaoyao','yawn','yellow-eyes','yellow-hair','yellow-ribbon','yoko','young-boy','young-girl','yuika-shiina','yukata','yukihana-lamy','yukinoshita-peo','yutori-natsu','yuuki-sakuna'] as const;
|
|
2
|
+
|
|
3
|
+
// https://api.nekosia.cat/api/v1/tags
|