yutaapis 1.0.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/LICENSE +21 -0
- package/README.md +2 -0
- package/lib/Routes/downloads/instagram.js +1 -0
- package/lib/Routes/downloads/ytaudio2.js +15 -0
- package/lib/Routes/geradores/geradores.js +12 -0
- package/lib/Routes/ias/ias.js +12 -0
- package/lib/Routes/pesquisa/github-search.js +21 -0
- package/lib/Routes/pesquisa/wikipedia.js +15 -0
- package/lib/Routes/pesquisa/yt-search.js +20 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/url.js +6 -0
- package/lib/Utils/validation.js +10 -0
- package/lib/client.js +70 -0
- package/lib/errors.js +16 -0
- package/lib/index.js +2 -0
- package/lib/request.js +60 -0
- package/lib/routes.js +71 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lm Only
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { request } from "../../request.js";
|
|
2
|
+
export default async function ytaudio2(opts) {
|
|
3
|
+
if (!opts.query) {
|
|
4
|
+
throw 'Parâmetro inválido - Está faltando';
|
|
5
|
+
}
|
|
6
|
+
return await request(opts.url, {
|
|
7
|
+
requestOptions: {
|
|
8
|
+
method: 'GET',
|
|
9
|
+
query: {
|
|
10
|
+
url: opts.query,
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
dataType: 'JSON'
|
|
14
|
+
}, 0, opts);
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { request } from "../../request.js";
|
|
2
|
+
export default async function geradores(opts, dataType) {
|
|
3
|
+
return await request(opts.url, {
|
|
4
|
+
requestOptions: {
|
|
5
|
+
method: 'GET',
|
|
6
|
+
query: {
|
|
7
|
+
text: opts.query
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
dataType: dataType
|
|
11
|
+
}, 0, opts);
|
|
12
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { request } from "../../request.js";
|
|
2
|
+
export default async function gitstalk(opts) {
|
|
3
|
+
if (!opts.query) {
|
|
4
|
+
throw 'Parâmetro inválido - Está faltando';
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
return await request(opts.url, {
|
|
8
|
+
requestOptions: {
|
|
9
|
+
method: 'GET',
|
|
10
|
+
query: {
|
|
11
|
+
username: opts.query,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
dataType: 'JSON'
|
|
15
|
+
}, 0, opts);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error('API_ERROR: ' + error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { request } from "../../request.js";
|
|
2
|
+
export default async function wiki(opts) {
|
|
3
|
+
if (!opts.query) {
|
|
4
|
+
throw 'Parâmetro inválido - Está faltando';
|
|
5
|
+
}
|
|
6
|
+
return await request(opts.url, {
|
|
7
|
+
requestOptions: {
|
|
8
|
+
method: 'GET',
|
|
9
|
+
query: {
|
|
10
|
+
query: opts.query,
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
dataType: 'JSON'
|
|
14
|
+
}, 0, opts);
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { request } from "../../request.js";
|
|
2
|
+
export default async function ytsearch(opts) {
|
|
3
|
+
if (!opts.query) {
|
|
4
|
+
throw 'Parâmetro inválido - Está faltando';
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
return await request(opts.url, {
|
|
8
|
+
requestOptions: {
|
|
9
|
+
method: 'GET',
|
|
10
|
+
query: {
|
|
11
|
+
query: opts.query,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
dataType: 'JSON'
|
|
15
|
+
}, 0, opts);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error('API_ERROR: ' + error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './validation.js';
|
package/lib/Utils/url.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analisa se o token tem as características da API token do yuta.
|
|
3
|
+
* Ele vai checar se a string tem o tamnho adequado
|
|
4
|
+
* Se o começo é previsto igual o do token e etc
|
|
5
|
+
*
|
|
6
|
+
* @param apiToken Suposta API Token do Yuta
|
|
7
|
+
*/
|
|
8
|
+
export function isYutaApiToken(apiToken) {
|
|
9
|
+
return apiToken.startsWith('yuta_') && apiToken.length >= 30;
|
|
10
|
+
}
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2026 Yuta & Hutao bot community
|
|
5
|
+
* Yuta APIs - Em parceria com HutaoBot
|
|
6
|
+
*
|
|
7
|
+
* @author Lm Only and Nk Petrov
|
|
8
|
+
*/
|
|
9
|
+
import { routes } from "./routes.js";
|
|
10
|
+
import { isYutaApiToken } from "./Utils/index.js";
|
|
11
|
+
const BASE_YUTA_API_URL = 'https://yuta-apis.xyz/api';
|
|
12
|
+
export class YutaApis {
|
|
13
|
+
apiToken;
|
|
14
|
+
url;
|
|
15
|
+
config;
|
|
16
|
+
httpOptions;
|
|
17
|
+
get ias() {
|
|
18
|
+
const baseUrl = this.url;
|
|
19
|
+
if (!baseUrl) {
|
|
20
|
+
throw new Error('baseUrl is not defined');
|
|
21
|
+
}
|
|
22
|
+
return routes({
|
|
23
|
+
...this.config,
|
|
24
|
+
route: 'ias'
|
|
25
|
+
}).ias;
|
|
26
|
+
}
|
|
27
|
+
get geradores() {
|
|
28
|
+
const baseUrl = this.url;
|
|
29
|
+
if (!baseUrl) {
|
|
30
|
+
throw new Error('baseUrl is not defined');
|
|
31
|
+
}
|
|
32
|
+
return routes({
|
|
33
|
+
...this.config,
|
|
34
|
+
route: 'geradores'
|
|
35
|
+
}).geradores;
|
|
36
|
+
}
|
|
37
|
+
get downloads() {
|
|
38
|
+
const baseUrl = this.url;
|
|
39
|
+
if (!baseUrl) {
|
|
40
|
+
throw new Error('baseUrl is not defined');
|
|
41
|
+
}
|
|
42
|
+
return routes({
|
|
43
|
+
...this.config,
|
|
44
|
+
route: 'downloads'
|
|
45
|
+
}).downloads;
|
|
46
|
+
}
|
|
47
|
+
get pesquisas() {
|
|
48
|
+
const baseUrl = this.url;
|
|
49
|
+
if (!baseUrl) {
|
|
50
|
+
throw new Error('baseUrl is not defined');
|
|
51
|
+
}
|
|
52
|
+
return routes({
|
|
53
|
+
...this.config,
|
|
54
|
+
route: 'pesquisas'
|
|
55
|
+
}).pesquisas;
|
|
56
|
+
}
|
|
57
|
+
constructor(opts = {}) {
|
|
58
|
+
if (!opts.apiToken || !isYutaApiToken(String(opts.apiToken))) {
|
|
59
|
+
throw new Error('apiToken is not defined');
|
|
60
|
+
}
|
|
61
|
+
this.apiToken = opts.apiToken;
|
|
62
|
+
this.httpOptions = opts.httpOptions ?? {};
|
|
63
|
+
this.url = opts.httpOptions?.baseUrl ?? BASE_YUTA_API_URL;
|
|
64
|
+
this.config = {
|
|
65
|
+
headers: this.httpOptions?.headers ?? {},
|
|
66
|
+
apitoken: this.apiToken,
|
|
67
|
+
baseUrl: this.url
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
package/lib/errors.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2026 Yuta & Hutao bot community
|
|
5
|
+
* Yuta APIs - Em parceria com HutaoBot
|
|
6
|
+
*
|
|
7
|
+
* @author Lm Only and Nk Petrov
|
|
8
|
+
*/
|
|
9
|
+
export class RequestError extends Error {
|
|
10
|
+
statusCode;
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
super(opts.message);
|
|
13
|
+
this.statusCode = opts.statusCode;
|
|
14
|
+
Object.setPrototypeOf(this, RequestError.prototype);
|
|
15
|
+
}
|
|
16
|
+
}
|
package/lib/index.js
ADDED
package/lib/request.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2026 Yuta & Hutao bot community
|
|
5
|
+
* Yuta APIs - Em parceria com HutaoBot
|
|
6
|
+
*
|
|
7
|
+
* @author Lm Only and Nk Petrov
|
|
8
|
+
*/
|
|
9
|
+
import { request as httpRequest } from 'undici';
|
|
10
|
+
import { RequestError } from './errors.js';
|
|
11
|
+
async function getBodyByType(body, dataType) {
|
|
12
|
+
if (!dataType)
|
|
13
|
+
return (await body.text());
|
|
14
|
+
switch (dataType.toUpperCase()) {
|
|
15
|
+
case 'JSON': return (await body.json());
|
|
16
|
+
case 'TEXT': return (await body.text());
|
|
17
|
+
case 'BUFFER': return Buffer.from(await body.arrayBuffer());
|
|
18
|
+
default: return (await body.text());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function request(url, opts, redirectCount = 0, otherOpts) {
|
|
22
|
+
if (redirectCount > 5) {
|
|
23
|
+
throw new RequestError({ statusCode: 310, message: 'MAX_REDIRECTS' });
|
|
24
|
+
}
|
|
25
|
+
opts.requestOptions.query.apitoken = otherOpts.apitoken;
|
|
26
|
+
opts.requestOptions.headers = {
|
|
27
|
+
...opts.requestOptions.headers,
|
|
28
|
+
...otherOpts.headers,
|
|
29
|
+
};
|
|
30
|
+
const { statusCode, headers, body } = await httpRequest(url, opts.requestOptions);
|
|
31
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
32
|
+
return await getBodyByType(body, opts.dataType);
|
|
33
|
+
}
|
|
34
|
+
const locationHeader = headers.location;
|
|
35
|
+
if (statusCode >= 300 && statusCode < 400 && locationHeader) {
|
|
36
|
+
await body.dump();
|
|
37
|
+
const targetUrl = Array.isArray(locationHeader) ? locationHeader[0] : locationHeader;
|
|
38
|
+
return request(targetUrl, opts, redirectCount + 1, otherOpts);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Aqui é pra quando der erro e a API retornar algo
|
|
42
|
+
* Evitando retornar erro mal detalhado
|
|
43
|
+
* Mas se caso a API não retornar nada
|
|
44
|
+
* Segue pra erro desconhecido .
|
|
45
|
+
*/
|
|
46
|
+
try {
|
|
47
|
+
const responseError = await getBodyByType(body, opts.dataType);
|
|
48
|
+
const hasResponseApi = Array.isArray(responseError) || typeof responseError !== 'undefined';
|
|
49
|
+
if (hasResponseApi) {
|
|
50
|
+
return responseError;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
await body.dump().catch(() => { });
|
|
55
|
+
}
|
|
56
|
+
throw new RequestError({
|
|
57
|
+
statusCode,
|
|
58
|
+
message: 'REQ_FAILED',
|
|
59
|
+
});
|
|
60
|
+
}
|
package/lib/routes.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2026 Yuta & Hutao bot community
|
|
5
|
+
* Yuta APIs - Em parceria com HutaoBot
|
|
6
|
+
*
|
|
7
|
+
* @author Lm Only and Nk Petrov
|
|
8
|
+
*/
|
|
9
|
+
import gitstalk from "./Routes/pesquisa/github-search.js";
|
|
10
|
+
import ytsearch from "./Routes/pesquisa/yt-search.js";
|
|
11
|
+
import ytaudio2 from "./Routes/downloads/ytaudio2.js";
|
|
12
|
+
import wiki from "./Routes/pesquisa/wikipedia.js";
|
|
13
|
+
import { urlFormatString } from "./Utils/url.js";
|
|
14
|
+
import ias from "./Routes/ias/ias.js";
|
|
15
|
+
import geradores from "./Routes/geradores/geradores.js";
|
|
16
|
+
export function routes(opts) {
|
|
17
|
+
return {
|
|
18
|
+
pesquisas: {
|
|
19
|
+
ytsearch: async (query) => await ytsearch({
|
|
20
|
+
...opts, query,
|
|
21
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'yt-search')
|
|
22
|
+
}),
|
|
23
|
+
gitstalk: async (query) => await gitstalk({
|
|
24
|
+
...opts, query,
|
|
25
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'github-stalker')
|
|
26
|
+
}),
|
|
27
|
+
wiki: async (query) => await wiki({
|
|
28
|
+
...opts, query,
|
|
29
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'wiki-search')
|
|
30
|
+
})
|
|
31
|
+
},
|
|
32
|
+
downloads: {
|
|
33
|
+
ytaudio2: async (query) => await ytaudio2({
|
|
34
|
+
...opts, query,
|
|
35
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'ytaudio2')
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
ias: {
|
|
39
|
+
gpt: async (query) => await ias({
|
|
40
|
+
...opts, query,
|
|
41
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'gpt')
|
|
42
|
+
}, 'JSON'),
|
|
43
|
+
gemini: async (query) => await ias({
|
|
44
|
+
...opts, query,
|
|
45
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'gemini')
|
|
46
|
+
}, 'JSON'),
|
|
47
|
+
gemini_pro: async (query) => await ias({
|
|
48
|
+
...opts, query,
|
|
49
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'gemini-pro')
|
|
50
|
+
}, 'JSON'),
|
|
51
|
+
geminivoz: async (query) => await ias({
|
|
52
|
+
...opts, query,
|
|
53
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'geminivoz')
|
|
54
|
+
}, 'BUFFER'),
|
|
55
|
+
perplexity_ai: async (query) => await ias({
|
|
56
|
+
...opts, query,
|
|
57
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'perplexity-ai')
|
|
58
|
+
}, 'JSON')
|
|
59
|
+
},
|
|
60
|
+
geradores: {
|
|
61
|
+
nick: async (query) => await geradores({
|
|
62
|
+
...opts, query,
|
|
63
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'gerar-nicks')
|
|
64
|
+
}, 'JSON'),
|
|
65
|
+
qrcode: async (query) => await geradores({
|
|
66
|
+
...opts, query,
|
|
67
|
+
url: urlFormatString(opts.baseUrl, opts.route, 'qrcode')
|
|
68
|
+
}, 'BUFFER'),
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yutaapis",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Módulo TS/JavaScript que se conecta com a API Oficial do Yuta",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"api",
|
|
7
|
+
"nodejs",
|
|
8
|
+
"web"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/Lm-Only/yutaapis#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/Lm-Only/yutaapis/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/Lm-Only/yutaapis.git"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"lib"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Lm-Only",
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "lib/index.js",
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^26.4.0",
|
|
30
|
+
"dotenv": "^17.4.2",
|
|
31
|
+
"typescript": "^7.0.2"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"undici": "^8.10.0"
|
|
35
|
+
},
|
|
36
|
+
"allowScripts": {
|
|
37
|
+
"esbuild@0.28.2": true
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=20.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|