fivelive.js 0.2.2 → 0.3.1
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 +145 -120
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.cts +13 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +3 -3
- package/package.json +8 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Five Network
|
|
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
CHANGED
|
@@ -1,181 +1,206 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<br />
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://live.fivenetwork.dev/developers"><img src="https://live.fivenetwork.dev/brand/five-mark-blue.png" width="120" alt="Five Live" /></a>
|
|
5
|
+
</p>
|
|
6
|
+
<h1>fivelive.js</h1>
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://www.npmjs.com/package/fivelive.js"><img src="https://img.shields.io/npm/v/fivelive.js.svg?maxAge=3600&color=3b6cf6" alt="versão no npm" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/fivelive.js"><img src="https://img.shields.io/npm/dt/fivelive.js.svg?maxAge=3600&color=3b6cf6" alt="downloads no npm" /></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/fivelive.js"><img src="https://img.shields.io/node/v/fivelive.js.svg?color=3b6cf6" alt="versão do Node" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/fivelive.js"><img src="https://img.shields.io/npm/types/fivelive.js.svg?color=3b6cf6" alt="tipos TypeScript" /></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/fivelive.js"><img src="https://img.shields.io/npm/l/fivelive.js.svg?color=3b6cf6" alt="licença" /></a>
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
<a href="https://live.fivenetwork.dev/developers/docs"><b>Documentação</b></a> ·
|
|
16
|
+
<a href="https://live.fivenetwork.dev/developers/docs/primeiro-bot"><b>Primeiro bot</b></a> ·
|
|
17
|
+
<a href="https://live.fivenetwork.dev/developers"><b>Portal do desenvolvedor</b></a>
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
## Sobre
|
|
22
|
+
|
|
23
|
+
**fivelive.js** é o SDK oficial para criar bots do [Five Live](https://live.fivenetwork.dev) em Node.js.
|
|
24
|
+
|
|
25
|
+
- Orientado a objetos: `Message`, `Channel`, `Group` e `User`, cada um com os próprios métodos (`message.reply()`, `channel.send()`, `group.kick()`…)
|
|
26
|
+
- Tempo real: mensagens, reações, “digitando…”, quem entra e quem sai, tudo por eventos
|
|
27
|
+
- **Comandos de barra (`/`)**: quem digita `/` no grupo vê os comandos do seu bot, com descrição e argumentos
|
|
28
|
+
- Reconecta sozinho, respeita os limites da API e tenta de novo quando precisa
|
|
29
|
+
- Tipos TypeScript incluídos, e funciona com `import` e com `require`
|
|
30
|
+
- Se você já fez bot com **discord.js**, vai se sentir em casa ([veja a comparação](#vindo-do-discordjs))
|
|
31
|
+
|
|
32
|
+
## Instalação
|
|
33
|
+
|
|
34
|
+
**Node.js 18 ou mais novo.**
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm install fivelive.js
|
|
38
|
+
yarn add fivelive.js
|
|
39
|
+
pnpm add fivelive.js
|
|
40
|
+
bun add fivelive.js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Pacotes opcionais
|
|
44
|
+
|
|
45
|
+
- [ws](https://www.npmjs.com/package/ws): o WebSocket no Node 18 e 20 (o Node 22+ já tem um nativo). É instalado junto automaticamente.
|
|
46
|
+
|
|
47
|
+
## Exemplo
|
|
2
48
|
|
|
3
|
-
|
|
49
|
+
Crie o bot em **[live.fivenetwork.dev/developers](https://live.fivenetwork.dev/developers)**, copie o token (começa com `b_`) e adicione o bot a um grupo pelo link da aba **Instalação**.
|
|
4
50
|
|
|
5
51
|
```js
|
|
6
|
-
import { Client } from "fivelive.js";
|
|
52
|
+
import { Client, EmbedBuilder } from "fivelive.js";
|
|
7
53
|
|
|
8
|
-
const client = new Client({ token: process.env.FIVELIVE_TOKEN });
|
|
54
|
+
const client = new Client({ token: process.env.FIVELIVE_TOKEN, prefix: "/" });
|
|
9
55
|
|
|
10
|
-
client.on("ready", (bot) => console.log(`Online como ${bot.displayName}
|
|
56
|
+
client.on("ready", (bot) => console.log(`Online como ${bot.displayName}!`));
|
|
11
57
|
|
|
58
|
+
// Aparece na lista quando alguém digita "/" no grupo.
|
|
12
59
|
client.command({
|
|
13
60
|
name: "ping",
|
|
61
|
+
description: "Responde pong",
|
|
14
62
|
run: ({ reply }) => reply("🏓 pong!"),
|
|
15
63
|
});
|
|
16
64
|
|
|
17
|
-
client.
|
|
18
|
-
|
|
65
|
+
client.command({
|
|
66
|
+
name: "info",
|
|
67
|
+
description: "Mostra o grupo",
|
|
68
|
+
run: ({ message, reply }) =>
|
|
69
|
+
reply({
|
|
70
|
+
embeds: [
|
|
71
|
+
new EmbedBuilder()
|
|
72
|
+
.setTitle(message.group.name)
|
|
73
|
+
.addFields({ name: "Membros", value: String(message.group.memberCount), inline: true })
|
|
74
|
+
.setColor("#3b6cf6"),
|
|
75
|
+
],
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
19
78
|
|
|
20
|
-
|
|
79
|
+
client.on("memberAdd", ({ user, group }) => group?.channel("geral")?.send(`Bem-vindo(a), ${user}!`));
|
|
21
80
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
3. Instale e rode:
|
|
81
|
+
client.login();
|
|
82
|
+
```
|
|
25
83
|
|
|
26
|
-
```
|
|
27
|
-
npm install fivelive.js
|
|
84
|
+
```sh
|
|
28
85
|
FIVELIVE_TOKEN=b_seu_token node bot.mjs
|
|
29
86
|
```
|
|
30
87
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Eventos
|
|
88
|
+
## Guia rápido
|
|
34
89
|
|
|
35
|
-
|
|
36
|
-
client.on("messageCreate", async (message) => {
|
|
37
|
-
if (message.content === "oi") await message.reply(`Oi, ${message.author}!`);
|
|
38
|
-
});
|
|
39
|
-
```
|
|
90
|
+
### Eventos
|
|
40
91
|
|
|
41
92
|
| Evento | Recebe |
|
|
42
93
|
|---|---|
|
|
43
94
|
| `ready` | o usuário do bot, depois de conectar e carregar os grupos |
|
|
44
95
|
| `messageCreate` | `Message` nova (as do próprio bot não chegam; as de outros bots só com `ignoreBots: false`) |
|
|
45
|
-
| `messageUpdate` | `Message` editada |
|
|
46
|
-
| `messageDelete` | `{ id, groupId, channelId }` |
|
|
96
|
+
| `messageUpdate` / `messageDelete` | `Message` editada / `{ id, groupId, channelId }` |
|
|
47
97
|
| `reactionUpdate` | `{ messageId, groupId, channelId, reactions }` |
|
|
48
98
|
| `typingStart` | `{ userId, name, groupId, channelId }` |
|
|
49
|
-
| `memberAdd` | `{ user, group, groupId, via }
|
|
50
|
-
| `memberRemove` | `{ userId, user, group, groupId, reason, by }` —
|
|
51
|
-
| `groupJoin`
|
|
52
|
-
| `groupLeave` | `{ id, reason }`, quando o bot sai, é expulso ou o grupo é apagado |
|
|
53
|
-
| `groupUpdate` | `Group`, quando o grupo muda (nome, salas, cargos) |
|
|
99
|
+
| `memberAdd` | `{ user, group, groupId, via }` — alguém entrou num grupo do bot |
|
|
100
|
+
| `memberRemove` | `{ userId, user, group, groupId, reason, by }` — `left`, `kicked` ou `banned` |
|
|
101
|
+
| `groupJoin` / `groupLeave` / `groupUpdate` | o bot entrou, saiu ou o grupo mudou |
|
|
54
102
|
| `reconnecting` / `reconnected` / `disconnect` | a conexão caiu e voltou sozinha |
|
|
55
|
-
| `error`
|
|
56
|
-
| `commandError` | `(error, context)`, quando um comando lança um erro |
|
|
103
|
+
| `error` / `commandError` | erros (o segundo recebe o contexto do comando) |
|
|
57
104
|
|
|
58
|
-
|
|
105
|
+
### Comandos de barra (/)
|
|
59
106
|
|
|
60
|
-
|
|
61
|
-
const client = new Client({ token, prefix: "!" });
|
|
107
|
+
Todo `client.command` com `description` aparece na lista do `/`. O `login()` manda a lista sozinho.
|
|
62
108
|
|
|
109
|
+
```js
|
|
63
110
|
client.command({
|
|
64
|
-
name: "
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
111
|
+
name: "ban",
|
|
112
|
+
description: "Bane alguém do grupo",
|
|
113
|
+
options: [
|
|
114
|
+
{ name: "usuario", description: "Quem banir", required: true, type: "user" },
|
|
115
|
+
{ name: "motivo", description: "Por quê" },
|
|
116
|
+
],
|
|
117
|
+
run: async ({ message, args, reply }) => {
|
|
118
|
+
const alvo = message.mentions.users[0];
|
|
119
|
+
if (!alvo) return reply("Use: /ban @pessoa motivo");
|
|
120
|
+
await message.group.ban(alvo, args.slice(1).join(" ") || "sem motivo");
|
|
121
|
+
await reply(`<@${alvo}> foi banido(a).`);
|
|
71
122
|
},
|
|
72
123
|
});
|
|
73
124
|
```
|
|
74
125
|
|
|
75
|
-
|
|
126
|
+
Até 25 comandos por bot. Sem `description`, o comando funciona pelo prefixo mas fica fora da lista. Registrou mais comandos depois do `login()`? Chame `client.syncCommands()`.
|
|
127
|
+
|
|
128
|
+
### Mensagens, menções e embeds
|
|
76
129
|
|
|
77
130
|
```js
|
|
78
|
-
await message.reply("
|
|
79
|
-
await message.channel.send(
|
|
131
|
+
await message.reply("citando a mensagem");
|
|
132
|
+
await message.channel.send({ content: `Oi, ${message.author}!`, roleMentions: [roleId] });
|
|
80
133
|
await message.react("👍");
|
|
81
|
-
await message.
|
|
134
|
+
await message.pin();
|
|
82
135
|
|
|
83
136
|
const minha = await message.channel.send("vou editar");
|
|
84
137
|
await minha.edit("editada");
|
|
85
|
-
await minha.delete();
|
|
86
|
-
|
|
87
|
-
message.content // o texto como está gravado, com as menções como <@id>
|
|
88
|
-
message.cleanContent // com as menções trocadas por @nome
|
|
89
|
-
message.author // User: id, username, displayName, avatarURL, bot
|
|
90
|
-
message.mentions // { users: [...ids], roles: [...ids], everyone }
|
|
91
|
-
message.mentionsMe // se mencionou o bot
|
|
92
|
-
message.group / message.channel
|
|
93
|
-
```
|
|
138
|
+
await minha.delete();
|
|
94
139
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```js
|
|
98
|
-
import { userMention } from "fivelive.js";
|
|
99
|
-
|
|
100
|
-
await channel.send(`Bem-vindo, ${userMention(id)}!`); // ou `${message.author}`
|
|
101
|
-
await channel.send({ content: "Atenção, mods", roleMentions: [roleId] });
|
|
102
|
-
await channel.send({ content: "Todo mundo!", everyone: true }); // precisa da permissão
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
A menção avisa a pessoa, igual a uma menção feita por alguém do grupo. As permissões do cargo do bot valem normalmente ("Mencionar membros", "Mencionar @everyone", cargo mencionável).
|
|
106
|
-
|
|
107
|
-
### Embeds
|
|
108
|
-
|
|
109
|
-
```js
|
|
110
|
-
import { EmbedBuilder } from "fivelive.js";
|
|
111
|
-
|
|
112
|
-
const embed = new EmbedBuilder()
|
|
113
|
-
.setTitle("Placar")
|
|
114
|
-
.setDescription("Resultado da rodada")
|
|
115
|
-
.setColor("#3b6cf6")
|
|
116
|
-
.setAuthor({ name: "Five Bot", iconURL: "https://..." })
|
|
117
|
-
.addFields(
|
|
118
|
-
{ name: "Time A", value: "3", inline: true },
|
|
119
|
-
{ name: "Time B", value: "1", inline: true },
|
|
120
|
-
)
|
|
121
|
-
.setImage("https://...")
|
|
122
|
-
.setFooter({ text: "Five Live" })
|
|
123
|
-
.setTimestamp();
|
|
124
|
-
|
|
125
|
-
await message.channel.send({ content: "Fim de jogo!", embeds: [embed] });
|
|
140
|
+
message.cleanContent; // texto com <@id> trocado por @nome
|
|
141
|
+
message.mentionsMe; // se mencionou o bot
|
|
126
142
|
```
|
|
127
143
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```js
|
|
131
|
-
for (const group of client.groups.values()) {
|
|
132
|
-
console.log(group.name, [...group.channels.values()].map((c) => c.name));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const geral = client.groups.get(groupId).channel("geral"); // pelo id ou pelo nome
|
|
136
|
-
await geral.send("Bom dia!");
|
|
137
|
-
|
|
138
|
-
const historico = await geral.fetchMessages({ limit: 20 });
|
|
139
|
-
const membros = await group.fetchMembers(); // com roleIds, owner e online
|
|
140
|
-
const pessoa = await client.fetchUser(userId);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## Moderação
|
|
144
|
+
### Grupos e moderação
|
|
144
145
|
|
|
145
146
|
Tudo respeita as permissões do cargo do bot e a hierarquia: ele só age em quem está abaixo do cargo mais alto dele.
|
|
146
147
|
|
|
147
148
|
```js
|
|
149
|
+
const group = client.groups.get(groupId);
|
|
150
|
+
await group.channel("geral").send("Bom dia!"); // sala pelo id ou pelo nome
|
|
151
|
+
const membros = await group.fetchMembers(); // com roleIds, owner e online
|
|
152
|
+
|
|
148
153
|
if (group.can("kickMembers")) await group.kick(userId);
|
|
149
|
-
await group.ban(userId, "flood");
|
|
150
|
-
await group.
|
|
151
|
-
const banidos = await group.fetchBans();
|
|
152
|
-
await group.addRole(userId, roleId); // manageRoles
|
|
153
|
-
await group.removeRole(userId, roleId);
|
|
154
|
-
await message.pin(); // manageMessages
|
|
155
|
-
await message.delete(); // de outras pessoas: manageMessages
|
|
156
|
-
await group.leave();
|
|
154
|
+
await group.ban(userId, "flood");
|
|
155
|
+
await group.addRole(userId, roleId);
|
|
157
156
|
```
|
|
158
157
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- **60 mensagens por minuto** por bot. Passando disso, o SDK espera o tempo que a API pede e tenta de novo sozinho.
|
|
162
|
-
- Texto de até **2000** caracteres e até **10 embeds** por mensagem.
|
|
163
|
-
- O bot só vê os grupos em que foi adicionado, e só as salas de texto.
|
|
158
|
+
### Erros e limites
|
|
164
159
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Uma chamada recusada
|
|
160
|
+
- 60 mensagens por minuto por bot; ao passar disso, o SDK espera o tempo que a API pede e tenta de novo.
|
|
161
|
+
- Até 2000 caracteres e 10 embeds por mensagem.
|
|
162
|
+
- Uma chamada recusada lança `FiveLiveAPIError`, com `status`, `method` e `path`.
|
|
168
163
|
|
|
169
164
|
```js
|
|
170
165
|
import { FiveLiveAPIError } from "fivelive.js";
|
|
171
166
|
|
|
172
167
|
try {
|
|
173
|
-
await
|
|
168
|
+
await group.kick(userId);
|
|
174
169
|
} catch (err) {
|
|
175
|
-
if (err instanceof FiveLiveAPIError && err.status === 403) console.log("
|
|
170
|
+
if (err instanceof FiveLiveAPIError && err.status === 403) console.log("Sem permissão.");
|
|
176
171
|
}
|
|
177
172
|
```
|
|
178
173
|
|
|
179
|
-
##
|
|
174
|
+
## Vindo do discord.js
|
|
180
175
|
|
|
181
|
-
|
|
176
|
+
| discord.js | fivelive.js |
|
|
177
|
+
|---|---|
|
|
178
|
+
| `new Client({ intents: [...] })` | `new Client({ token })` — sem intents: o bot recebe tudo dos grupos em que está |
|
|
179
|
+
| `client.login(token)` | `client.login()` (o token vai no `Client`) |
|
|
180
|
+
| `Guild` / `message.guild` | `Group` / `message.group` |
|
|
181
|
+
| `TextChannel` / `channel.send()` | `Channel` / `channel.send()` |
|
|
182
|
+
| `SlashCommandBuilder` + `interactionCreate` | `client.command({ name, description, options, run })` |
|
|
183
|
+
| `interaction.reply()` | `reply()` no contexto do comando |
|
|
184
|
+
| `guildMemberAdd` / `guildMemberRemove` | `memberAdd` / `memberRemove` |
|
|
185
|
+
| `messageReactionAdd` / `Remove` | `reactionUpdate` (a lista inteira, atualizada) |
|
|
186
|
+
| `EmbedBuilder` | `EmbedBuilder` (os mesmos métodos) |
|
|
187
|
+
| `member.kick()` / `guild.members.ban()` | `group.kick(userId)` / `group.ban(userId, motivo)` |
|
|
188
|
+
| `member.roles.add()` | `group.addRole(userId, roleId)` |
|
|
189
|
+
| `<@id>` | `<@id>` (igual) |
|
|
190
|
+
|
|
191
|
+
## Links
|
|
192
|
+
|
|
193
|
+
- [Documentação](https://live.fivenetwork.dev/developers/docs) — gateway, permissões, moderação, OAuth2, webhooks
|
|
194
|
+
- [Primeiro bot](https://live.fivenetwork.dev/developers/docs/primeiro-bot) — do zero ao bot funcionando
|
|
195
|
+
- [Comandos de barra](https://live.fivenetwork.dev/developers/docs/comandos-de-barra)
|
|
196
|
+
- [Exemplos prontos](https://live.fivenetwork.dev/developers/docs/exemplos) — boas-vindas, moderação, cargos por reação
|
|
197
|
+
- [Portal do desenvolvedor](https://live.fivenetwork.dev/developers) — criar bots, token, OAuth2 e instalação
|
|
198
|
+
- [Five Live](https://live.fivenetwork.dev)
|
|
199
|
+
|
|
200
|
+
## Ajuda
|
|
201
|
+
|
|
202
|
+
Travou em algo? Comece pela [documentação](https://live.fivenetwork.dev/developers/docs). Se o problema continuar, fale com a equipe pelo [Five Live](https://live.fivenetwork.dev).
|
|
203
|
+
|
|
204
|
+
## Licença
|
|
205
|
+
|
|
206
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var U=Object.create;var y=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var M=(r,t)=>{for(var e in t)y(r,e,{get:t[e],enumerable:!0})},$=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of S(t))!C.call(r,i)&&i!==e&&y(r,i,{get:()=>t[i],enumerable:!(s=x(t,i))||s.enumerable});return r};var E=(r,t,e)=>(e=r!=null?U(T(r)):{},$(t||!r||!r.__esModule?y(e,"default",{value:r,enumerable:!0}):e,r)),A=r=>$(y({},"__esModule",{value:!0}),r);var B={};M(B,{Channel:()=>f,Client:()=>w,EmbedBuilder:()=>I,FiveLiveAPIError:()=>g,Group:()=>l,Message:()=>h,REST:()=>d,User:()=>u,channelMention:()=>v,userMention:()=>_});module.exports=A(B);var k=require("node:events");var g=class extends Error{constructor(t,e,s,i){super(t),this.name="FiveLiveAPIError",this.status=e,this.method=s,this.path=i}},L=r=>new Promise(t=>setTimeout(t,r)),d=class{constructor(t){this.token=t.token,this.apiUrl=t.apiUrl.replace(/\/$/,""),this.retries=t.retries??3}async request(t,e,s){for(let i=0;;i++){let a=await fetch(this.apiUrl+e,{method:t,headers:{Authorization:`Bot ${this.token}`,...s!==void 0?{"Content-Type":"application/json"}:{},"User-Agent":"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)"},body:s!==void 0?JSON.stringify(s):void 0}),o=await a.json().catch(()=>({}));if(a.status===429&&i<this.retries){let c=Number(o.retryAfter??a.headers.get("retry-after")??5);await L(Math.max(1,c)*1e3);continue}if(!a.ok)throw new g(o.error??`HTTP ${a.status}`,a.status,t,e);return o}}get(t){return this.request("GET",t)}post(t,e){return this.request("POST",t,e??{})}patch(t,e){return this.request("PATCH",t,e??{})}put(t,e){return this.request("PUT",t,e??{})}delete(t){return this.request("DELETE",t)}},n=encodeURIComponent;var _=r=>`<@${r}>`,v=r=>`<#${r}>`;function b(r){let t=typeof r=="string"?{content:r}:r??{},e=(t.embeds??[]).map(i=>typeof i?.toJSON=="function"?i.toJSON():i),s=(t.roleMentions??[]).map(i=>`@role:${i}`);return{text:t.content??"",...e.length?{embeds:e}:{},...t.mentions?.length||s.length||t.everyone?{mentions:[...t.mentions??[],...s,...t.everyone?["@everyone"]:[]]}:{},...t.reply?{replyTo:typeof t.reply=="string"?t.reply:t.reply.id}:{}}}var u=class{constructor(t,e){this.client=t,this.id=e.id,this.username=e.username??null,this.displayName=e.displayName??e.name??e.username??"",this.avatarURL=e.avatarUrl??null,this.bot=e.bot===!0,this.flags=e.flags??[]}toString(){return _(this.id)}},f=class{constructor(t,e,s){this.client=t,this.group=e,this.id=s.id,this.name=s.name,this.kind=s.kind,this.categoryId=s.categoryId??null,this.topic=s.topic??""}get isText(){return this.kind==="text"}get path(){return`/bot/groups/${n(this.group.id)}/channels/${n(this.id)}`}async send(t){let e=await this.client.rest.post(`${this.path}/messages`,b(t));return new h(this.client,e.message,this.client.user)}async sendTyping(){await this.client.rest.post(`${this.path}/typing`,{typing:!0})}async fetchMessages(t={}){let e=new URLSearchParams;return t.limit&&e.set("limit",String(t.limit)),t.after&&e.set("after",t.after),(await this.client.rest.get(`${this.path}/messages?${e}`)).messages.map(i=>new h(this.client,i))}async fetchMessage(t){let e=await this.client.rest.get(`${this.path}/messages/${n(t)}`);return new h(this.client,e.message)}toString(){return`<#${this.id}>`}},l=class{constructor(t,e){this.client=t,this._patch(e)}_patch(t){this.id=t.id,this.name=t.name,this.iconURL=t.iconUrl??null,this.ownerId=t.ownerId??null,this.memberCount=t.memberCount??0,this.roles=t.roles??[],this.permissions=t.permissions??{},this.channels=new Map((t.channels??[]).map(e=>[e.id,new f(this.client,this,e)]))}channel(t){return this.channels.get(t)??[...this.channels.values()].find(e=>e.name===t)??null}async fetchMembers(){return(await this.client.rest.get(`/bot/groups/${n(this.id)}/members`)).members.map(e=>({...e,user:this.client._cacheUser(e)}))}get path(){return`/bot/groups/${n(this.id)}`}can(t){return this.permissions.administrator===!0||this.permissions[t]===!0}async kick(t){await this.client.rest.post(`${this.path}/members/${n(t)}/kick`,{})}async ban(t,e){await this.client.rest.put(`${this.path}/bans/${n(t)}`,e?{reason:e}:{})}async unban(t){await this.client.rest.delete(`${this.path}/bans/${n(t)}`)}async fetchBans(){return(await this.client.rest.get(`${this.path}/bans`)).bans}async addRole(t,e){return(await this.client.rest.put(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async removeRole(t,e){return(await this.client.rest.delete(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async leave(){await this.client.rest.post(`${this.path}/leave`,{})}role(t){return this.roles.find(e=>e.id===t||e.name===t)??null}},h=class r{constructor(t,e,s){this.client=t,this.id=e.id,this.groupId=e.groupId,this.channelId=e.channelId,this.content=e.text??"",this.embeds=e.embeds??[],this.attachments=e.attachments??[],this.images=e.images??[],this.reactions=e.reactions??[],this.replyTo=e.replyTo??null,this.createdAt=new Date(e.ts??Date.now()),this.editedAt=e.editedAt?new Date(e.editedAt):null,this.pinned=!!e.pinnedAt,this.webhook=!!e.webhook;let i=e.mentions??[];this.mentions={users:i.filter(a=>!a.startsWith("@")),roles:i.filter(a=>a.startsWith("@role:")).map(a=>a.slice(6)),everyone:i.includes("@everyone"),raw:i},this.author=s instanceof u?s:s?t._cacheUser(s):t.users.get(e.from)??new u(t,{id:e.from,name:e.fromName})}get group(){return this.client.groups.get(this.groupId)??null}get channel(){return this.group?.channels.get(this.channelId)??null}get cleanContent(){return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g,(t,e)=>{let s=this.client.users.get(e);return s?`@${s.displayName}`:t})}get mentionsMe(){return this.mentions.users.includes(this.client.user?.id)||this.mentions.everyone}get path(){return`/bot/groups/${n(this.groupId)}/channels/${n(this.channelId)}/messages`}async reply(t){let e=b(t),s=await this.client.rest.post(this.path,{...e,replyTo:this.id});return new r(this.client,s.message,this.client.user)}async edit(t){let e=b(t),s=await this.client.rest.patch(`${this.path}/${n(this.id)}`,{text:e.text,...e.embeds?{embeds:e.embeds}:{}});return new r(this.client,s.message,this.author)}async pin(){await this.client.rest.put(`${this.path}/${n(this.id)}/pin`)}async unpin(){await this.client.rest.delete(`${this.path}/${n(this.id)}/pin`)}async delete(){await this.client.rest.delete(`${this.path}/${n(this.id)}`)}async react(t){await this.client.rest.put(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}async unreact(t){await this.client.rest.delete(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}};var N="https://api.fivenetwork.dev",R=3e4,P=3e4;async function D(){if(typeof globalThis.WebSocket=="function")return globalThis.WebSocket;try{let r=await import("ws");return r.default??r.WebSocket}catch{throw new Error("Este Node n\xE3o tem WebSocket nativo (\xE9 do Node 22+). Rode `npm install ws` ou atualize o Node.")}}var w=class extends k.EventEmitter{constructor(t){if(super(),!t?.token||!String(t.token).startsWith("b_"))throw new Error("Passe o token do bot (come\xE7a com b_). Pegue em https://live.fivenetwork.dev/developers.");this.token=t.token,this.apiUrl=(t.apiUrl??N).replace(/\/$/,""),this.gatewayUrl=t.gatewayUrl??`${this.apiUrl.replace(/^http/,"ws")}/ws`,this.prefix=t.prefix??"!",this.ignoreBots=t.ignoreBots??!0,this.rest=new d({token:this.token,apiUrl:this.apiUrl}),this.user=null,this.groups=new Map,this.users=new Map,this.commands=new Map,this._ws=null,this._ready=!1,this._closing=!1,this._attempt=0,this._keepalive=null}command(t){this.commands.set(t.name.toLowerCase(),t);for(let e of t.aliases??[])this.commands.set(e.toLowerCase(),t);return this}async _runCommand(t){if(!this.commands.size||!t.content.startsWith(this.prefix))return;let[e,...s]=t.content.slice(this.prefix.length).trim().split(/\s+/),i=this.commands.get((e??"").toLowerCase());if(!i)return;let a={message:t,args:s,client:this,reply:o=>t.reply(o)};try{await i.run(a)}catch(o){this.listenerCount("commandError")?this.emit("commandError",o,a):this.emit("error",o)}}async login(){let t=await this.rest.get("/bot/@me");return this.user=this._cacheUser({...t.bot,bot:!0}),await this._loadGroups(),this._closing=!1,await this._connect(),this.user}destroy(){this._closing=!0,clearInterval(this._keepalive);try{this._ws?.close()}catch{}}async _loadGroups(){let t=await this.rest.get("/bot/groups"),e=new Set;for(let s of t.groups){e.add(s.id);let i=this.groups.get(s.id);i?i._patch(s):this.groups.set(s.id,new l(this,s))}for(let s of[...this.groups.keys()])e.has(s)||this.groups.delete(s)}async fetchGroup(t){let e=await this.rest.get(`/bot/groups/${encodeURIComponent(t)}`),s=this.groups.get(t);return s?s._patch(e.group):this.groups.set(t,new l(this,e.group)),this.groups.get(t)}async fetchUser(t){let e=await this.rest.get(`/bot/users/${encodeURIComponent(t)}`);return this._cacheUser(e.user)}_cacheUser(t){let e=new u(this,t);return this.users.set(e.id,e),e}async _connect(){let t=await D();return new Promise((e,s)=>{let i=new t(this.gatewayUrl);this._ws=i;let a=!1,o=c=>{i.readyState===1&&i.send(JSON.stringify(c))};i.onopen=()=>{o({type:"register",name:this.user.displayName||this.user.username,token:this.token}),clearInterval(this._keepalive),this._keepalive=setInterval(()=>o({type:"time-sync",t0:Date.now()}),R)},i.onmessage=c=>{let m;try{m=JSON.parse(typeof c.data=="string"?c.data:c.data.toString())}catch{return}if(m.type==="registered"){let p=!this._ready;this._ready=!0,this._attempt=0,a||(a=!0,e()),p?this.emit("ready",this.user):this.emit("reconnected");return}if(m.type==="register-error"){this._closing=!0;let p=new Error(m.message||"O Five Live recusou o token do bot.");a?this.emit("error",p):(a=!0,s(p));return}this._dispatch(m).catch(p=>this.emit("error",p))},i.onerror=c=>{!a&&this._attempt===0&&!this._ready&&(a=!0,s(new Error(`N\xE3o foi poss\xEDvel conectar em ${this.gatewayUrl}: ${c?.message??"erro de rede"}`)))},i.onclose=()=>{clearInterval(this._keepalive),this.emit("disconnect"),!(this._closing||!this._ready)&&this._reconnect()}})}_reconnect(){this._attempt+=1;let t=Math.min(P,1e3*2**Math.min(this._attempt-1,5))+Math.random()*500;this.emit("reconnecting",this._attempt),setTimeout(async()=>{if(!this._closing)try{await this._loadGroups(),await this._connect()}catch{this._reconnect()}},t)}async _dispatch(t){switch(t.type){case"group-message":{if(!t.message)return;let e=new h(this,t.message,t.author?{...t.author}:void 0);if(e.author.id===this.user?.id||this.ignoreBots&&e.author.bot)return;this.emit("messageCreate",e),await this._runCommand(e);return}case"group-message-updated":t.message&&this.emit("messageUpdate",new h(this,t.message));return;case"group-message-deleted":this.emit("messageDelete",{id:t.messageId,groupId:t.groupId,channelId:t.channelId});return;case"group-message-reactions":this.emit("reactionUpdate",{messageId:t.messageId,groupId:t.groupId,channelId:t.channelId,reactions:t.reactions??[]});return;case"group-typing":t.userId!==this.user?.id&&t.typing!==!1&&this.emit("typingStart",{userId:t.userId,name:t.name,groupId:t.groupId,channelId:t.channelId});return;case"group-joined":{let e=await this.fetchGroup(t.groupId);this.emit("groupJoin",e);return}case"group-updated":{if(!this.groups.has(t.groupId))return;let e=await this.fetchGroup(t.groupId).catch(()=>null);e&&this.emit("groupUpdate",e);return}case"group-member-add":{if(!t.member)return;let e=this._cacheUser(t.member),s=this.groups.get(t.groupId)??await this.fetchGroup(t.groupId).catch(()=>null);s&&(s.memberCount+=1),this.emit("memberAdd",{user:e,group:s,groupId:t.groupId,via:t.via??null});return}case"group-member-remove":{let e=this.groups.get(t.groupId)??null;e&&(e.memberCount=Math.max(0,e.memberCount-1)),this.emit("memberRemove",{userId:t.userId,user:this.users.get(t.userId)??null,group:e,groupId:t.groupId,reason:t.reason??null,by:t.by??null});return}case"group-removed":this.groups.delete(t.groupId),this.emit("groupLeave",{id:t.groupId,reason:t.reason??null});return;default:this.emit("raw",t)}}};function G(r){if(typeof r=="number")return r;let t=String(r).replace(/^#/,"");return/^[0-9a-f]{6}$/i.test(t)?parseInt(t,16):void 0}var I=class{constructor(t={}){this.data={...t}}setTitle(t){return this.data.title=t,this}setDescription(t){return this.data.description=t,this}setURL(t){return this.data.url=t,this}setColor(t){return this.data.color=G(t),this}setAuthor(t){return this.data.author={name:t.name,url:t.url,icon_url:t.iconURL},this}setFooter(t){return this.data.footer={text:t.text,icon_url:t.iconURL},this}setImage(t){return this.data.image={url:t},this}setThumbnail(t){return this.data.thumbnail={url:t},this}setTimestamp(t=new Date){return this.data.timestamp=new Date(t).toISOString(),this}addFields(...t){return this.data.fields=[...this.data.fields??[],...t.flat()],this}toJSON(){return this.data}};0&&(module.exports={Channel,Client,EmbedBuilder,FiveLiveAPIError,Group,Message,REST,User,channelMention,userMention});
|
|
1
|
+
"use strict";var U=Object.create;var y=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty;var M=(i,t)=>{for(var e in t)y(i,e,{get:t[e],enumerable:!0})},$=(i,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of S(t))!T.call(i,r)&&r!==e&&y(i,r,{get:()=>t[r],enumerable:!(s=x(t,r))||s.enumerable});return i};var E=(i,t,e)=>(e=i!=null?U(C(i)):{},$(t||!i||!i.__esModule?y(e,"default",{value:i,enumerable:!0}):e,i)),A=i=>$(y({},"__esModule",{value:!0}),i);var B={};M(B,{Channel:()=>f,Client:()=>w,EmbedBuilder:()=>I,FiveLiveAPIError:()=>g,Group:()=>l,Message:()=>h,REST:()=>d,User:()=>u,channelMention:()=>v,userMention:()=>_});module.exports=A(B);var k=require("node:events");var g=class extends Error{constructor(t,e,s,r){super(t),this.name="FiveLiveAPIError",this.status=e,this.method=s,this.path=r}},L=i=>new Promise(t=>setTimeout(t,i)),d=class{constructor(t){this.token=t.token,this.apiUrl=t.apiUrl.replace(/\/$/,""),this.retries=t.retries??3}async request(t,e,s){for(let r=0;;r++){let a=await fetch(this.apiUrl+e,{method:t,headers:{Authorization:`Bot ${this.token}`,...s!==void 0?{"Content-Type":"application/json"}:{},"User-Agent":"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)"},body:s!==void 0?JSON.stringify(s):void 0}),o=await a.json().catch(()=>({}));if(a.status===429&&r<this.retries){let c=Number(o.retryAfter??a.headers.get("retry-after")??5);await L(Math.max(1,c)*1e3);continue}if(!a.ok)throw new g(o.error??`HTTP ${a.status}`,a.status,t,e);return o}}get(t){return this.request("GET",t)}post(t,e){return this.request("POST",t,e??{})}patch(t,e){return this.request("PATCH",t,e??{})}put(t,e){return this.request("PUT",t,e??{})}delete(t){return this.request("DELETE",t)}},n=encodeURIComponent;var _=i=>`<@${i}>`,v=i=>`<#${i}>`;function b(i){let t=typeof i=="string"?{content:i}:i??{},e=(t.embeds??[]).map(r=>typeof r?.toJSON=="function"?r.toJSON():r),s=(t.roleMentions??[]).map(r=>`@role:${r}`);return{text:t.content??"",...e.length?{embeds:e}:{},...t.mentions?.length||s.length||t.everyone?{mentions:[...t.mentions??[],...s,...t.everyone?["@everyone"]:[]]}:{},...t.reply?{replyTo:typeof t.reply=="string"?t.reply:t.reply.id}:{}}}var u=class{constructor(t,e){this.client=t,this.id=e.id,this.username=e.username??null,this.displayName=e.displayName??e.name??e.username??"",this.avatarURL=e.avatarUrl??null,this.bot=e.bot===!0,this.flags=e.flags??[]}toString(){return _(this.id)}},f=class{constructor(t,e,s){this.client=t,this.group=e,this.id=s.id,this.name=s.name,this.kind=s.kind,this.categoryId=s.categoryId??null,this.topic=s.topic??""}get isText(){return this.kind==="text"}get path(){return`/bot/groups/${n(this.group.id)}/channels/${n(this.id)}`}async send(t){let e=await this.client.rest.post(`${this.path}/messages`,b(t));return new h(this.client,e.message,this.client.user)}async sendTyping(){await this.client.rest.post(`${this.path}/typing`,{typing:!0})}async fetchMessages(t={}){let e=new URLSearchParams;return t.limit&&e.set("limit",String(t.limit)),t.after&&e.set("after",t.after),(await this.client.rest.get(`${this.path}/messages?${e}`)).messages.map(r=>new h(this.client,r))}async fetchMessage(t){let e=await this.client.rest.get(`${this.path}/messages/${n(t)}`);return new h(this.client,e.message)}toString(){return`<#${this.id}>`}},l=class{constructor(t,e){this.client=t,this._patch(e)}_patch(t){this.id=t.id,this.name=t.name,this.iconURL=t.iconUrl??null,this.ownerId=t.ownerId??null,this.memberCount=t.memberCount??0,this.roles=t.roles??[],this.permissions=t.permissions??{},this.channels=new Map((t.channels??[]).map(e=>[e.id,new f(this.client,this,e)]))}channel(t){return this.channels.get(t)??[...this.channels.values()].find(e=>e.name===t)??null}async fetchMembers(){return(await this.client.rest.get(`/bot/groups/${n(this.id)}/members`)).members.map(e=>({...e,user:this.client._cacheUser(e)}))}get path(){return`/bot/groups/${n(this.id)}`}can(t){return this.permissions.administrator===!0||this.permissions[t]===!0}async kick(t){await this.client.rest.post(`${this.path}/members/${n(t)}/kick`,{})}async ban(t,e){await this.client.rest.put(`${this.path}/bans/${n(t)}`,e?{reason:e}:{})}async unban(t){await this.client.rest.delete(`${this.path}/bans/${n(t)}`)}async fetchBans(){return(await this.client.rest.get(`${this.path}/bans`)).bans}async addRole(t,e){return(await this.client.rest.put(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async removeRole(t,e){return(await this.client.rest.delete(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async leave(){await this.client.rest.post(`${this.path}/leave`,{})}role(t){return this.roles.find(e=>e.id===t||e.name===t)??null}},h=class i{constructor(t,e,s){this.client=t,this.id=e.id,this.groupId=e.groupId,this.channelId=e.channelId,this.content=e.text??"",this.embeds=e.embeds??[],this.attachments=e.attachments??[],this.images=e.images??[],this.reactions=e.reactions??[],this.replyTo=e.replyTo??null,this.createdAt=new Date(e.ts??Date.now()),this.editedAt=e.editedAt?new Date(e.editedAt):null,this.pinned=!!e.pinnedAt,this.webhook=!!e.webhook;let r=e.mentions??[];this.mentions={users:r.filter(a=>!a.startsWith("@")),roles:r.filter(a=>a.startsWith("@role:")).map(a=>a.slice(6)),everyone:r.includes("@everyone"),raw:r},this.author=s instanceof u?s:s?t._cacheUser(s):t.users.get(e.from)??new u(t,{id:e.from,name:e.fromName})}get group(){return this.client.groups.get(this.groupId)??null}get channel(){return this.group?.channels.get(this.channelId)??null}get cleanContent(){return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g,(t,e)=>{let s=this.client.users.get(e);return s?`@${s.displayName}`:t})}get mentionsMe(){return this.mentions.users.includes(this.client.user?.id)||this.mentions.everyone}get path(){return`/bot/groups/${n(this.groupId)}/channels/${n(this.channelId)}/messages`}async reply(t){let e=b(t),s=await this.client.rest.post(this.path,{...e,replyTo:this.id});return new i(this.client,s.message,this.client.user)}async edit(t){let e=b(t),s=await this.client.rest.patch(`${this.path}/${n(this.id)}`,{text:e.text,...e.embeds?{embeds:e.embeds}:{}});return new i(this.client,s.message,this.author)}async pin(){await this.client.rest.put(`${this.path}/${n(this.id)}/pin`)}async unpin(){await this.client.rest.delete(`${this.path}/${n(this.id)}/pin`)}async delete(){await this.client.rest.delete(`${this.path}/${n(this.id)}`)}async react(t){await this.client.rest.put(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}async unreact(t){await this.client.rest.delete(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}};var N="https://api.fivenetwork.dev",R=3e4,P=3e4;async function D(){if(typeof globalThis.WebSocket=="function")return globalThis.WebSocket;try{let i=await import("ws");return i.default??i.WebSocket}catch{throw new Error("Este Node n\xE3o tem WebSocket nativo (\xE9 do Node 22+). Rode `npm install ws` ou atualize o Node.")}}var w=class extends k.EventEmitter{constructor(t){if(super(),!t?.token||!String(t.token).startsWith("b_"))throw new Error("Passe o token do bot (come\xE7a com b_). Pegue em https://live.fivenetwork.dev/developers.");this.token=t.token,this.apiUrl=(t.apiUrl??N).replace(/\/$/,""),this.gatewayUrl=t.gatewayUrl??`${this.apiUrl.replace(/^http/,"ws")}/ws`,this.prefix=t.prefix??"!",this.ignoreBots=t.ignoreBots??!0,this.rest=new d({token:this.token,apiUrl:this.apiUrl}),this.user=null,this.groups=new Map,this.users=new Map,this.commands=new Map,this._ws=null,this._ready=!1,this._closing=!1,this._attempt=0,this._keepalive=null}command(t){this.commands.set(t.name.toLowerCase(),t);for(let e of t.aliases??[])this.commands.set(e.toLowerCase(),t);return this}async syncCommands(){let t=new Set,e=[];for(let s of this.commands.values())t.has(s.name)||!s.description||(t.add(s.name),e.push({name:s.name,description:s.description,options:s.options??[]}));try{await this.rest.put("/bot/commands",{prefix:this.prefix,commands:e})}catch(s){this.emit("error",s)}}async _runCommand(t){if(!this.commands.size||!t.content.startsWith(this.prefix))return;let[e,...s]=t.content.slice(this.prefix.length).trim().split(/\s+/),r=this.commands.get((e??"").toLowerCase());if(!r)return;let a={message:t,args:s,client:this,reply:o=>t.reply(o)};try{await r.run(a)}catch(o){this.listenerCount("commandError")?this.emit("commandError",o,a):this.emit("error",o)}}async login(){let t=await this.rest.get("/bot/@me");return this.user=this._cacheUser({...t.bot,bot:!0}),await this._loadGroups(),await this.syncCommands(),this._closing=!1,await this._connect(),this.user}destroy(){this._closing=!0,clearInterval(this._keepalive);try{this._ws?.close()}catch{}}async _loadGroups(){let t=await this.rest.get("/bot/groups"),e=new Set;for(let s of t.groups){e.add(s.id);let r=this.groups.get(s.id);r?r._patch(s):this.groups.set(s.id,new l(this,s))}for(let s of[...this.groups.keys()])e.has(s)||this.groups.delete(s)}async fetchGroup(t){let e=await this.rest.get(`/bot/groups/${encodeURIComponent(t)}`),s=this.groups.get(t);return s?s._patch(e.group):this.groups.set(t,new l(this,e.group)),this.groups.get(t)}async fetchUser(t){let e=await this.rest.get(`/bot/users/${encodeURIComponent(t)}`);return this._cacheUser(e.user)}_cacheUser(t){let e=new u(this,t);return this.users.set(e.id,e),e}async _connect(){let t=await D();return new Promise((e,s)=>{let r=new t(this.gatewayUrl);this._ws=r;let a=!1,o=c=>{r.readyState===1&&r.send(JSON.stringify(c))};r.onopen=()=>{o({type:"register",name:this.user.displayName||this.user.username,token:this.token}),clearInterval(this._keepalive),this._keepalive=setInterval(()=>o({type:"time-sync",t0:Date.now()}),R)},r.onmessage=c=>{let m;try{m=JSON.parse(typeof c.data=="string"?c.data:c.data.toString())}catch{return}if(m.type==="registered"){let p=!this._ready;this._ready=!0,this._attempt=0,a||(a=!0,e()),p?this.emit("ready",this.user):this.emit("reconnected");return}if(m.type==="register-error"){this._closing=!0;let p=new Error(m.message||"O Five Live recusou o token do bot.");a?this.emit("error",p):(a=!0,s(p));return}this._dispatch(m).catch(p=>this.emit("error",p))},r.onerror=c=>{!a&&this._attempt===0&&!this._ready&&(a=!0,s(new Error(`N\xE3o foi poss\xEDvel conectar em ${this.gatewayUrl}: ${c?.message??"erro de rede"}`)))},r.onclose=()=>{clearInterval(this._keepalive),this.emit("disconnect"),!(this._closing||!this._ready)&&this._reconnect()}})}_reconnect(){this._attempt+=1;let t=Math.min(P,1e3*2**Math.min(this._attempt-1,5))+Math.random()*500;this.emit("reconnecting",this._attempt),setTimeout(async()=>{if(!this._closing)try{await this._loadGroups(),await this._connect()}catch{this._reconnect()}},t)}async _dispatch(t){switch(t.type){case"group-message":{if(!t.message)return;let e=new h(this,t.message,t.author?{...t.author}:void 0);if(e.author.id===this.user?.id||this.ignoreBots&&e.author.bot)return;this.emit("messageCreate",e),await this._runCommand(e);return}case"group-message-updated":t.message&&this.emit("messageUpdate",new h(this,t.message));return;case"group-message-deleted":this.emit("messageDelete",{id:t.messageId,groupId:t.groupId,channelId:t.channelId});return;case"group-message-reactions":this.emit("reactionUpdate",{messageId:t.messageId,groupId:t.groupId,channelId:t.channelId,reactions:t.reactions??[]});return;case"group-typing":t.userId!==this.user?.id&&t.typing!==!1&&this.emit("typingStart",{userId:t.userId,name:t.name,groupId:t.groupId,channelId:t.channelId});return;case"group-joined":{let e=await this.fetchGroup(t.groupId);this.emit("groupJoin",e);return}case"group-updated":{if(!this.groups.has(t.groupId))return;let e=await this.fetchGroup(t.groupId).catch(()=>null);e&&this.emit("groupUpdate",e);return}case"group-member-add":{if(!t.member)return;let e=this._cacheUser(t.member),s=this.groups.get(t.groupId)??await this.fetchGroup(t.groupId).catch(()=>null);s&&(s.memberCount+=1),this.emit("memberAdd",{user:e,group:s,groupId:t.groupId,via:t.via??null});return}case"group-member-remove":{let e=this.groups.get(t.groupId)??null;e&&(e.memberCount=Math.max(0,e.memberCount-1)),this.emit("memberRemove",{userId:t.userId,user:this.users.get(t.userId)??null,group:e,groupId:t.groupId,reason:t.reason??null,by:t.by??null});return}case"group-removed":this.groups.delete(t.groupId),this.emit("groupLeave",{id:t.groupId,reason:t.reason??null});return;default:this.emit("raw",t)}}};function G(i){if(typeof i=="number")return i;let t=String(i).replace(/^#/,"");return/^[0-9a-f]{6}$/i.test(t)?parseInt(t,16):void 0}var I=class{constructor(t={}){this.data={...t}}setTitle(t){return this.data.title=t,this}setDescription(t){return this.data.description=t,this}setURL(t){return this.data.url=t,this}setColor(t){return this.data.color=G(t),this}setAuthor(t){return this.data.author={name:t.name,url:t.url,icon_url:t.iconURL},this}setFooter(t){return this.data.footer={text:t.text,icon_url:t.iconURL},this}setImage(t){return this.data.image={url:t},this}setThumbnail(t){return this.data.thumbnail={url:t},this}setTimestamp(t=new Date){return this.data.timestamp=new Date(t).toISOString(),this}addFields(...t){return this.data.fields=[...this.data.fields??[],...t.flat()],this}toJSON(){return this.data}};0&&(module.exports={Channel,Client,EmbedBuilder,FiveLiveAPIError,Group,Message,REST,User,channelMention,userMention});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.js", "../src/client.js", "../src/rest.js", "../src/structures.js", "../src/embed.js"],
|
|
4
|
-
"sourcesContent": ["// fivelive.js \u2014 SDK para bots do Five Live.\n// Documenta\u00E7\u00E3o: README.md e https://live.fivenetwork.dev/developers\n\nexport { Client } from \"./client.js\";\nexport { EmbedBuilder } from \"./embed.js\";\nexport { REST, FiveLiveAPIError } from \"./rest.js\";\nexport { Channel, Group, Message, User, channelMention, userMention } from \"./structures.js\";\n", "// O Client: conecta no WebSocket do Five Live com o token do bot, mant\u00E9m a\n// conex\u00E3o viva (e reconecta sozinho), transforma os avisos da API em eventos\n// e guarda grupos e usu\u00E1rios conhecidos.\n//\n// Eventos:\n// ready(user) conectou e carregou os grupos\n// messageCreate(message) mensagem nova num grupo do bot\n// messageUpdate(message) mensagem editada\n// messageDelete({ id, groupId, channelId })\n// reactionUpdate({ messageId, groupId, channelId, reactions })\n// typingStart({ userId, name, groupId, channelId })\n// groupJoin(group) / groupLeave({ id, reason }) / groupUpdate(group)\n// reconnecting(attempt) / reconnected() / disconnect() / error(err)\n// commandError(err, context)\n\nimport { EventEmitter } from \"node:events\";\nimport { REST } from \"./rest.js\";\nimport { Group, Message, User } from \"./structures.js\";\n\nconst DEFAULT_API = \"https://api.fivenetwork.dev\";\nconst KEEPALIVE_MS = 30_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nasync function socketClass() {\n if (typeof globalThis.WebSocket === \"function\") return globalThis.WebSocket;\n try {\n const mod = await import(\"ws\");\n return mod.default ?? mod.WebSocket;\n } catch {\n throw new Error(\"Este Node n\u00E3o tem WebSocket nativo (\u00E9 do Node 22+). Rode `npm install ws` ou atualize o Node.\");\n }\n}\n\nexport class Client extends EventEmitter {\n /**\n * @param {{\n * token: string,\n * apiUrl?: string,\n * gatewayUrl?: string,\n * prefix?: string,\n * ignoreBots?: boolean,\n * }} options\n */\n constructor(options) {\n super();\n if (!options?.token || !String(options.token).startsWith(\"b_\")) {\n throw new Error(\"Passe o token do bot (come\u00E7a com b_). Pegue em https://live.fivenetwork.dev/developers.\");\n }\n this.token = options.token;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API).replace(/\\/$/, \"\");\n this.gatewayUrl = options.gatewayUrl ?? `${this.apiUrl.replace(/^http/, \"ws\")}/ws`;\n this.prefix = options.prefix ?? \"!\";\n this.ignoreBots = options.ignoreBots ?? true;\n this.rest = new REST({ token: this.token, apiUrl: this.apiUrl });\n /** @type {User | null} */\n this.user = null;\n /** @type {Map<string, Group>} */\n this.groups = new Map();\n /** @type {Map<string, User>} */\n this.users = new Map();\n /** @type {Map<string, { name: string, description?: string, aliases?: string[], run: Function }>} */\n this.commands = new Map();\n this._ws = null;\n this._ready = false;\n this._closing = false;\n this._attempt = 0;\n this._keepalive = null;\n }\n\n // \u2500\u2500\u2500 Comandos com prefixo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Registra um comando: `!nome arg1 arg2`.\n * @param {{ name: string, description?: string, aliases?: string[], run: (ctx: { message: Message, args: string[], client: Client, reply: (content: any) => Promise<Message> }) => any }} command\n */\n command(command) {\n this.commands.set(command.name.toLowerCase(), command);\n for (const alias of command.aliases ?? []) this.commands.set(alias.toLowerCase(), command);\n return this;\n }\n\n /** @param {Message} message */\n async _runCommand(message) {\n if (!this.commands.size || !message.content.startsWith(this.prefix)) return;\n const [name, ...args] = message.content.slice(this.prefix.length).trim().split(/\\s+/);\n const command = this.commands.get((name ?? \"\").toLowerCase());\n if (!command) return;\n const context = { message, args, client: this, reply: (content) => message.reply(content) };\n try {\n await command.run(context);\n } catch (err) {\n if (this.listenerCount(\"commandError\")) this.emit(\"commandError\", err, context);\n else this.emit(\"error\", err);\n }\n }\n\n // \u2500\u2500\u2500 Conex\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Conecta. Resolve quando o bot estiver pronto (evento \"ready\"). */\n async login() {\n const me = await this.rest.get(\"/bot/@me\");\n this.user = this._cacheUser({ ...me.bot, bot: true });\n await this._loadGroups();\n this._closing = false;\n await this._connect();\n return this.user;\n }\n\n /** Desconecta de vez (sem reconectar). */\n destroy() {\n this._closing = true;\n clearInterval(this._keepalive);\n try {\n this._ws?.close();\n } catch {\n // j\u00E1 fechado\n }\n }\n\n async _loadGroups() {\n const data = await this.rest.get(\"/bot/groups\");\n const seen = new Set();\n for (const raw of data.groups) {\n seen.add(raw.id);\n const held = this.groups.get(raw.id);\n if (held) held._patch(raw);\n else this.groups.set(raw.id, new Group(this, raw));\n }\n for (const id of [...this.groups.keys()]) if (!seen.has(id)) this.groups.delete(id);\n }\n\n /** Um grupo, relido da API. @param {string} id */\n async fetchGroup(id) {\n const data = await this.rest.get(`/bot/groups/${encodeURIComponent(id)}`);\n const held = this.groups.get(id);\n if (held) held._patch(data.group);\n else this.groups.set(id, new Group(this, data.group));\n return this.groups.get(id);\n }\n\n /** Uma pessoa pelo id. @param {string} id */\n async fetchUser(id) {\n const data = await this.rest.get(`/bot/users/${encodeURIComponent(id)}`);\n return this._cacheUser(data.user);\n }\n\n /** @param {Record<string, any>} data */\n _cacheUser(data) {\n const user = new User(this, data);\n this.users.set(user.id, user);\n return user;\n }\n\n async _connect() {\n const Socket = await socketClass();\n return new Promise((resolve, reject) => {\n const ws = new Socket(this.gatewayUrl);\n this._ws = ws;\n let settled = false;\n const send = (payload) => {\n if (ws.readyState === 1) ws.send(JSON.stringify(payload));\n };\n ws.onopen = () => {\n send({ type: \"register\", name: this.user.displayName || this.user.username, token: this.token });\n clearInterval(this._keepalive);\n // O proxy da hospedagem derruba conex\u00E3o parada: uma mensagem leve de tempos em tempos.\n this._keepalive = setInterval(() => send({ type: \"time-sync\", t0: Date.now() }), KEEPALIVE_MS);\n };\n ws.onmessage = (event) => {\n let msg;\n try {\n msg = JSON.parse(typeof event.data === \"string\" ? event.data : event.data.toString());\n } catch {\n return;\n }\n if (msg.type === \"registered\") {\n const first = !this._ready;\n this._ready = true;\n this._attempt = 0;\n if (!settled) {\n settled = true;\n resolve();\n }\n if (first) this.emit(\"ready\", this.user);\n else this.emit(\"reconnected\");\n return;\n }\n if (msg.type === \"register-error\") {\n this._closing = true;\n const err = new Error(msg.message || \"O Five Live recusou o token do bot.\");\n if (!settled) {\n settled = true;\n reject(err);\n } else this.emit(\"error\", err);\n return;\n }\n this._dispatch(msg).catch((err) => this.emit(\"error\", err));\n };\n ws.onerror = (event) => {\n if (!settled && this._attempt === 0 && !this._ready) {\n settled = true;\n reject(new Error(`N\u00E3o foi poss\u00EDvel conectar em ${this.gatewayUrl}: ${event?.message ?? \"erro de rede\"}`));\n }\n };\n ws.onclose = () => {\n clearInterval(this._keepalive);\n this.emit(\"disconnect\");\n if (this._closing || !this._ready) return;\n this._reconnect();\n };\n });\n }\n\n _reconnect() {\n this._attempt += 1;\n const delay = Math.min(MAX_BACKOFF_MS, 1000 * 2 ** Math.min(this._attempt - 1, 5)) + Math.random() * 500;\n this.emit(\"reconnecting\", this._attempt);\n setTimeout(async () => {\n if (this._closing) return;\n try {\n // O que mudou enquanto estava fora (grupos que entrou/saiu).\n await this._loadGroups();\n await this._connect();\n } catch {\n this._reconnect();\n }\n }, delay);\n }\n\n /** @param {Record<string, any>} msg */\n async _dispatch(msg) {\n switch (msg.type) {\n case \"group-message\": {\n if (!msg.message) return;\n const message = new Message(this, msg.message, msg.author ? { ...msg.author } : undefined);\n if (message.author.id === this.user?.id) return;\n if (this.ignoreBots && message.author.bot) return;\n this.emit(\"messageCreate\", message);\n await this._runCommand(message);\n return;\n }\n case \"group-message-updated\":\n if (msg.message) this.emit(\"messageUpdate\", new Message(this, msg.message));\n return;\n case \"group-message-deleted\":\n this.emit(\"messageDelete\", { id: msg.messageId, groupId: msg.groupId, channelId: msg.channelId });\n return;\n case \"group-message-reactions\":\n this.emit(\"reactionUpdate\", { messageId: msg.messageId, groupId: msg.groupId, channelId: msg.channelId, reactions: msg.reactions ?? [] });\n return;\n case \"group-typing\":\n if (msg.userId !== this.user?.id && msg.typing !== false) {\n this.emit(\"typingStart\", { userId: msg.userId, name: msg.name, groupId: msg.groupId, channelId: msg.channelId });\n }\n return;\n case \"group-joined\": {\n const group = await this.fetchGroup(msg.groupId);\n this.emit(\"groupJoin\", group);\n return;\n }\n case \"group-updated\": {\n if (!this.groups.has(msg.groupId)) return;\n const group = await this.fetchGroup(msg.groupId).catch(() => null);\n if (group) this.emit(\"groupUpdate\", group);\n return;\n }\n case \"group-member-add\": {\n if (!msg.member) return;\n const user = this._cacheUser(msg.member);\n const group = this.groups.get(msg.groupId) ?? (await this.fetchGroup(msg.groupId).catch(() => null));\n if (group) group.memberCount += 1;\n this.emit(\"memberAdd\", { user, group, groupId: msg.groupId, via: msg.via ?? null });\n return;\n }\n case \"group-member-remove\": {\n const group = this.groups.get(msg.groupId) ?? null;\n if (group) group.memberCount = Math.max(0, group.memberCount - 1);\n this.emit(\"memberRemove\", { userId: msg.userId, user: this.users.get(msg.userId) ?? null, group, groupId: msg.groupId, reason: msg.reason ?? null, by: msg.by ?? null });\n return;\n }\n case \"group-removed\":\n this.groups.delete(msg.groupId);\n this.emit(\"groupLeave\", { id: msg.groupId, reason: msg.reason ?? null });\n return;\n default:\n this.emit(\"raw\", msg);\n }\n }\n}\n", "// As rotas HTTP da API de bots (api/botApi.mjs), com o token no cabe\u00E7alho\n// `Authorization: Bot <token>`. Trata o limite de envio (429) esperando o\n// tempo que a API pede e tentando de novo.\n\nexport class FiveLiveAPIError extends Error {\n /**\n * @param {string} message\n * @param {number} status\n * @param {string} method\n * @param {string} path\n */\n constructor(message, status, method, path) {\n super(message);\n this.name = \"FiveLiveAPIError\";\n this.status = status;\n this.method = method;\n this.path = path;\n }\n}\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class REST {\n /** @param {{ token: string, apiUrl: string, retries?: number }} options */\n constructor(options) {\n this.token = options.token;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.retries = options.retries ?? 3;\n }\n\n /**\n * @param {string} method\n * @param {string} path\n * @param {unknown} [body]\n */\n async request(method, path, body) {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(this.apiUrl + path, {\n method,\n headers: {\n Authorization: `Bot ${this.token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n \"User-Agent\": \"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)\",\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n const data = await res.json().catch(() => ({}));\n if (res.status === 429 && attempt < this.retries) {\n const seconds = Number(data.retryAfter ?? res.headers.get(\"retry-after\") ?? 5);\n await sleep(Math.max(1, seconds) * 1000);\n continue;\n }\n if (!res.ok) throw new FiveLiveAPIError(data.error ?? `HTTP ${res.status}`, res.status, method, path);\n return data;\n }\n }\n\n get(path) {\n return this.request(\"GET\", path);\n }\n post(path, body) {\n return this.request(\"POST\", path, body ?? {});\n }\n patch(path, body) {\n return this.request(\"PATCH\", path, body ?? {});\n }\n put(path, body) {\n return this.request(\"PUT\", path, body ?? {});\n }\n delete(path) {\n return this.request(\"DELETE\", path);\n }\n}\n\nexport const enc = encodeURIComponent;\n", "// Os objetos que o bot recebe: User, Group, Channel, Message. Cada um sabe\n// agir sobre si mesmo (message.reply, channel.send, \u2026) usando o client.\n\nimport { enc } from \"./rest.js\";\n\n/** `<@id>` \u2014 como mencionar algu\u00E9m no texto. */\nexport const userMention = (id) => `<@${id}>`;\n/** `<#id>` \u2014 como apontar uma sala no texto. */\nexport const channelMention = (id) => `<#${id}>`;\n\n/**\n * Normaliza o que se manda: um texto, ou { content, embeds, mentions, reply }.\n * @param {string | Record<string, any>} input\n */\nexport function messagePayload(input) {\n const options = typeof input === \"string\" ? { content: input } : input ?? {};\n const embeds = (options.embeds ?? []).map((embed) => (typeof embed?.toJSON === \"function\" ? embed.toJSON() : embed));\n const roles = (options.roleMentions ?? []).map((id) => `@role:${id}`);\n return {\n text: options.content ?? \"\",\n ...(embeds.length ? { embeds } : {}),\n ...(options.mentions?.length || roles.length || options.everyone\n ? { mentions: [...(options.mentions ?? []), ...roles, ...(options.everyone ? [\"@everyone\"] : [])] }\n : {}),\n ...(options.reply ? { replyTo: typeof options.reply === \"string\" ? options.reply : options.reply.id } : {}),\n };\n}\n\nexport class User {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this.id = data.id;\n this.username = data.username ?? null;\n this.displayName = data.displayName ?? data.name ?? data.username ?? \"\";\n this.avatarURL = data.avatarUrl ?? null;\n this.bot = data.bot === true;\n this.flags = data.flags ?? [];\n }\n /** `<@id>`, para colocar no texto. */\n toString() {\n return userMention(this.id);\n }\n}\n\nexport class Channel {\n /** @param {import(\"./client.js\").Client} client @param {Group} group @param {Record<string, any>} data */\n constructor(client, group, data) {\n this.client = client;\n this.group = group;\n this.id = data.id;\n this.name = data.name;\n /** \"text\" | \"voice\" */\n this.kind = data.kind;\n this.categoryId = data.categoryId ?? null;\n this.topic = data.topic ?? \"\";\n }\n get isText() {\n return this.kind === \"text\";\n }\n get path() {\n return `/bot/groups/${enc(this.group.id)}/channels/${enc(this.id)}`;\n }\n /** Manda uma mensagem. @param {string | Record<string, any>} content */\n async send(content) {\n const data = await this.client.rest.post(`${this.path}/messages`, messagePayload(content));\n return new Message(this.client, data.message, this.client.user);\n }\n /** \"Digitando\u2026\" por alguns segundos. */\n async sendTyping() {\n await this.client.rest.post(`${this.path}/typing`, { typing: true });\n }\n /**\n * As \u00FAltimas mensagens (a mais nova por \u00FAltimo).\n * @param {{ limit?: number, after?: string }} [options]\n */\n async fetchMessages(options = {}) {\n const query = new URLSearchParams();\n if (options.limit) query.set(\"limit\", String(options.limit));\n if (options.after) query.set(\"after\", options.after);\n const data = await this.client.rest.get(`${this.path}/messages?${query}`);\n return data.messages.map((message) => new Message(this.client, message));\n }\n /** Uma mensagem pelo id. */\n async fetchMessage(id) {\n const data = await this.client.rest.get(`${this.path}/messages/${enc(id)}`);\n return new Message(this.client, data.message);\n }\n toString() {\n return `<#${this.id}>`;\n }\n}\n\nexport class Group {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this._patch(data);\n }\n /** @param {Record<string, any>} data */\n _patch(data) {\n this.id = data.id;\n this.name = data.name;\n this.iconURL = data.iconUrl ?? null;\n this.ownerId = data.ownerId ?? null;\n this.memberCount = data.memberCount ?? 0;\n /** @type {{ id: string, name: string, color: string | null, position: number, mentionable: boolean }[]} */\n this.roles = data.roles ?? [];\n /** O que o bot pode fazer aqui (kickMembers, banMembers, manageRoles, manageMessages\u2026). */\n this.permissions = data.permissions ?? {};\n /** @type {Map<string, Channel>} */\n this.channels = new Map((data.channels ?? []).map((channel) => [channel.id, new Channel(this.client, this, channel)]));\n }\n /** A sala pelo id ou pelo nome. @param {string} idOrName */\n channel(idOrName) {\n return this.channels.get(idOrName) ?? [...this.channels.values()].find((channel) => channel.name === idOrName) ?? null;\n }\n /** Os membros, com cargos e quem est\u00E1 online. */\n async fetchMembers() {\n const data = await this.client.rest.get(`/bot/groups/${enc(this.id)}/members`);\n return data.members.map((member) => ({ ...member, user: this.client._cacheUser(member) }));\n }\n get path() {\n return `/bot/groups/${enc(this.id)}`;\n }\n /** Se o bot tem a permiss\u00E3o (administrator vale por todas). @param {string} key */\n can(key) {\n return this.permissions.administrator === true || this.permissions[key] === true;\n }\n /** Expulsa algu\u00E9m (precisa de kickMembers e de um cargo acima do da pessoa). @param {string} userId */\n async kick(userId) {\n await this.client.rest.post(`${this.path}/members/${enc(userId)}/kick`, {});\n }\n /** Bane algu\u00E9m, mesmo que n\u00E3o esteja no grupo (banMembers). @param {string} userId @param {string} [reason] */\n async ban(userId, reason) {\n await this.client.rest.put(`${this.path}/bans/${enc(userId)}`, reason ? { reason } : {});\n }\n /** Tira o banimento (banMembers). @param {string} userId */\n async unban(userId) {\n await this.client.rest.delete(`${this.path}/bans/${enc(userId)}`);\n }\n /** Quem est\u00E1 banido (banMembers). */\n async fetchBans() {\n const data = await this.client.rest.get(`${this.path}/bans`);\n return data.bans;\n }\n /** D\u00E1 um cargo (manageRoles; s\u00F3 cargos abaixo do mais alto do bot). @param {string} userId @param {string} roleId */\n async addRole(userId, roleId) {\n const data = await this.client.rest.put(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** Tira um cargo (manageRoles). @param {string} userId @param {string} roleId */\n async removeRole(userId, roleId) {\n const data = await this.client.rest.delete(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** O bot sai do grupo. */\n async leave() {\n await this.client.rest.post(`${this.path}/leave`, {});\n }\n /** `<@&id>` n\u00E3o existe aqui: para mencionar um cargo, use { roleMentions: [id] } no envio. */\n role(idOrName) {\n return this.roles.find((role) => role.id === idOrName || role.name === idOrName) ?? null;\n }\n}\n\nexport class Message {\n /**\n * @param {import(\"./client.js\").Client} client\n * @param {Record<string, any>} data\n * @param {User | Record<string, any>} [author]\n */\n constructor(client, data, author) {\n this.client = client;\n this.id = data.id;\n this.groupId = data.groupId;\n this.channelId = data.channelId;\n /** O texto como est\u00E1 gravado \u2014 men\u00E7\u00F5es como `<@id>`. */\n this.content = data.text ?? \"\";\n this.embeds = data.embeds ?? [];\n this.attachments = data.attachments ?? [];\n this.images = data.images ?? [];\n this.reactions = data.reactions ?? [];\n this.replyTo = data.replyTo ?? null;\n this.createdAt = new Date(data.ts ?? Date.now());\n this.editedAt = data.editedAt ? new Date(data.editedAt) : null;\n this.pinned = Boolean(data.pinnedAt);\n this.webhook = Boolean(data.webhook);\n const mentions = data.mentions ?? [];\n this.mentions = {\n /** ids das pessoas mencionadas */\n users: mentions.filter((entry) => !entry.startsWith(\"@\")),\n /** ids dos cargos mencionados */\n roles: mentions.filter((entry) => entry.startsWith(\"@role:\")).map((entry) => entry.slice(6)),\n everyone: mentions.includes(\"@everyone\"),\n raw: mentions,\n };\n this.author =\n author instanceof User\n ? author\n : author\n ? client._cacheUser(author)\n : client.users.get(data.from) ?? new User(client, { id: data.from, name: data.fromName });\n }\n get group() {\n return this.client.groups.get(this.groupId) ?? null;\n }\n get channel() {\n return this.group?.channels.get(this.channelId) ?? null;\n }\n /** O texto com `<@id>` trocado por `@nome` (quando o nome \u00E9 conhecido). */\n get cleanContent() {\n return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g, (whole, id) => {\n const user = this.client.users.get(id);\n return user ? `@${user.displayName}` : whole;\n });\n }\n /** Se a mensagem menciona o bot (pelo id, cargo n\u00E3o conta). */\n get mentionsMe() {\n return this.mentions.users.includes(this.client.user?.id) || this.mentions.everyone;\n }\n get path() {\n return `/bot/groups/${enc(this.groupId)}/channels/${enc(this.channelId)}/messages`;\n }\n /** Responde citando esta mensagem. @param {string | Record<string, any>} content */\n async reply(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.post(this.path, { ...payload, replyTo: this.id });\n return new Message(this.client, data.message, this.client.user);\n }\n /** Edita (s\u00F3 as mensagens do pr\u00F3prio bot). @param {string | Record<string, any>} content */\n async edit(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.patch(`${this.path}/${enc(this.id)}`, { text: payload.text, ...(payload.embeds ? { embeds: payload.embeds } : {}) });\n return new Message(this.client, data.message, this.author);\n }\n /** Fixa na sala (manageMessages). */\n async pin() {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Desafixa (manageMessages). */\n async unpin() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Apaga: as do pr\u00F3prio bot sempre; as dos outros, com manageMessages. */\n async delete() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}`);\n }\n /** Reage com um emoji. @param {string} emoji */\n async react(emoji) {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n /** Tira a rea\u00E7\u00E3o do bot. @param {string} emoji */\n async unreact(emoji) {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n}\n", "// Construtor de embeds no mesmo formato do discord.js (e do webhook do Five\n// Live): t\u00EDtulo, descri\u00E7\u00E3o, cor, autor, campos, imagem, miniatura, rodap\u00E9.\n\n/** @param {string | number} color */\nfunction toColor(color) {\n if (typeof color === \"number\") return color;\n const hex = String(color).replace(/^#/, \"\");\n return /^[0-9a-f]{6}$/i.test(hex) ? parseInt(hex, 16) : undefined;\n}\n\nexport class EmbedBuilder {\n /** @param {Record<string, unknown>} [data] */\n constructor(data = {}) {\n /** @type {Record<string, any>} */\n this.data = { ...data };\n }\n setTitle(title) {\n this.data.title = title;\n return this;\n }\n setDescription(description) {\n this.data.description = description;\n return this;\n }\n setURL(url) {\n this.data.url = url;\n return this;\n }\n /** @param {string | number} color \"#3b6cf6\" ou 0x3b6cf6 */\n setColor(color) {\n this.data.color = toColor(color);\n return this;\n }\n /** @param {{ name: string, url?: string, iconURL?: string }} author */\n setAuthor(author) {\n this.data.author = { name: author.name, url: author.url, icon_url: author.iconURL };\n return this;\n }\n /** @param {{ text: string, iconURL?: string }} footer */\n setFooter(footer) {\n this.data.footer = { text: footer.text, icon_url: footer.iconURL };\n return this;\n }\n setImage(url) {\n this.data.image = { url };\n return this;\n }\n setThumbnail(url) {\n this.data.thumbnail = { url };\n return this;\n }\n /** @param {Date | number | string} [timestamp] */\n setTimestamp(timestamp = new Date()) {\n this.data.timestamp = new Date(timestamp).toISOString();\n return this;\n }\n /** @param {...{ name: string, value: string, inline?: boolean }} fields */\n addFields(...fields) {\n this.data.fields = [...(this.data.fields ?? []), ...fields.flat()];\n return this;\n }\n toJSON() {\n return this.data;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["index_exports", "__export", "Channel", "Client", "EmbedBuilder", "FiveLiveAPIError", "Group", "Message", "REST", "User", "channelMention", "userMention", "__toCommonJS", "import_node_events", "FiveLiveAPIError", "message", "status", "method", "path", "sleep", "ms", "resolve", "REST", "options", "body", "attempt", "res", "data", "seconds", "enc", "userMention", "id", "channelMention", "messagePayload", "input", "options", "embeds", "embed", "roles", "User", "client", "data", "Channel", "group", "enc", "content", "Message", "query", "message", "Group", "channel", "idOrName", "member", "key", "userId", "reason", "roleId", "role", "_Message", "author", "mentions", "entry", "whole", "user", "payload", "emoji", "DEFAULT_API", "KEEPALIVE_MS", "MAX_BACKOFF_MS", "socketClass", "mod", "Client", "options", "REST", "command", "alias", "
|
|
4
|
+
"sourcesContent": ["// fivelive.js \u2014 SDK para bots do Five Live.\n// Documenta\u00E7\u00E3o: README.md e https://live.fivenetwork.dev/developers\n\nexport { Client } from \"./client.js\";\nexport { EmbedBuilder } from \"./embed.js\";\nexport { REST, FiveLiveAPIError } from \"./rest.js\";\nexport { Channel, Group, Message, User, channelMention, userMention } from \"./structures.js\";\n", "// O Client: conecta no WebSocket do Five Live com o token do bot, mant\u00E9m a\n// conex\u00E3o viva (e reconecta sozinho), transforma os avisos da API em eventos\n// e guarda grupos e usu\u00E1rios conhecidos.\n//\n// Eventos:\n// ready(user) conectou e carregou os grupos\n// messageCreate(message) mensagem nova num grupo do bot\n// messageUpdate(message) mensagem editada\n// messageDelete({ id, groupId, channelId })\n// reactionUpdate({ messageId, groupId, channelId, reactions })\n// typingStart({ userId, name, groupId, channelId })\n// groupJoin(group) / groupLeave({ id, reason }) / groupUpdate(group)\n// reconnecting(attempt) / reconnected() / disconnect() / error(err)\n// commandError(err, context)\n\nimport { EventEmitter } from \"node:events\";\nimport { REST } from \"./rest.js\";\nimport { Group, Message, User } from \"./structures.js\";\n\nconst DEFAULT_API = \"https://api.fivenetwork.dev\";\nconst KEEPALIVE_MS = 30_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nasync function socketClass() {\n if (typeof globalThis.WebSocket === \"function\") return globalThis.WebSocket;\n try {\n const mod = await import(\"ws\");\n return mod.default ?? mod.WebSocket;\n } catch {\n throw new Error(\"Este Node n\u00E3o tem WebSocket nativo (\u00E9 do Node 22+). Rode `npm install ws` ou atualize o Node.\");\n }\n}\n\nexport class Client extends EventEmitter {\n /**\n * @param {{\n * token: string,\n * apiUrl?: string,\n * gatewayUrl?: string,\n * prefix?: string,\n * ignoreBots?: boolean,\n * }} options\n */\n constructor(options) {\n super();\n if (!options?.token || !String(options.token).startsWith(\"b_\")) {\n throw new Error(\"Passe o token do bot (come\u00E7a com b_). Pegue em https://live.fivenetwork.dev/developers.\");\n }\n this.token = options.token;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API).replace(/\\/$/, \"\");\n this.gatewayUrl = options.gatewayUrl ?? `${this.apiUrl.replace(/^http/, \"ws\")}/ws`;\n this.prefix = options.prefix ?? \"!\";\n this.ignoreBots = options.ignoreBots ?? true;\n this.rest = new REST({ token: this.token, apiUrl: this.apiUrl });\n /** @type {User | null} */\n this.user = null;\n /** @type {Map<string, Group>} */\n this.groups = new Map();\n /** @type {Map<string, User>} */\n this.users = new Map();\n /** @type {Map<string, { name: string, description?: string, aliases?: string[], run: Function }>} */\n this.commands = new Map();\n this._ws = null;\n this._ready = false;\n this._closing = false;\n this._attempt = 0;\n this._keepalive = null;\n }\n\n // \u2500\u2500\u2500 Comandos com prefixo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Registra um comando: `!nome arg1 arg2`.\n *\n * Com `description`, ele tamb\u00E9m vira um comando de barra (`/`): quem\n * escrever \"/\" numa sala em que o bot est\u00E1 v\u00EA o comando na lista, com a\n * descri\u00E7\u00E3o e os `options` como o jeito de escrever os argumentos \u2014 do\n * jeito do Discord. `login()` manda esse manifesto para a API sozinho; para\n * mandar de novo depois de registrar mais comandos, chame `syncCommands()`.\n * @param {{\n * name: string,\n * description?: string,\n * aliases?: string[],\n * options?: { name: string, description: string, required?: boolean, type?: \"string\" | \"number\" | \"boolean\" | \"user\" }[],\n * run: (ctx: { message: Message, args: string[], client: Client, reply: (content: any) => Promise<Message> }) => any,\n * }} command\n */\n command(command) {\n this.commands.set(command.name.toLowerCase(), command);\n for (const alias of command.aliases ?? []) this.commands.set(alias.toLowerCase(), command);\n return this;\n }\n\n /**\n * Manda para a API o manifesto de comandos de barra: todo comando com\n * `description` registrado at\u00E9 agora. Chamado sozinho ao fim de `login()`;\n * chame de novo se registrar comandos depois disso. Nunca lan\u00E7a \u2014 um erro\n * aqui n\u00E3o deveria derrubar o bot, s\u00F3 sai como o evento \"error\".\n */\n async syncCommands() {\n const seen = new Set();\n const commands = [];\n for (const command of this.commands.values()) {\n if (seen.has(command.name) || !command.description) continue;\n seen.add(command.name);\n commands.push({ name: command.name, description: command.description, options: command.options ?? [] });\n }\n try {\n await this.rest.put(\"/bot/commands\", { prefix: this.prefix, commands });\n } catch (err) {\n this.emit(\"error\", err);\n }\n }\n\n /** @param {Message} message */\n async _runCommand(message) {\n if (!this.commands.size || !message.content.startsWith(this.prefix)) return;\n const [name, ...args] = message.content.slice(this.prefix.length).trim().split(/\\s+/);\n const command = this.commands.get((name ?? \"\").toLowerCase());\n if (!command) return;\n const context = { message, args, client: this, reply: (content) => message.reply(content) };\n try {\n await command.run(context);\n } catch (err) {\n if (this.listenerCount(\"commandError\")) this.emit(\"commandError\", err, context);\n else this.emit(\"error\", err);\n }\n }\n\n // \u2500\u2500\u2500 Conex\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Conecta. Resolve quando o bot estiver pronto (evento \"ready\"). */\n async login() {\n const me = await this.rest.get(\"/bot/@me\");\n this.user = this._cacheUser({ ...me.bot, bot: true });\n await this._loadGroups();\n await this.syncCommands();\n this._closing = false;\n await this._connect();\n return this.user;\n }\n\n /** Desconecta de vez (sem reconectar). */\n destroy() {\n this._closing = true;\n clearInterval(this._keepalive);\n try {\n this._ws?.close();\n } catch {\n // j\u00E1 fechado\n }\n }\n\n async _loadGroups() {\n const data = await this.rest.get(\"/bot/groups\");\n const seen = new Set();\n for (const raw of data.groups) {\n seen.add(raw.id);\n const held = this.groups.get(raw.id);\n if (held) held._patch(raw);\n else this.groups.set(raw.id, new Group(this, raw));\n }\n for (const id of [...this.groups.keys()]) if (!seen.has(id)) this.groups.delete(id);\n }\n\n /** Um grupo, relido da API. @param {string} id */\n async fetchGroup(id) {\n const data = await this.rest.get(`/bot/groups/${encodeURIComponent(id)}`);\n const held = this.groups.get(id);\n if (held) held._patch(data.group);\n else this.groups.set(id, new Group(this, data.group));\n return this.groups.get(id);\n }\n\n /** Uma pessoa pelo id. @param {string} id */\n async fetchUser(id) {\n const data = await this.rest.get(`/bot/users/${encodeURIComponent(id)}`);\n return this._cacheUser(data.user);\n }\n\n /** @param {Record<string, any>} data */\n _cacheUser(data) {\n const user = new User(this, data);\n this.users.set(user.id, user);\n return user;\n }\n\n async _connect() {\n const Socket = await socketClass();\n return new Promise((resolve, reject) => {\n const ws = new Socket(this.gatewayUrl);\n this._ws = ws;\n let settled = false;\n const send = (payload) => {\n if (ws.readyState === 1) ws.send(JSON.stringify(payload));\n };\n ws.onopen = () => {\n send({ type: \"register\", name: this.user.displayName || this.user.username, token: this.token });\n clearInterval(this._keepalive);\n // O proxy da hospedagem derruba conex\u00E3o parada: uma mensagem leve de tempos em tempos.\n this._keepalive = setInterval(() => send({ type: \"time-sync\", t0: Date.now() }), KEEPALIVE_MS);\n };\n ws.onmessage = (event) => {\n let msg;\n try {\n msg = JSON.parse(typeof event.data === \"string\" ? event.data : event.data.toString());\n } catch {\n return;\n }\n if (msg.type === \"registered\") {\n const first = !this._ready;\n this._ready = true;\n this._attempt = 0;\n if (!settled) {\n settled = true;\n resolve();\n }\n if (first) this.emit(\"ready\", this.user);\n else this.emit(\"reconnected\");\n return;\n }\n if (msg.type === \"register-error\") {\n this._closing = true;\n const err = new Error(msg.message || \"O Five Live recusou o token do bot.\");\n if (!settled) {\n settled = true;\n reject(err);\n } else this.emit(\"error\", err);\n return;\n }\n this._dispatch(msg).catch((err) => this.emit(\"error\", err));\n };\n ws.onerror = (event) => {\n if (!settled && this._attempt === 0 && !this._ready) {\n settled = true;\n reject(new Error(`N\u00E3o foi poss\u00EDvel conectar em ${this.gatewayUrl}: ${event?.message ?? \"erro de rede\"}`));\n }\n };\n ws.onclose = () => {\n clearInterval(this._keepalive);\n this.emit(\"disconnect\");\n if (this._closing || !this._ready) return;\n this._reconnect();\n };\n });\n }\n\n _reconnect() {\n this._attempt += 1;\n const delay = Math.min(MAX_BACKOFF_MS, 1000 * 2 ** Math.min(this._attempt - 1, 5)) + Math.random() * 500;\n this.emit(\"reconnecting\", this._attempt);\n setTimeout(async () => {\n if (this._closing) return;\n try {\n // O que mudou enquanto estava fora (grupos que entrou/saiu).\n await this._loadGroups();\n await this._connect();\n } catch {\n this._reconnect();\n }\n }, delay);\n }\n\n /** @param {Record<string, any>} msg */\n async _dispatch(msg) {\n switch (msg.type) {\n case \"group-message\": {\n if (!msg.message) return;\n const message = new Message(this, msg.message, msg.author ? { ...msg.author } : undefined);\n if (message.author.id === this.user?.id) return;\n if (this.ignoreBots && message.author.bot) return;\n this.emit(\"messageCreate\", message);\n await this._runCommand(message);\n return;\n }\n case \"group-message-updated\":\n if (msg.message) this.emit(\"messageUpdate\", new Message(this, msg.message));\n return;\n case \"group-message-deleted\":\n this.emit(\"messageDelete\", { id: msg.messageId, groupId: msg.groupId, channelId: msg.channelId });\n return;\n case \"group-message-reactions\":\n this.emit(\"reactionUpdate\", { messageId: msg.messageId, groupId: msg.groupId, channelId: msg.channelId, reactions: msg.reactions ?? [] });\n return;\n case \"group-typing\":\n if (msg.userId !== this.user?.id && msg.typing !== false) {\n this.emit(\"typingStart\", { userId: msg.userId, name: msg.name, groupId: msg.groupId, channelId: msg.channelId });\n }\n return;\n case \"group-joined\": {\n const group = await this.fetchGroup(msg.groupId);\n this.emit(\"groupJoin\", group);\n return;\n }\n case \"group-updated\": {\n if (!this.groups.has(msg.groupId)) return;\n const group = await this.fetchGroup(msg.groupId).catch(() => null);\n if (group) this.emit(\"groupUpdate\", group);\n return;\n }\n case \"group-member-add\": {\n if (!msg.member) return;\n const user = this._cacheUser(msg.member);\n const group = this.groups.get(msg.groupId) ?? (await this.fetchGroup(msg.groupId).catch(() => null));\n if (group) group.memberCount += 1;\n this.emit(\"memberAdd\", { user, group, groupId: msg.groupId, via: msg.via ?? null });\n return;\n }\n case \"group-member-remove\": {\n const group = this.groups.get(msg.groupId) ?? null;\n if (group) group.memberCount = Math.max(0, group.memberCount - 1);\n this.emit(\"memberRemove\", { userId: msg.userId, user: this.users.get(msg.userId) ?? null, group, groupId: msg.groupId, reason: msg.reason ?? null, by: msg.by ?? null });\n return;\n }\n case \"group-removed\":\n this.groups.delete(msg.groupId);\n this.emit(\"groupLeave\", { id: msg.groupId, reason: msg.reason ?? null });\n return;\n default:\n this.emit(\"raw\", msg);\n }\n }\n}\n", "// As rotas HTTP da API de bots (api/botApi.mjs), com o token no cabe\u00E7alho\n// `Authorization: Bot <token>`. Trata o limite de envio (429) esperando o\n// tempo que a API pede e tentando de novo.\n\nexport class FiveLiveAPIError extends Error {\n /**\n * @param {string} message\n * @param {number} status\n * @param {string} method\n * @param {string} path\n */\n constructor(message, status, method, path) {\n super(message);\n this.name = \"FiveLiveAPIError\";\n this.status = status;\n this.method = method;\n this.path = path;\n }\n}\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class REST {\n /** @param {{ token: string, apiUrl: string, retries?: number }} options */\n constructor(options) {\n this.token = options.token;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.retries = options.retries ?? 3;\n }\n\n /**\n * @param {string} method\n * @param {string} path\n * @param {unknown} [body]\n */\n async request(method, path, body) {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(this.apiUrl + path, {\n method,\n headers: {\n Authorization: `Bot ${this.token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n \"User-Agent\": \"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)\",\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n const data = await res.json().catch(() => ({}));\n if (res.status === 429 && attempt < this.retries) {\n const seconds = Number(data.retryAfter ?? res.headers.get(\"retry-after\") ?? 5);\n await sleep(Math.max(1, seconds) * 1000);\n continue;\n }\n if (!res.ok) throw new FiveLiveAPIError(data.error ?? `HTTP ${res.status}`, res.status, method, path);\n return data;\n }\n }\n\n get(path) {\n return this.request(\"GET\", path);\n }\n post(path, body) {\n return this.request(\"POST\", path, body ?? {});\n }\n patch(path, body) {\n return this.request(\"PATCH\", path, body ?? {});\n }\n put(path, body) {\n return this.request(\"PUT\", path, body ?? {});\n }\n delete(path) {\n return this.request(\"DELETE\", path);\n }\n}\n\nexport const enc = encodeURIComponent;\n", "// Os objetos que o bot recebe: User, Group, Channel, Message. Cada um sabe\n// agir sobre si mesmo (message.reply, channel.send, \u2026) usando o client.\n\nimport { enc } from \"./rest.js\";\n\n/** `<@id>` \u2014 como mencionar algu\u00E9m no texto. */\nexport const userMention = (id) => `<@${id}>`;\n/** `<#id>` \u2014 como apontar uma sala no texto. */\nexport const channelMention = (id) => `<#${id}>`;\n\n/**\n * Normaliza o que se manda: um texto, ou { content, embeds, mentions, reply }.\n * @param {string | Record<string, any>} input\n */\nexport function messagePayload(input) {\n const options = typeof input === \"string\" ? { content: input } : input ?? {};\n const embeds = (options.embeds ?? []).map((embed) => (typeof embed?.toJSON === \"function\" ? embed.toJSON() : embed));\n const roles = (options.roleMentions ?? []).map((id) => `@role:${id}`);\n return {\n text: options.content ?? \"\",\n ...(embeds.length ? { embeds } : {}),\n ...(options.mentions?.length || roles.length || options.everyone\n ? { mentions: [...(options.mentions ?? []), ...roles, ...(options.everyone ? [\"@everyone\"] : [])] }\n : {}),\n ...(options.reply ? { replyTo: typeof options.reply === \"string\" ? options.reply : options.reply.id } : {}),\n };\n}\n\nexport class User {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this.id = data.id;\n this.username = data.username ?? null;\n this.displayName = data.displayName ?? data.name ?? data.username ?? \"\";\n this.avatarURL = data.avatarUrl ?? null;\n this.bot = data.bot === true;\n this.flags = data.flags ?? [];\n }\n /** `<@id>`, para colocar no texto. */\n toString() {\n return userMention(this.id);\n }\n}\n\nexport class Channel {\n /** @param {import(\"./client.js\").Client} client @param {Group} group @param {Record<string, any>} data */\n constructor(client, group, data) {\n this.client = client;\n this.group = group;\n this.id = data.id;\n this.name = data.name;\n /** \"text\" | \"voice\" */\n this.kind = data.kind;\n this.categoryId = data.categoryId ?? null;\n this.topic = data.topic ?? \"\";\n }\n get isText() {\n return this.kind === \"text\";\n }\n get path() {\n return `/bot/groups/${enc(this.group.id)}/channels/${enc(this.id)}`;\n }\n /** Manda uma mensagem. @param {string | Record<string, any>} content */\n async send(content) {\n const data = await this.client.rest.post(`${this.path}/messages`, messagePayload(content));\n return new Message(this.client, data.message, this.client.user);\n }\n /** \"Digitando\u2026\" por alguns segundos. */\n async sendTyping() {\n await this.client.rest.post(`${this.path}/typing`, { typing: true });\n }\n /**\n * As \u00FAltimas mensagens (a mais nova por \u00FAltimo).\n * @param {{ limit?: number, after?: string }} [options]\n */\n async fetchMessages(options = {}) {\n const query = new URLSearchParams();\n if (options.limit) query.set(\"limit\", String(options.limit));\n if (options.after) query.set(\"after\", options.after);\n const data = await this.client.rest.get(`${this.path}/messages?${query}`);\n return data.messages.map((message) => new Message(this.client, message));\n }\n /** Uma mensagem pelo id. */\n async fetchMessage(id) {\n const data = await this.client.rest.get(`${this.path}/messages/${enc(id)}`);\n return new Message(this.client, data.message);\n }\n toString() {\n return `<#${this.id}>`;\n }\n}\n\nexport class Group {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this._patch(data);\n }\n /** @param {Record<string, any>} data */\n _patch(data) {\n this.id = data.id;\n this.name = data.name;\n this.iconURL = data.iconUrl ?? null;\n this.ownerId = data.ownerId ?? null;\n this.memberCount = data.memberCount ?? 0;\n /** @type {{ id: string, name: string, color: string | null, position: number, mentionable: boolean }[]} */\n this.roles = data.roles ?? [];\n /** O que o bot pode fazer aqui (kickMembers, banMembers, manageRoles, manageMessages\u2026). */\n this.permissions = data.permissions ?? {};\n /** @type {Map<string, Channel>} */\n this.channels = new Map((data.channels ?? []).map((channel) => [channel.id, new Channel(this.client, this, channel)]));\n }\n /** A sala pelo id ou pelo nome. @param {string} idOrName */\n channel(idOrName) {\n return this.channels.get(idOrName) ?? [...this.channels.values()].find((channel) => channel.name === idOrName) ?? null;\n }\n /** Os membros, com cargos e quem est\u00E1 online. */\n async fetchMembers() {\n const data = await this.client.rest.get(`/bot/groups/${enc(this.id)}/members`);\n return data.members.map((member) => ({ ...member, user: this.client._cacheUser(member) }));\n }\n get path() {\n return `/bot/groups/${enc(this.id)}`;\n }\n /** Se o bot tem a permiss\u00E3o (administrator vale por todas). @param {string} key */\n can(key) {\n return this.permissions.administrator === true || this.permissions[key] === true;\n }\n /** Expulsa algu\u00E9m (precisa de kickMembers e de um cargo acima do da pessoa). @param {string} userId */\n async kick(userId) {\n await this.client.rest.post(`${this.path}/members/${enc(userId)}/kick`, {});\n }\n /** Bane algu\u00E9m, mesmo que n\u00E3o esteja no grupo (banMembers). @param {string} userId @param {string} [reason] */\n async ban(userId, reason) {\n await this.client.rest.put(`${this.path}/bans/${enc(userId)}`, reason ? { reason } : {});\n }\n /** Tira o banimento (banMembers). @param {string} userId */\n async unban(userId) {\n await this.client.rest.delete(`${this.path}/bans/${enc(userId)}`);\n }\n /** Quem est\u00E1 banido (banMembers). */\n async fetchBans() {\n const data = await this.client.rest.get(`${this.path}/bans`);\n return data.bans;\n }\n /** D\u00E1 um cargo (manageRoles; s\u00F3 cargos abaixo do mais alto do bot). @param {string} userId @param {string} roleId */\n async addRole(userId, roleId) {\n const data = await this.client.rest.put(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** Tira um cargo (manageRoles). @param {string} userId @param {string} roleId */\n async removeRole(userId, roleId) {\n const data = await this.client.rest.delete(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** O bot sai do grupo. */\n async leave() {\n await this.client.rest.post(`${this.path}/leave`, {});\n }\n /** `<@&id>` n\u00E3o existe aqui: para mencionar um cargo, use { roleMentions: [id] } no envio. */\n role(idOrName) {\n return this.roles.find((role) => role.id === idOrName || role.name === idOrName) ?? null;\n }\n}\n\nexport class Message {\n /**\n * @param {import(\"./client.js\").Client} client\n * @param {Record<string, any>} data\n * @param {User | Record<string, any>} [author]\n */\n constructor(client, data, author) {\n this.client = client;\n this.id = data.id;\n this.groupId = data.groupId;\n this.channelId = data.channelId;\n /** O texto como est\u00E1 gravado \u2014 men\u00E7\u00F5es como `<@id>`. */\n this.content = data.text ?? \"\";\n this.embeds = data.embeds ?? [];\n this.attachments = data.attachments ?? [];\n this.images = data.images ?? [];\n this.reactions = data.reactions ?? [];\n this.replyTo = data.replyTo ?? null;\n this.createdAt = new Date(data.ts ?? Date.now());\n this.editedAt = data.editedAt ? new Date(data.editedAt) : null;\n this.pinned = Boolean(data.pinnedAt);\n this.webhook = Boolean(data.webhook);\n const mentions = data.mentions ?? [];\n this.mentions = {\n /** ids das pessoas mencionadas */\n users: mentions.filter((entry) => !entry.startsWith(\"@\")),\n /** ids dos cargos mencionados */\n roles: mentions.filter((entry) => entry.startsWith(\"@role:\")).map((entry) => entry.slice(6)),\n everyone: mentions.includes(\"@everyone\"),\n raw: mentions,\n };\n this.author =\n author instanceof User\n ? author\n : author\n ? client._cacheUser(author)\n : client.users.get(data.from) ?? new User(client, { id: data.from, name: data.fromName });\n }\n get group() {\n return this.client.groups.get(this.groupId) ?? null;\n }\n get channel() {\n return this.group?.channels.get(this.channelId) ?? null;\n }\n /** O texto com `<@id>` trocado por `@nome` (quando o nome \u00E9 conhecido). */\n get cleanContent() {\n return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g, (whole, id) => {\n const user = this.client.users.get(id);\n return user ? `@${user.displayName}` : whole;\n });\n }\n /** Se a mensagem menciona o bot (pelo id, cargo n\u00E3o conta). */\n get mentionsMe() {\n return this.mentions.users.includes(this.client.user?.id) || this.mentions.everyone;\n }\n get path() {\n return `/bot/groups/${enc(this.groupId)}/channels/${enc(this.channelId)}/messages`;\n }\n /** Responde citando esta mensagem. @param {string | Record<string, any>} content */\n async reply(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.post(this.path, { ...payload, replyTo: this.id });\n return new Message(this.client, data.message, this.client.user);\n }\n /** Edita (s\u00F3 as mensagens do pr\u00F3prio bot). @param {string | Record<string, any>} content */\n async edit(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.patch(`${this.path}/${enc(this.id)}`, { text: payload.text, ...(payload.embeds ? { embeds: payload.embeds } : {}) });\n return new Message(this.client, data.message, this.author);\n }\n /** Fixa na sala (manageMessages). */\n async pin() {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Desafixa (manageMessages). */\n async unpin() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Apaga: as do pr\u00F3prio bot sempre; as dos outros, com manageMessages. */\n async delete() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}`);\n }\n /** Reage com um emoji. @param {string} emoji */\n async react(emoji) {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n /** Tira a rea\u00E7\u00E3o do bot. @param {string} emoji */\n async unreact(emoji) {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n}\n", "// Construtor de embeds no mesmo formato do discord.js (e do webhook do Five\n// Live): t\u00EDtulo, descri\u00E7\u00E3o, cor, autor, campos, imagem, miniatura, rodap\u00E9.\n\n/** @param {string | number} color */\nfunction toColor(color) {\n if (typeof color === \"number\") return color;\n const hex = String(color).replace(/^#/, \"\");\n return /^[0-9a-f]{6}$/i.test(hex) ? parseInt(hex, 16) : undefined;\n}\n\nexport class EmbedBuilder {\n /** @param {Record<string, unknown>} [data] */\n constructor(data = {}) {\n /** @type {Record<string, any>} */\n this.data = { ...data };\n }\n setTitle(title) {\n this.data.title = title;\n return this;\n }\n setDescription(description) {\n this.data.description = description;\n return this;\n }\n setURL(url) {\n this.data.url = url;\n return this;\n }\n /** @param {string | number} color \"#3b6cf6\" ou 0x3b6cf6 */\n setColor(color) {\n this.data.color = toColor(color);\n return this;\n }\n /** @param {{ name: string, url?: string, iconURL?: string }} author */\n setAuthor(author) {\n this.data.author = { name: author.name, url: author.url, icon_url: author.iconURL };\n return this;\n }\n /** @param {{ text: string, iconURL?: string }} footer */\n setFooter(footer) {\n this.data.footer = { text: footer.text, icon_url: footer.iconURL };\n return this;\n }\n setImage(url) {\n this.data.image = { url };\n return this;\n }\n setThumbnail(url) {\n this.data.thumbnail = { url };\n return this;\n }\n /** @param {Date | number | string} [timestamp] */\n setTimestamp(timestamp = new Date()) {\n this.data.timestamp = new Date(timestamp).toISOString();\n return this;\n }\n /** @param {...{ name: string, value: string, inline?: boolean }} fields */\n addFields(...fields) {\n this.data.fields = [...(this.data.fields ?? []), ...fields.flat()];\n return this;\n }\n toJSON() {\n return this.data;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "Channel", "Client", "EmbedBuilder", "FiveLiveAPIError", "Group", "Message", "REST", "User", "channelMention", "userMention", "__toCommonJS", "import_node_events", "FiveLiveAPIError", "message", "status", "method", "path", "sleep", "ms", "resolve", "REST", "options", "body", "attempt", "res", "data", "seconds", "enc", "userMention", "id", "channelMention", "messagePayload", "input", "options", "embeds", "embed", "roles", "User", "client", "data", "Channel", "group", "enc", "content", "Message", "query", "message", "Group", "channel", "idOrName", "member", "key", "userId", "reason", "roleId", "role", "_Message", "author", "mentions", "entry", "whole", "user", "payload", "emoji", "DEFAULT_API", "KEEPALIVE_MS", "MAX_BACKOFF_MS", "socketClass", "mod", "Client", "options", "REST", "command", "alias", "seen", "commands", "err", "message", "name", "args", "context", "content", "me", "data", "raw", "held", "Group", "id", "user", "User", "Socket", "resolve", "reject", "ws", "settled", "send", "payload", "event", "msg", "first", "delay", "Message", "group", "toColor", "color", "hex", "EmbedBuilder", "data", "title", "description", "url", "author", "footer", "timestamp", "fields"]
|
|
7
7
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -183,10 +183,21 @@ export interface CommandContext {
|
|
|
183
183
|
reply(content: MessageContent): Promise<Message>;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/** One argument a slash command takes — how the composer prompts for it and labels it under the box. */
|
|
187
|
+
export interface CommandOption {
|
|
188
|
+
name: string;
|
|
189
|
+
description: string;
|
|
190
|
+
required?: boolean;
|
|
191
|
+
type?: "string" | "number" | "boolean" | "user";
|
|
192
|
+
}
|
|
193
|
+
|
|
186
194
|
export interface Command {
|
|
187
195
|
name: string;
|
|
196
|
+
/** With a description, this also becomes a "/" (slash) command in the composer's picker. */
|
|
188
197
|
description?: string;
|
|
189
198
|
aliases?: string[];
|
|
199
|
+
/** The arguments a slash command takes — only used when `description` is set. */
|
|
200
|
+
options?: CommandOption[];
|
|
190
201
|
run(context: CommandContext): unknown;
|
|
191
202
|
}
|
|
192
203
|
|
|
@@ -221,6 +232,8 @@ export class Client extends EventEmitter {
|
|
|
221
232
|
login(): Promise<User>;
|
|
222
233
|
destroy(): void;
|
|
223
234
|
command(command: Command): this;
|
|
235
|
+
/** Sends every command with a description to the API as the "/" manifest — run automatically at the end of `login()`. */
|
|
236
|
+
syncCommands(): Promise<void>;
|
|
224
237
|
fetchGroup(id: string): Promise<Group>;
|
|
225
238
|
fetchUser(id: string): Promise<User>;
|
|
226
239
|
on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): this;
|
package/dist/index.d.mts
CHANGED
|
@@ -183,10 +183,21 @@ export interface CommandContext {
|
|
|
183
183
|
reply(content: MessageContent): Promise<Message>;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/** One argument a slash command takes — how the composer prompts for it and labels it under the box. */
|
|
187
|
+
export interface CommandOption {
|
|
188
|
+
name: string;
|
|
189
|
+
description: string;
|
|
190
|
+
required?: boolean;
|
|
191
|
+
type?: "string" | "number" | "boolean" | "user";
|
|
192
|
+
}
|
|
193
|
+
|
|
186
194
|
export interface Command {
|
|
187
195
|
name: string;
|
|
196
|
+
/** With a description, this also becomes a "/" (slash) command in the composer's picker. */
|
|
188
197
|
description?: string;
|
|
189
198
|
aliases?: string[];
|
|
199
|
+
/** The arguments a slash command takes — only used when `description` is set. */
|
|
200
|
+
options?: CommandOption[];
|
|
190
201
|
run(context: CommandContext): unknown;
|
|
191
202
|
}
|
|
192
203
|
|
|
@@ -221,6 +232,8 @@ export class Client extends EventEmitter {
|
|
|
221
232
|
login(): Promise<User>;
|
|
222
233
|
destroy(): void;
|
|
223
234
|
command(command: Command): this;
|
|
235
|
+
/** Sends every command with a description to the API as the "/" manifest — run automatically at the end of `login()`. */
|
|
236
|
+
syncCommands(): Promise<void>;
|
|
224
237
|
fetchGroup(id: string): Promise<Group>;
|
|
225
238
|
fetchUser(id: string): Promise<User>;
|
|
226
239
|
on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): this;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{EventEmitter as v}from"node:events";var g=class extends Error{constructor(t,e,s,r){super(t),this.name="FiveLiveAPIError",this.status=e,this.method=s,this.path=r}},_=i=>new Promise(t=>setTimeout(t,i)),m=class{constructor(t){this.token=t.token,this.apiUrl=t.apiUrl.replace(/\/$/,""),this.retries=t.retries??3}async request(t,e,s){for(let r=0;;r++){let a=await fetch(this.apiUrl+e,{method:t,headers:{Authorization:`Bot ${this.token}`,...s!==void 0?{"Content-Type":"application/json"}:{},"User-Agent":"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)"},body:s!==void 0?JSON.stringify(s):void 0}),o=await a.json().catch(()=>({}));if(a.status===429&&r<this.retries){let h=Number(o.retryAfter??a.headers.get("retry-after")??5);await _(Math.max(1,h)*1e3);continue}if(!a.ok)throw new g(o.error??`HTTP ${a.status}`,a.status,t,e);return o}}get(t){return this.request("GET",t)}post(t,e){return this.request("POST",t,e??{})}patch(t,e){return this.request("PATCH",t,e??{})}put(t,e){return this.request("PUT",t,e??{})}delete(t){return this.request("DELETE",t)}},n=encodeURIComponent;var b=i=>`<@${i}>`,$=i=>`<#${i}>`;function y(i){let t=typeof i=="string"?{content:i}:i??{},e=(t.embeds??[]).map(r=>typeof r?.toJSON=="function"?r.toJSON():r),s=(t.roleMentions??[]).map(r=>`@role:${r}`);return{text:t.content??"",...e.length?{embeds:e}:{},...t.mentions?.length||s.length||t.everyone?{mentions:[...t.mentions??[],...s,...t.everyone?["@everyone"]:[]]}:{},...t.reply?{replyTo:typeof t.reply=="string"?t.reply:t.reply.id}:{}}}var u=class{constructor(t,e){this.client=t,this.id=e.id,this.username=e.username??null,this.displayName=e.displayName??e.name??e.username??"",this.avatarURL=e.avatarUrl??null,this.bot=e.bot===!0,this.flags=e.flags??[]}toString(){return b(this.id)}},f=class{constructor(t,e,s){this.client=t,this.group=e,this.id=s.id,this.name=s.name,this.kind=s.kind,this.categoryId=s.categoryId??null,this.topic=s.topic??""}get isText(){return this.kind==="text"}get path(){return`/bot/groups/${n(this.group.id)}/channels/${n(this.id)}`}async send(t){let e=await this.client.rest.post(`${this.path}/messages`,y(t));return new c(this.client,e.message,this.client.user)}async sendTyping(){await this.client.rest.post(`${this.path}/typing`,{typing:!0})}async fetchMessages(t={}){let e=new URLSearchParams;return t.limit&&e.set("limit",String(t.limit)),t.after&&e.set("after",t.after),(await this.client.rest.get(`${this.path}/messages?${e}`)).messages.map(r=>new c(this.client,r))}async fetchMessage(t){let e=await this.client.rest.get(`${this.path}/messages/${n(t)}`);return new c(this.client,e.message)}toString(){return`<#${this.id}>`}},p=class{constructor(t,e){this.client=t,this._patch(e)}_patch(t){this.id=t.id,this.name=t.name,this.iconURL=t.iconUrl??null,this.ownerId=t.ownerId??null,this.memberCount=t.memberCount??0,this.roles=t.roles??[],this.permissions=t.permissions??{},this.channels=new Map((t.channels??[]).map(e=>[e.id,new f(this.client,this,e)]))}channel(t){return this.channels.get(t)??[...this.channels.values()].find(e=>e.name===t)??null}async fetchMembers(){return(await this.client.rest.get(`/bot/groups/${n(this.id)}/members`)).members.map(e=>({...e,user:this.client._cacheUser(e)}))}get path(){return`/bot/groups/${n(this.id)}`}can(t){return this.permissions.administrator===!0||this.permissions[t]===!0}async kick(t){await this.client.rest.post(`${this.path}/members/${n(t)}/kick`,{})}async ban(t,e){await this.client.rest.put(`${this.path}/bans/${n(t)}`,e?{reason:e}:{})}async unban(t){await this.client.rest.delete(`${this.path}/bans/${n(t)}`)}async fetchBans(){return(await this.client.rest.get(`${this.path}/bans`)).bans}async addRole(t,e){return(await this.client.rest.put(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async removeRole(t,e){return(await this.client.rest.delete(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async leave(){await this.client.rest.post(`${this.path}/leave`,{})}role(t){return this.roles.find(e=>e.id===t||e.name===t)??null}},c=class i{constructor(t,e,s){this.client=t,this.id=e.id,this.groupId=e.groupId,this.channelId=e.channelId,this.content=e.text??"",this.embeds=e.embeds??[],this.attachments=e.attachments??[],this.images=e.images??[],this.reactions=e.reactions??[],this.replyTo=e.replyTo??null,this.createdAt=new Date(e.ts??Date.now()),this.editedAt=e.editedAt?new Date(e.editedAt):null,this.pinned=!!e.pinnedAt,this.webhook=!!e.webhook;let r=e.mentions??[];this.mentions={users:r.filter(a=>!a.startsWith("@")),roles:r.filter(a=>a.startsWith("@role:")).map(a=>a.slice(6)),everyone:r.includes("@everyone"),raw:r},this.author=s instanceof u?s:s?t._cacheUser(s):t.users.get(e.from)??new u(t,{id:e.from,name:e.fromName})}get group(){return this.client.groups.get(this.groupId)??null}get channel(){return this.group?.channels.get(this.channelId)??null}get cleanContent(){return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g,(t,e)=>{let s=this.client.users.get(e);return s?`@${s.displayName}`:t})}get mentionsMe(){return this.mentions.users.includes(this.client.user?.id)||this.mentions.everyone}get path(){return`/bot/groups/${n(this.groupId)}/channels/${n(this.channelId)}/messages`}async reply(t){let e=y(t),s=await this.client.rest.post(this.path,{...e,replyTo:this.id});return new i(this.client,s.message,this.client.user)}async edit(t){let e=y(t),s=await this.client.rest.patch(`${this.path}/${n(this.id)}`,{text:e.text,...e.embeds?{embeds:e.embeds}:{}});return new i(this.client,s.message,this.author)}async pin(){await this.client.rest.put(`${this.path}/${n(this.id)}/pin`)}async unpin(){await this.client.rest.delete(`${this.path}/${n(this.id)}/pin`)}async delete(){await this.client.rest.delete(`${this.path}/${n(this.id)}`)}async react(t){await this.client.rest.put(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}async unreact(t){await this.client.rest.delete(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}};var k="https://api.fivenetwork.dev",U=3e4,x=3e4;async function S(){if(typeof globalThis.WebSocket=="function")return globalThis.WebSocket;try{let i=await import("ws");return i.default??i.WebSocket}catch{throw new Error("Este Node n\xE3o tem WebSocket nativo (\xE9 do Node 22+). Rode `npm install ws` ou atualize o Node.")}}var w=class extends v{constructor(t){if(super(),!t?.token||!String(t.token).startsWith("b_"))throw new Error("Passe o token do bot (come\xE7a com b_). Pegue em https://live.fivenetwork.dev/developers.");this.token=t.token,this.apiUrl=(t.apiUrl??k).replace(/\/$/,""),this.gatewayUrl=t.gatewayUrl??`${this.apiUrl.replace(/^http/,"ws")}/ws`,this.prefix=t.prefix??"!",this.ignoreBots=t.ignoreBots??!0,this.rest=new m({token:this.token,apiUrl:this.apiUrl}),this.user=null,this.groups=new Map,this.users=new Map,this.commands=new Map,this._ws=null,this._ready=!1,this._closing=!1,this._attempt=0,this._keepalive=null}command(t){this.commands.set(t.name.toLowerCase(),t);for(let e of t.aliases??[])this.commands.set(e.toLowerCase(),t);return this}async _runCommand(t){if(!this.commands.size||!t.content.startsWith(this.prefix))return;let[e,...s]=t.content.slice(this.prefix.length).trim().split(/\s+/),r=this.commands.get((e??"").toLowerCase());if(!r)return;let a={message:t,args:s,client:this,reply:o=>t.reply(o)};try{await r.run(a)}catch(o){this.listenerCount("commandError")?this.emit("commandError",o,a):this.emit("error",o)}}async login(){let t=await this.rest.get("/bot/@me");return this.user=this._cacheUser({...t.bot,bot:!0}),await this._loadGroups(),this._closing=!1,await this._connect(),this.user}destroy(){this._closing=!0,clearInterval(this._keepalive);try{this._ws?.close()}catch{}}async _loadGroups(){let t=await this.rest.get("/bot/groups"),e=new Set;for(let s of t.groups){e.add(s.id);let r=this.groups.get(s.id);r?r._patch(s):this.groups.set(s.id,new p(this,s))}for(let s of[...this.groups.keys()])e.has(s)||this.groups.delete(s)}async fetchGroup(t){let e=await this.rest.get(`/bot/groups/${encodeURIComponent(t)}`),s=this.groups.get(t);return s?s._patch(e.group):this.groups.set(t,new p(this,e.group)),this.groups.get(t)}async fetchUser(t){let e=await this.rest.get(`/bot/users/${encodeURIComponent(t)}`);return this._cacheUser(e.user)}_cacheUser(t){let e=new u(this,t);return this.users.set(e.id,e),e}async _connect(){let t=await S();return new Promise((e,s)=>{let r=new t(this.gatewayUrl);this._ws=r;let a=!1,o=h=>{r.readyState===1&&r.send(JSON.stringify(h))};r.onopen=()=>{o({type:"register",name:this.user.displayName||this.user.username,token:this.token}),clearInterval(this._keepalive),this._keepalive=setInterval(()=>o({type:"time-sync",t0:Date.now()}),U)},r.onmessage=h=>{let d;try{d=JSON.parse(typeof h.data=="string"?h.data:h.data.toString())}catch{return}if(d.type==="registered"){let l=!this._ready;this._ready=!0,this._attempt=0,a||(a=!0,e()),l?this.emit("ready",this.user):this.emit("reconnected");return}if(d.type==="register-error"){this._closing=!0;let l=new Error(d.message||"O Five Live recusou o token do bot.");a?this.emit("error",l):(a=!0,s(l));return}this._dispatch(d).catch(l=>this.emit("error",l))},r.onerror=h=>{!a&&this._attempt===0&&!this._ready&&(a=!0,s(new Error(`N\xE3o foi poss\xEDvel conectar em ${this.gatewayUrl}: ${h?.message??"erro de rede"}`)))},r.onclose=()=>{clearInterval(this._keepalive),this.emit("disconnect"),!(this._closing||!this._ready)&&this._reconnect()}})}_reconnect(){this._attempt+=1;let t=Math.min(x,1e3*2**Math.min(this._attempt-1,5))+Math.random()*500;this.emit("reconnecting",this._attempt),setTimeout(async()=>{if(!this._closing)try{await this._loadGroups(),await this._connect()}catch{this._reconnect()}},t)}async _dispatch(t){switch(t.type){case"group-message":{if(!t.message)return;let e=new c(this,t.message,t.author?{...t.author}:void 0);if(e.author.id===this.user?.id||this.ignoreBots&&e.author.bot)return;this.emit("messageCreate",e),await this._runCommand(e);return}case"group-message-updated":t.message&&this.emit("messageUpdate",new c(this,t.message));return;case"group-message-deleted":this.emit("messageDelete",{id:t.messageId,groupId:t.groupId,channelId:t.channelId});return;case"group-message-reactions":this.emit("reactionUpdate",{messageId:t.messageId,groupId:t.groupId,channelId:t.channelId,reactions:t.reactions??[]});return;case"group-typing":t.userId!==this.user?.id&&t.typing!==!1&&this.emit("typingStart",{userId:t.userId,name:t.name,groupId:t.groupId,channelId:t.channelId});return;case"group-joined":{let e=await this.fetchGroup(t.groupId);this.emit("groupJoin",e);return}case"group-updated":{if(!this.groups.has(t.groupId))return;let e=await this.fetchGroup(t.groupId).catch(()=>null);e&&this.emit("groupUpdate",e);return}case"group-member-add":{if(!t.member)return;let e=this._cacheUser(t.member),s=this.groups.get(t.groupId)??await this.fetchGroup(t.groupId).catch(()=>null);s&&(s.memberCount+=1),this.emit("memberAdd",{user:e,group:s,groupId:t.groupId,via:t.via??null});return}case"group-member-remove":{let e=this.groups.get(t.groupId)??null;e&&(e.memberCount=Math.max(0,e.memberCount-1)),this.emit("memberRemove",{userId:t.userId,user:this.users.get(t.userId)??null,group:e,groupId:t.groupId,reason:t.reason??null,by:t.by??null});return}case"group-removed":this.groups.delete(t.groupId),this.emit("groupLeave",{id:t.groupId,reason:t.reason??null});return;default:this.emit("raw",t)}}};function T(i){if(typeof i=="number")return i;let t=String(i).replace(/^#/,"");return/^[0-9a-f]{6}$/i.test(t)?parseInt(t,16):void 0}var I=class{constructor(t={}){this.data={...t}}setTitle(t){return this.data.title=t,this}setDescription(t){return this.data.description=t,this}setURL(t){return this.data.url=t,this}setColor(t){return this.data.color=T(t),this}setAuthor(t){return this.data.author={name:t.name,url:t.url,icon_url:t.iconURL},this}setFooter(t){return this.data.footer={text:t.text,icon_url:t.iconURL},this}setImage(t){return this.data.image={url:t},this}setThumbnail(t){return this.data.thumbnail={url:t},this}setTimestamp(t=new Date){return this.data.timestamp=new Date(t).toISOString(),this}addFields(...t){return this.data.fields=[...this.data.fields??[],...t.flat()],this}toJSON(){return this.data}};export{f as Channel,w as Client,I as EmbedBuilder,g as FiveLiveAPIError,p as Group,c as Message,m as REST,u as User,$ as channelMention,b as userMention};
|
|
1
|
+
import{EventEmitter as v}from"node:events";var g=class extends Error{constructor(t,e,s,i){super(t),this.name="FiveLiveAPIError",this.status=e,this.method=s,this.path=i}},_=r=>new Promise(t=>setTimeout(t,r)),m=class{constructor(t){this.token=t.token,this.apiUrl=t.apiUrl.replace(/\/$/,""),this.retries=t.retries??3}async request(t,e,s){for(let i=0;;i++){let a=await fetch(this.apiUrl+e,{method:t,headers:{Authorization:`Bot ${this.token}`,...s!==void 0?{"Content-Type":"application/json"}:{},"User-Agent":"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)"},body:s!==void 0?JSON.stringify(s):void 0}),o=await a.json().catch(()=>({}));if(a.status===429&&i<this.retries){let h=Number(o.retryAfter??a.headers.get("retry-after")??5);await _(Math.max(1,h)*1e3);continue}if(!a.ok)throw new g(o.error??`HTTP ${a.status}`,a.status,t,e);return o}}get(t){return this.request("GET",t)}post(t,e){return this.request("POST",t,e??{})}patch(t,e){return this.request("PATCH",t,e??{})}put(t,e){return this.request("PUT",t,e??{})}delete(t){return this.request("DELETE",t)}},n=encodeURIComponent;var b=r=>`<@${r}>`,$=r=>`<#${r}>`;function y(r){let t=typeof r=="string"?{content:r}:r??{},e=(t.embeds??[]).map(i=>typeof i?.toJSON=="function"?i.toJSON():i),s=(t.roleMentions??[]).map(i=>`@role:${i}`);return{text:t.content??"",...e.length?{embeds:e}:{},...t.mentions?.length||s.length||t.everyone?{mentions:[...t.mentions??[],...s,...t.everyone?["@everyone"]:[]]}:{},...t.reply?{replyTo:typeof t.reply=="string"?t.reply:t.reply.id}:{}}}var u=class{constructor(t,e){this.client=t,this.id=e.id,this.username=e.username??null,this.displayName=e.displayName??e.name??e.username??"",this.avatarURL=e.avatarUrl??null,this.bot=e.bot===!0,this.flags=e.flags??[]}toString(){return b(this.id)}},f=class{constructor(t,e,s){this.client=t,this.group=e,this.id=s.id,this.name=s.name,this.kind=s.kind,this.categoryId=s.categoryId??null,this.topic=s.topic??""}get isText(){return this.kind==="text"}get path(){return`/bot/groups/${n(this.group.id)}/channels/${n(this.id)}`}async send(t){let e=await this.client.rest.post(`${this.path}/messages`,y(t));return new c(this.client,e.message,this.client.user)}async sendTyping(){await this.client.rest.post(`${this.path}/typing`,{typing:!0})}async fetchMessages(t={}){let e=new URLSearchParams;return t.limit&&e.set("limit",String(t.limit)),t.after&&e.set("after",t.after),(await this.client.rest.get(`${this.path}/messages?${e}`)).messages.map(i=>new c(this.client,i))}async fetchMessage(t){let e=await this.client.rest.get(`${this.path}/messages/${n(t)}`);return new c(this.client,e.message)}toString(){return`<#${this.id}>`}},p=class{constructor(t,e){this.client=t,this._patch(e)}_patch(t){this.id=t.id,this.name=t.name,this.iconURL=t.iconUrl??null,this.ownerId=t.ownerId??null,this.memberCount=t.memberCount??0,this.roles=t.roles??[],this.permissions=t.permissions??{},this.channels=new Map((t.channels??[]).map(e=>[e.id,new f(this.client,this,e)]))}channel(t){return this.channels.get(t)??[...this.channels.values()].find(e=>e.name===t)??null}async fetchMembers(){return(await this.client.rest.get(`/bot/groups/${n(this.id)}/members`)).members.map(e=>({...e,user:this.client._cacheUser(e)}))}get path(){return`/bot/groups/${n(this.id)}`}can(t){return this.permissions.administrator===!0||this.permissions[t]===!0}async kick(t){await this.client.rest.post(`${this.path}/members/${n(t)}/kick`,{})}async ban(t,e){await this.client.rest.put(`${this.path}/bans/${n(t)}`,e?{reason:e}:{})}async unban(t){await this.client.rest.delete(`${this.path}/bans/${n(t)}`)}async fetchBans(){return(await this.client.rest.get(`${this.path}/bans`)).bans}async addRole(t,e){return(await this.client.rest.put(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async removeRole(t,e){return(await this.client.rest.delete(`${this.path}/members/${n(t)}/roles/${n(e)}`)).roleIds}async leave(){await this.client.rest.post(`${this.path}/leave`,{})}role(t){return this.roles.find(e=>e.id===t||e.name===t)??null}},c=class r{constructor(t,e,s){this.client=t,this.id=e.id,this.groupId=e.groupId,this.channelId=e.channelId,this.content=e.text??"",this.embeds=e.embeds??[],this.attachments=e.attachments??[],this.images=e.images??[],this.reactions=e.reactions??[],this.replyTo=e.replyTo??null,this.createdAt=new Date(e.ts??Date.now()),this.editedAt=e.editedAt?new Date(e.editedAt):null,this.pinned=!!e.pinnedAt,this.webhook=!!e.webhook;let i=e.mentions??[];this.mentions={users:i.filter(a=>!a.startsWith("@")),roles:i.filter(a=>a.startsWith("@role:")).map(a=>a.slice(6)),everyone:i.includes("@everyone"),raw:i},this.author=s instanceof u?s:s?t._cacheUser(s):t.users.get(e.from)??new u(t,{id:e.from,name:e.fromName})}get group(){return this.client.groups.get(this.groupId)??null}get channel(){return this.group?.channels.get(this.channelId)??null}get cleanContent(){return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g,(t,e)=>{let s=this.client.users.get(e);return s?`@${s.displayName}`:t})}get mentionsMe(){return this.mentions.users.includes(this.client.user?.id)||this.mentions.everyone}get path(){return`/bot/groups/${n(this.groupId)}/channels/${n(this.channelId)}/messages`}async reply(t){let e=y(t),s=await this.client.rest.post(this.path,{...e,replyTo:this.id});return new r(this.client,s.message,this.client.user)}async edit(t){let e=y(t),s=await this.client.rest.patch(`${this.path}/${n(this.id)}`,{text:e.text,...e.embeds?{embeds:e.embeds}:{}});return new r(this.client,s.message,this.author)}async pin(){await this.client.rest.put(`${this.path}/${n(this.id)}/pin`)}async unpin(){await this.client.rest.delete(`${this.path}/${n(this.id)}/pin`)}async delete(){await this.client.rest.delete(`${this.path}/${n(this.id)}`)}async react(t){await this.client.rest.put(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}async unreact(t){await this.client.rest.delete(`${this.path}/${n(this.id)}/reactions/${n(t)}`)}};var k="https://api.fivenetwork.dev",U=3e4,x=3e4;async function S(){if(typeof globalThis.WebSocket=="function")return globalThis.WebSocket;try{let r=await import("ws");return r.default??r.WebSocket}catch{throw new Error("Este Node n\xE3o tem WebSocket nativo (\xE9 do Node 22+). Rode `npm install ws` ou atualize o Node.")}}var w=class extends v{constructor(t){if(super(),!t?.token||!String(t.token).startsWith("b_"))throw new Error("Passe o token do bot (come\xE7a com b_). Pegue em https://live.fivenetwork.dev/developers.");this.token=t.token,this.apiUrl=(t.apiUrl??k).replace(/\/$/,""),this.gatewayUrl=t.gatewayUrl??`${this.apiUrl.replace(/^http/,"ws")}/ws`,this.prefix=t.prefix??"!",this.ignoreBots=t.ignoreBots??!0,this.rest=new m({token:this.token,apiUrl:this.apiUrl}),this.user=null,this.groups=new Map,this.users=new Map,this.commands=new Map,this._ws=null,this._ready=!1,this._closing=!1,this._attempt=0,this._keepalive=null}command(t){this.commands.set(t.name.toLowerCase(),t);for(let e of t.aliases??[])this.commands.set(e.toLowerCase(),t);return this}async syncCommands(){let t=new Set,e=[];for(let s of this.commands.values())t.has(s.name)||!s.description||(t.add(s.name),e.push({name:s.name,description:s.description,options:s.options??[]}));try{await this.rest.put("/bot/commands",{prefix:this.prefix,commands:e})}catch(s){this.emit("error",s)}}async _runCommand(t){if(!this.commands.size||!t.content.startsWith(this.prefix))return;let[e,...s]=t.content.slice(this.prefix.length).trim().split(/\s+/),i=this.commands.get((e??"").toLowerCase());if(!i)return;let a={message:t,args:s,client:this,reply:o=>t.reply(o)};try{await i.run(a)}catch(o){this.listenerCount("commandError")?this.emit("commandError",o,a):this.emit("error",o)}}async login(){let t=await this.rest.get("/bot/@me");return this.user=this._cacheUser({...t.bot,bot:!0}),await this._loadGroups(),await this.syncCommands(),this._closing=!1,await this._connect(),this.user}destroy(){this._closing=!0,clearInterval(this._keepalive);try{this._ws?.close()}catch{}}async _loadGroups(){let t=await this.rest.get("/bot/groups"),e=new Set;for(let s of t.groups){e.add(s.id);let i=this.groups.get(s.id);i?i._patch(s):this.groups.set(s.id,new p(this,s))}for(let s of[...this.groups.keys()])e.has(s)||this.groups.delete(s)}async fetchGroup(t){let e=await this.rest.get(`/bot/groups/${encodeURIComponent(t)}`),s=this.groups.get(t);return s?s._patch(e.group):this.groups.set(t,new p(this,e.group)),this.groups.get(t)}async fetchUser(t){let e=await this.rest.get(`/bot/users/${encodeURIComponent(t)}`);return this._cacheUser(e.user)}_cacheUser(t){let e=new u(this,t);return this.users.set(e.id,e),e}async _connect(){let t=await S();return new Promise((e,s)=>{let i=new t(this.gatewayUrl);this._ws=i;let a=!1,o=h=>{i.readyState===1&&i.send(JSON.stringify(h))};i.onopen=()=>{o({type:"register",name:this.user.displayName||this.user.username,token:this.token}),clearInterval(this._keepalive),this._keepalive=setInterval(()=>o({type:"time-sync",t0:Date.now()}),U)},i.onmessage=h=>{let d;try{d=JSON.parse(typeof h.data=="string"?h.data:h.data.toString())}catch{return}if(d.type==="registered"){let l=!this._ready;this._ready=!0,this._attempt=0,a||(a=!0,e()),l?this.emit("ready",this.user):this.emit("reconnected");return}if(d.type==="register-error"){this._closing=!0;let l=new Error(d.message||"O Five Live recusou o token do bot.");a?this.emit("error",l):(a=!0,s(l));return}this._dispatch(d).catch(l=>this.emit("error",l))},i.onerror=h=>{!a&&this._attempt===0&&!this._ready&&(a=!0,s(new Error(`N\xE3o foi poss\xEDvel conectar em ${this.gatewayUrl}: ${h?.message??"erro de rede"}`)))},i.onclose=()=>{clearInterval(this._keepalive),this.emit("disconnect"),!(this._closing||!this._ready)&&this._reconnect()}})}_reconnect(){this._attempt+=1;let t=Math.min(x,1e3*2**Math.min(this._attempt-1,5))+Math.random()*500;this.emit("reconnecting",this._attempt),setTimeout(async()=>{if(!this._closing)try{await this._loadGroups(),await this._connect()}catch{this._reconnect()}},t)}async _dispatch(t){switch(t.type){case"group-message":{if(!t.message)return;let e=new c(this,t.message,t.author?{...t.author}:void 0);if(e.author.id===this.user?.id||this.ignoreBots&&e.author.bot)return;this.emit("messageCreate",e),await this._runCommand(e);return}case"group-message-updated":t.message&&this.emit("messageUpdate",new c(this,t.message));return;case"group-message-deleted":this.emit("messageDelete",{id:t.messageId,groupId:t.groupId,channelId:t.channelId});return;case"group-message-reactions":this.emit("reactionUpdate",{messageId:t.messageId,groupId:t.groupId,channelId:t.channelId,reactions:t.reactions??[]});return;case"group-typing":t.userId!==this.user?.id&&t.typing!==!1&&this.emit("typingStart",{userId:t.userId,name:t.name,groupId:t.groupId,channelId:t.channelId});return;case"group-joined":{let e=await this.fetchGroup(t.groupId);this.emit("groupJoin",e);return}case"group-updated":{if(!this.groups.has(t.groupId))return;let e=await this.fetchGroup(t.groupId).catch(()=>null);e&&this.emit("groupUpdate",e);return}case"group-member-add":{if(!t.member)return;let e=this._cacheUser(t.member),s=this.groups.get(t.groupId)??await this.fetchGroup(t.groupId).catch(()=>null);s&&(s.memberCount+=1),this.emit("memberAdd",{user:e,group:s,groupId:t.groupId,via:t.via??null});return}case"group-member-remove":{let e=this.groups.get(t.groupId)??null;e&&(e.memberCount=Math.max(0,e.memberCount-1)),this.emit("memberRemove",{userId:t.userId,user:this.users.get(t.userId)??null,group:e,groupId:t.groupId,reason:t.reason??null,by:t.by??null});return}case"group-removed":this.groups.delete(t.groupId),this.emit("groupLeave",{id:t.groupId,reason:t.reason??null});return;default:this.emit("raw",t)}}};function C(r){if(typeof r=="number")return r;let t=String(r).replace(/^#/,"");return/^[0-9a-f]{6}$/i.test(t)?parseInt(t,16):void 0}var I=class{constructor(t={}){this.data={...t}}setTitle(t){return this.data.title=t,this}setDescription(t){return this.data.description=t,this}setURL(t){return this.data.url=t,this}setColor(t){return this.data.color=C(t),this}setAuthor(t){return this.data.author={name:t.name,url:t.url,icon_url:t.iconURL},this}setFooter(t){return this.data.footer={text:t.text,icon_url:t.iconURL},this}setImage(t){return this.data.image={url:t},this}setThumbnail(t){return this.data.thumbnail={url:t},this}setTimestamp(t=new Date){return this.data.timestamp=new Date(t).toISOString(),this}addFields(...t){return this.data.fields=[...this.data.fields??[],...t.flat()],this}toJSON(){return this.data}};export{f as Channel,w as Client,I as EmbedBuilder,g as FiveLiveAPIError,p as Group,c as Message,m as REST,u as User,$ as channelMention,b as userMention};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client.js", "../src/rest.js", "../src/structures.js", "../src/embed.js"],
|
|
4
|
-
"sourcesContent": ["// O Client: conecta no WebSocket do Five Live com o token do bot, mant\u00E9m a\n// conex\u00E3o viva (e reconecta sozinho), transforma os avisos da API em eventos\n// e guarda grupos e usu\u00E1rios conhecidos.\n//\n// Eventos:\n// ready(user) conectou e carregou os grupos\n// messageCreate(message) mensagem nova num grupo do bot\n// messageUpdate(message) mensagem editada\n// messageDelete({ id, groupId, channelId })\n// reactionUpdate({ messageId, groupId, channelId, reactions })\n// typingStart({ userId, name, groupId, channelId })\n// groupJoin(group) / groupLeave({ id, reason }) / groupUpdate(group)\n// reconnecting(attempt) / reconnected() / disconnect() / error(err)\n// commandError(err, context)\n\nimport { EventEmitter } from \"node:events\";\nimport { REST } from \"./rest.js\";\nimport { Group, Message, User } from \"./structures.js\";\n\nconst DEFAULT_API = \"https://api.fivenetwork.dev\";\nconst KEEPALIVE_MS = 30_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nasync function socketClass() {\n if (typeof globalThis.WebSocket === \"function\") return globalThis.WebSocket;\n try {\n const mod = await import(\"ws\");\n return mod.default ?? mod.WebSocket;\n } catch {\n throw new Error(\"Este Node n\u00E3o tem WebSocket nativo (\u00E9 do Node 22+). Rode `npm install ws` ou atualize o Node.\");\n }\n}\n\nexport class Client extends EventEmitter {\n /**\n * @param {{\n * token: string,\n * apiUrl?: string,\n * gatewayUrl?: string,\n * prefix?: string,\n * ignoreBots?: boolean,\n * }} options\n */\n constructor(options) {\n super();\n if (!options?.token || !String(options.token).startsWith(\"b_\")) {\n throw new Error(\"Passe o token do bot (come\u00E7a com b_). Pegue em https://live.fivenetwork.dev/developers.\");\n }\n this.token = options.token;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API).replace(/\\/$/, \"\");\n this.gatewayUrl = options.gatewayUrl ?? `${this.apiUrl.replace(/^http/, \"ws\")}/ws`;\n this.prefix = options.prefix ?? \"!\";\n this.ignoreBots = options.ignoreBots ?? true;\n this.rest = new REST({ token: this.token, apiUrl: this.apiUrl });\n /** @type {User | null} */\n this.user = null;\n /** @type {Map<string, Group>} */\n this.groups = new Map();\n /** @type {Map<string, User>} */\n this.users = new Map();\n /** @type {Map<string, { name: string, description?: string, aliases?: string[], run: Function }>} */\n this.commands = new Map();\n this._ws = null;\n this._ready = false;\n this._closing = false;\n this._attempt = 0;\n this._keepalive = null;\n }\n\n // \u2500\u2500\u2500 Comandos com prefixo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Registra um comando: `!nome arg1 arg2`.\n * @param {{ name: string, description?: string, aliases?: string[], run: (ctx: { message: Message, args: string[], client: Client, reply: (content: any) => Promise<Message> }) => any }} command\n */\n command(command) {\n this.commands.set(command.name.toLowerCase(), command);\n for (const alias of command.aliases ?? []) this.commands.set(alias.toLowerCase(), command);\n return this;\n }\n\n /** @param {Message} message */\n async _runCommand(message) {\n if (!this.commands.size || !message.content.startsWith(this.prefix)) return;\n const [name, ...args] = message.content.slice(this.prefix.length).trim().split(/\\s+/);\n const command = this.commands.get((name ?? \"\").toLowerCase());\n if (!command) return;\n const context = { message, args, client: this, reply: (content) => message.reply(content) };\n try {\n await command.run(context);\n } catch (err) {\n if (this.listenerCount(\"commandError\")) this.emit(\"commandError\", err, context);\n else this.emit(\"error\", err);\n }\n }\n\n // \u2500\u2500\u2500 Conex\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Conecta. Resolve quando o bot estiver pronto (evento \"ready\"). */\n async login() {\n const me = await this.rest.get(\"/bot/@me\");\n this.user = this._cacheUser({ ...me.bot, bot: true });\n await this._loadGroups();\n this._closing = false;\n await this._connect();\n return this.user;\n }\n\n /** Desconecta de vez (sem reconectar). */\n destroy() {\n this._closing = true;\n clearInterval(this._keepalive);\n try {\n this._ws?.close();\n } catch {\n // j\u00E1 fechado\n }\n }\n\n async _loadGroups() {\n const data = await this.rest.get(\"/bot/groups\");\n const seen = new Set();\n for (const raw of data.groups) {\n seen.add(raw.id);\n const held = this.groups.get(raw.id);\n if (held) held._patch(raw);\n else this.groups.set(raw.id, new Group(this, raw));\n }\n for (const id of [...this.groups.keys()]) if (!seen.has(id)) this.groups.delete(id);\n }\n\n /** Um grupo, relido da API. @param {string} id */\n async fetchGroup(id) {\n const data = await this.rest.get(`/bot/groups/${encodeURIComponent(id)}`);\n const held = this.groups.get(id);\n if (held) held._patch(data.group);\n else this.groups.set(id, new Group(this, data.group));\n return this.groups.get(id);\n }\n\n /** Uma pessoa pelo id. @param {string} id */\n async fetchUser(id) {\n const data = await this.rest.get(`/bot/users/${encodeURIComponent(id)}`);\n return this._cacheUser(data.user);\n }\n\n /** @param {Record<string, any>} data */\n _cacheUser(data) {\n const user = new User(this, data);\n this.users.set(user.id, user);\n return user;\n }\n\n async _connect() {\n const Socket = await socketClass();\n return new Promise((resolve, reject) => {\n const ws = new Socket(this.gatewayUrl);\n this._ws = ws;\n let settled = false;\n const send = (payload) => {\n if (ws.readyState === 1) ws.send(JSON.stringify(payload));\n };\n ws.onopen = () => {\n send({ type: \"register\", name: this.user.displayName || this.user.username, token: this.token });\n clearInterval(this._keepalive);\n // O proxy da hospedagem derruba conex\u00E3o parada: uma mensagem leve de tempos em tempos.\n this._keepalive = setInterval(() => send({ type: \"time-sync\", t0: Date.now() }), KEEPALIVE_MS);\n };\n ws.onmessage = (event) => {\n let msg;\n try {\n msg = JSON.parse(typeof event.data === \"string\" ? event.data : event.data.toString());\n } catch {\n return;\n }\n if (msg.type === \"registered\") {\n const first = !this._ready;\n this._ready = true;\n this._attempt = 0;\n if (!settled) {\n settled = true;\n resolve();\n }\n if (first) this.emit(\"ready\", this.user);\n else this.emit(\"reconnected\");\n return;\n }\n if (msg.type === \"register-error\") {\n this._closing = true;\n const err = new Error(msg.message || \"O Five Live recusou o token do bot.\");\n if (!settled) {\n settled = true;\n reject(err);\n } else this.emit(\"error\", err);\n return;\n }\n this._dispatch(msg).catch((err) => this.emit(\"error\", err));\n };\n ws.onerror = (event) => {\n if (!settled && this._attempt === 0 && !this._ready) {\n settled = true;\n reject(new Error(`N\u00E3o foi poss\u00EDvel conectar em ${this.gatewayUrl}: ${event?.message ?? \"erro de rede\"}`));\n }\n };\n ws.onclose = () => {\n clearInterval(this._keepalive);\n this.emit(\"disconnect\");\n if (this._closing || !this._ready) return;\n this._reconnect();\n };\n });\n }\n\n _reconnect() {\n this._attempt += 1;\n const delay = Math.min(MAX_BACKOFF_MS, 1000 * 2 ** Math.min(this._attempt - 1, 5)) + Math.random() * 500;\n this.emit(\"reconnecting\", this._attempt);\n setTimeout(async () => {\n if (this._closing) return;\n try {\n // O que mudou enquanto estava fora (grupos que entrou/saiu).\n await this._loadGroups();\n await this._connect();\n } catch {\n this._reconnect();\n }\n }, delay);\n }\n\n /** @param {Record<string, any>} msg */\n async _dispatch(msg) {\n switch (msg.type) {\n case \"group-message\": {\n if (!msg.message) return;\n const message = new Message(this, msg.message, msg.author ? { ...msg.author } : undefined);\n if (message.author.id === this.user?.id) return;\n if (this.ignoreBots && message.author.bot) return;\n this.emit(\"messageCreate\", message);\n await this._runCommand(message);\n return;\n }\n case \"group-message-updated\":\n if (msg.message) this.emit(\"messageUpdate\", new Message(this, msg.message));\n return;\n case \"group-message-deleted\":\n this.emit(\"messageDelete\", { id: msg.messageId, groupId: msg.groupId, channelId: msg.channelId });\n return;\n case \"group-message-reactions\":\n this.emit(\"reactionUpdate\", { messageId: msg.messageId, groupId: msg.groupId, channelId: msg.channelId, reactions: msg.reactions ?? [] });\n return;\n case \"group-typing\":\n if (msg.userId !== this.user?.id && msg.typing !== false) {\n this.emit(\"typingStart\", { userId: msg.userId, name: msg.name, groupId: msg.groupId, channelId: msg.channelId });\n }\n return;\n case \"group-joined\": {\n const group = await this.fetchGroup(msg.groupId);\n this.emit(\"groupJoin\", group);\n return;\n }\n case \"group-updated\": {\n if (!this.groups.has(msg.groupId)) return;\n const group = await this.fetchGroup(msg.groupId).catch(() => null);\n if (group) this.emit(\"groupUpdate\", group);\n return;\n }\n case \"group-member-add\": {\n if (!msg.member) return;\n const user = this._cacheUser(msg.member);\n const group = this.groups.get(msg.groupId) ?? (await this.fetchGroup(msg.groupId).catch(() => null));\n if (group) group.memberCount += 1;\n this.emit(\"memberAdd\", { user, group, groupId: msg.groupId, via: msg.via ?? null });\n return;\n }\n case \"group-member-remove\": {\n const group = this.groups.get(msg.groupId) ?? null;\n if (group) group.memberCount = Math.max(0, group.memberCount - 1);\n this.emit(\"memberRemove\", { userId: msg.userId, user: this.users.get(msg.userId) ?? null, group, groupId: msg.groupId, reason: msg.reason ?? null, by: msg.by ?? null });\n return;\n }\n case \"group-removed\":\n this.groups.delete(msg.groupId);\n this.emit(\"groupLeave\", { id: msg.groupId, reason: msg.reason ?? null });\n return;\n default:\n this.emit(\"raw\", msg);\n }\n }\n}\n", "// As rotas HTTP da API de bots (api/botApi.mjs), com o token no cabe\u00E7alho\n// `Authorization: Bot <token>`. Trata o limite de envio (429) esperando o\n// tempo que a API pede e tentando de novo.\n\nexport class FiveLiveAPIError extends Error {\n /**\n * @param {string} message\n * @param {number} status\n * @param {string} method\n * @param {string} path\n */\n constructor(message, status, method, path) {\n super(message);\n this.name = \"FiveLiveAPIError\";\n this.status = status;\n this.method = method;\n this.path = path;\n }\n}\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class REST {\n /** @param {{ token: string, apiUrl: string, retries?: number }} options */\n constructor(options) {\n this.token = options.token;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.retries = options.retries ?? 3;\n }\n\n /**\n * @param {string} method\n * @param {string} path\n * @param {unknown} [body]\n */\n async request(method, path, body) {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(this.apiUrl + path, {\n method,\n headers: {\n Authorization: `Bot ${this.token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n \"User-Agent\": \"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)\",\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n const data = await res.json().catch(() => ({}));\n if (res.status === 429 && attempt < this.retries) {\n const seconds = Number(data.retryAfter ?? res.headers.get(\"retry-after\") ?? 5);\n await sleep(Math.max(1, seconds) * 1000);\n continue;\n }\n if (!res.ok) throw new FiveLiveAPIError(data.error ?? `HTTP ${res.status}`, res.status, method, path);\n return data;\n }\n }\n\n get(path) {\n return this.request(\"GET\", path);\n }\n post(path, body) {\n return this.request(\"POST\", path, body ?? {});\n }\n patch(path, body) {\n return this.request(\"PATCH\", path, body ?? {});\n }\n put(path, body) {\n return this.request(\"PUT\", path, body ?? {});\n }\n delete(path) {\n return this.request(\"DELETE\", path);\n }\n}\n\nexport const enc = encodeURIComponent;\n", "// Os objetos que o bot recebe: User, Group, Channel, Message. Cada um sabe\n// agir sobre si mesmo (message.reply, channel.send, \u2026) usando o client.\n\nimport { enc } from \"./rest.js\";\n\n/** `<@id>` \u2014 como mencionar algu\u00E9m no texto. */\nexport const userMention = (id) => `<@${id}>`;\n/** `<#id>` \u2014 como apontar uma sala no texto. */\nexport const channelMention = (id) => `<#${id}>`;\n\n/**\n * Normaliza o que se manda: um texto, ou { content, embeds, mentions, reply }.\n * @param {string | Record<string, any>} input\n */\nexport function messagePayload(input) {\n const options = typeof input === \"string\" ? { content: input } : input ?? {};\n const embeds = (options.embeds ?? []).map((embed) => (typeof embed?.toJSON === \"function\" ? embed.toJSON() : embed));\n const roles = (options.roleMentions ?? []).map((id) => `@role:${id}`);\n return {\n text: options.content ?? \"\",\n ...(embeds.length ? { embeds } : {}),\n ...(options.mentions?.length || roles.length || options.everyone\n ? { mentions: [...(options.mentions ?? []), ...roles, ...(options.everyone ? [\"@everyone\"] : [])] }\n : {}),\n ...(options.reply ? { replyTo: typeof options.reply === \"string\" ? options.reply : options.reply.id } : {}),\n };\n}\n\nexport class User {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this.id = data.id;\n this.username = data.username ?? null;\n this.displayName = data.displayName ?? data.name ?? data.username ?? \"\";\n this.avatarURL = data.avatarUrl ?? null;\n this.bot = data.bot === true;\n this.flags = data.flags ?? [];\n }\n /** `<@id>`, para colocar no texto. */\n toString() {\n return userMention(this.id);\n }\n}\n\nexport class Channel {\n /** @param {import(\"./client.js\").Client} client @param {Group} group @param {Record<string, any>} data */\n constructor(client, group, data) {\n this.client = client;\n this.group = group;\n this.id = data.id;\n this.name = data.name;\n /** \"text\" | \"voice\" */\n this.kind = data.kind;\n this.categoryId = data.categoryId ?? null;\n this.topic = data.topic ?? \"\";\n }\n get isText() {\n return this.kind === \"text\";\n }\n get path() {\n return `/bot/groups/${enc(this.group.id)}/channels/${enc(this.id)}`;\n }\n /** Manda uma mensagem. @param {string | Record<string, any>} content */\n async send(content) {\n const data = await this.client.rest.post(`${this.path}/messages`, messagePayload(content));\n return new Message(this.client, data.message, this.client.user);\n }\n /** \"Digitando\u2026\" por alguns segundos. */\n async sendTyping() {\n await this.client.rest.post(`${this.path}/typing`, { typing: true });\n }\n /**\n * As \u00FAltimas mensagens (a mais nova por \u00FAltimo).\n * @param {{ limit?: number, after?: string }} [options]\n */\n async fetchMessages(options = {}) {\n const query = new URLSearchParams();\n if (options.limit) query.set(\"limit\", String(options.limit));\n if (options.after) query.set(\"after\", options.after);\n const data = await this.client.rest.get(`${this.path}/messages?${query}`);\n return data.messages.map((message) => new Message(this.client, message));\n }\n /** Uma mensagem pelo id. */\n async fetchMessage(id) {\n const data = await this.client.rest.get(`${this.path}/messages/${enc(id)}`);\n return new Message(this.client, data.message);\n }\n toString() {\n return `<#${this.id}>`;\n }\n}\n\nexport class Group {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this._patch(data);\n }\n /** @param {Record<string, any>} data */\n _patch(data) {\n this.id = data.id;\n this.name = data.name;\n this.iconURL = data.iconUrl ?? null;\n this.ownerId = data.ownerId ?? null;\n this.memberCount = data.memberCount ?? 0;\n /** @type {{ id: string, name: string, color: string | null, position: number, mentionable: boolean }[]} */\n this.roles = data.roles ?? [];\n /** O que o bot pode fazer aqui (kickMembers, banMembers, manageRoles, manageMessages\u2026). */\n this.permissions = data.permissions ?? {};\n /** @type {Map<string, Channel>} */\n this.channels = new Map((data.channels ?? []).map((channel) => [channel.id, new Channel(this.client, this, channel)]));\n }\n /** A sala pelo id ou pelo nome. @param {string} idOrName */\n channel(idOrName) {\n return this.channels.get(idOrName) ?? [...this.channels.values()].find((channel) => channel.name === idOrName) ?? null;\n }\n /** Os membros, com cargos e quem est\u00E1 online. */\n async fetchMembers() {\n const data = await this.client.rest.get(`/bot/groups/${enc(this.id)}/members`);\n return data.members.map((member) => ({ ...member, user: this.client._cacheUser(member) }));\n }\n get path() {\n return `/bot/groups/${enc(this.id)}`;\n }\n /** Se o bot tem a permiss\u00E3o (administrator vale por todas). @param {string} key */\n can(key) {\n return this.permissions.administrator === true || this.permissions[key] === true;\n }\n /** Expulsa algu\u00E9m (precisa de kickMembers e de um cargo acima do da pessoa). @param {string} userId */\n async kick(userId) {\n await this.client.rest.post(`${this.path}/members/${enc(userId)}/kick`, {});\n }\n /** Bane algu\u00E9m, mesmo que n\u00E3o esteja no grupo (banMembers). @param {string} userId @param {string} [reason] */\n async ban(userId, reason) {\n await this.client.rest.put(`${this.path}/bans/${enc(userId)}`, reason ? { reason } : {});\n }\n /** Tira o banimento (banMembers). @param {string} userId */\n async unban(userId) {\n await this.client.rest.delete(`${this.path}/bans/${enc(userId)}`);\n }\n /** Quem est\u00E1 banido (banMembers). */\n async fetchBans() {\n const data = await this.client.rest.get(`${this.path}/bans`);\n return data.bans;\n }\n /** D\u00E1 um cargo (manageRoles; s\u00F3 cargos abaixo do mais alto do bot). @param {string} userId @param {string} roleId */\n async addRole(userId, roleId) {\n const data = await this.client.rest.put(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** Tira um cargo (manageRoles). @param {string} userId @param {string} roleId */\n async removeRole(userId, roleId) {\n const data = await this.client.rest.delete(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** O bot sai do grupo. */\n async leave() {\n await this.client.rest.post(`${this.path}/leave`, {});\n }\n /** `<@&id>` n\u00E3o existe aqui: para mencionar um cargo, use { roleMentions: [id] } no envio. */\n role(idOrName) {\n return this.roles.find((role) => role.id === idOrName || role.name === idOrName) ?? null;\n }\n}\n\nexport class Message {\n /**\n * @param {import(\"./client.js\").Client} client\n * @param {Record<string, any>} data\n * @param {User | Record<string, any>} [author]\n */\n constructor(client, data, author) {\n this.client = client;\n this.id = data.id;\n this.groupId = data.groupId;\n this.channelId = data.channelId;\n /** O texto como est\u00E1 gravado \u2014 men\u00E7\u00F5es como `<@id>`. */\n this.content = data.text ?? \"\";\n this.embeds = data.embeds ?? [];\n this.attachments = data.attachments ?? [];\n this.images = data.images ?? [];\n this.reactions = data.reactions ?? [];\n this.replyTo = data.replyTo ?? null;\n this.createdAt = new Date(data.ts ?? Date.now());\n this.editedAt = data.editedAt ? new Date(data.editedAt) : null;\n this.pinned = Boolean(data.pinnedAt);\n this.webhook = Boolean(data.webhook);\n const mentions = data.mentions ?? [];\n this.mentions = {\n /** ids das pessoas mencionadas */\n users: mentions.filter((entry) => !entry.startsWith(\"@\")),\n /** ids dos cargos mencionados */\n roles: mentions.filter((entry) => entry.startsWith(\"@role:\")).map((entry) => entry.slice(6)),\n everyone: mentions.includes(\"@everyone\"),\n raw: mentions,\n };\n this.author =\n author instanceof User\n ? author\n : author\n ? client._cacheUser(author)\n : client.users.get(data.from) ?? new User(client, { id: data.from, name: data.fromName });\n }\n get group() {\n return this.client.groups.get(this.groupId) ?? null;\n }\n get channel() {\n return this.group?.channels.get(this.channelId) ?? null;\n }\n /** O texto com `<@id>` trocado por `@nome` (quando o nome \u00E9 conhecido). */\n get cleanContent() {\n return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g, (whole, id) => {\n const user = this.client.users.get(id);\n return user ? `@${user.displayName}` : whole;\n });\n }\n /** Se a mensagem menciona o bot (pelo id, cargo n\u00E3o conta). */\n get mentionsMe() {\n return this.mentions.users.includes(this.client.user?.id) || this.mentions.everyone;\n }\n get path() {\n return `/bot/groups/${enc(this.groupId)}/channels/${enc(this.channelId)}/messages`;\n }\n /** Responde citando esta mensagem. @param {string | Record<string, any>} content */\n async reply(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.post(this.path, { ...payload, replyTo: this.id });\n return new Message(this.client, data.message, this.client.user);\n }\n /** Edita (s\u00F3 as mensagens do pr\u00F3prio bot). @param {string | Record<string, any>} content */\n async edit(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.patch(`${this.path}/${enc(this.id)}`, { text: payload.text, ...(payload.embeds ? { embeds: payload.embeds } : {}) });\n return new Message(this.client, data.message, this.author);\n }\n /** Fixa na sala (manageMessages). */\n async pin() {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Desafixa (manageMessages). */\n async unpin() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Apaga: as do pr\u00F3prio bot sempre; as dos outros, com manageMessages. */\n async delete() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}`);\n }\n /** Reage com um emoji. @param {string} emoji */\n async react(emoji) {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n /** Tira a rea\u00E7\u00E3o do bot. @param {string} emoji */\n async unreact(emoji) {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n}\n", "// Construtor de embeds no mesmo formato do discord.js (e do webhook do Five\n// Live): t\u00EDtulo, descri\u00E7\u00E3o, cor, autor, campos, imagem, miniatura, rodap\u00E9.\n\n/** @param {string | number} color */\nfunction toColor(color) {\n if (typeof color === \"number\") return color;\n const hex = String(color).replace(/^#/, \"\");\n return /^[0-9a-f]{6}$/i.test(hex) ? parseInt(hex, 16) : undefined;\n}\n\nexport class EmbedBuilder {\n /** @param {Record<string, unknown>} [data] */\n constructor(data = {}) {\n /** @type {Record<string, any>} */\n this.data = { ...data };\n }\n setTitle(title) {\n this.data.title = title;\n return this;\n }\n setDescription(description) {\n this.data.description = description;\n return this;\n }\n setURL(url) {\n this.data.url = url;\n return this;\n }\n /** @param {string | number} color \"#3b6cf6\" ou 0x3b6cf6 */\n setColor(color) {\n this.data.color = toColor(color);\n return this;\n }\n /** @param {{ name: string, url?: string, iconURL?: string }} author */\n setAuthor(author) {\n this.data.author = { name: author.name, url: author.url, icon_url: author.iconURL };\n return this;\n }\n /** @param {{ text: string, iconURL?: string }} footer */\n setFooter(footer) {\n this.data.footer = { text: footer.text, icon_url: footer.iconURL };\n return this;\n }\n setImage(url) {\n this.data.image = { url };\n return this;\n }\n setThumbnail(url) {\n this.data.thumbnail = { url };\n return this;\n }\n /** @param {Date | number | string} [timestamp] */\n setTimestamp(timestamp = new Date()) {\n this.data.timestamp = new Date(timestamp).toISOString();\n return this;\n }\n /** @param {...{ name: string, value: string, inline?: boolean }} fields */\n addFields(...fields) {\n this.data.fields = [...(this.data.fields ?? []), ...fields.flat()];\n return this;\n }\n toJSON() {\n return this.data;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAeA,OAAS,gBAAAA,MAAoB,cCXtB,IAAMC,EAAN,cAA+B,KAAM,CAO1C,YAAYC,EAASC,EAAQC,EAAQC,EAAM,CACzC,MAAMH,CAAO,EACb,KAAK,KAAO,mBACZ,KAAK,OAASC,EACd,KAAK,OAASC,EACd,KAAK,KAAOC,CACd,CACF,EAEMC,EAASC,GAAO,IAAI,QAASC,GAAY,WAAWA,EAASD,CAAE,CAAC,EAEzDE,EAAN,KAAW,CAEhB,YAAYC,EAAS,CACnB,KAAK,MAAQA,EAAQ,MACrB,KAAK,OAASA,EAAQ,OAAO,QAAQ,MAAO,EAAE,EAC9C,KAAK,QAAUA,EAAQ,SAAW,CACpC,CAOA,MAAM,QAAQN,EAAQC,EAAMM,EAAM,CAChC,QAASC,EAAU,GAAKA,IAAW,CACjC,IAAMC,EAAM,MAAM,MAAM,KAAK,OAASR,EAAM,CAC1C,OAAAD,EACA,QAAS,CACP,cAAe,OAAO,KAAK,KAAK,GAChC,GAAIO,IAAS,OAAY,CAAE,eAAgB,kBAAmB,EAAI,CAAC,EACnE,aAAc,8DAChB,EACA,KAAMA,IAAS,OAAY,KAAK,UAAUA,CAAI,EAAI,MACpD,CAAC,EACKG,EAAO,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAC,EAAE,EAC9C,GAAIA,EAAI,SAAW,KAAOD,EAAU,KAAK,QAAS,CAChD,IAAMG,EAAU,OAAOD,EAAK,YAAcD,EAAI,QAAQ,IAAI,aAAa,GAAK,CAAC,EAC7E,MAAMP,EAAM,KAAK,IAAI,EAAGS,CAAO,EAAI,GAAI,EACvC,QACF,CACA,GAAI,CAACF,EAAI,GAAI,MAAM,IAAIZ,EAAiBa,EAAK,OAAS,QAAQD,EAAI,MAAM,GAAIA,EAAI,OAAQT,EAAQC,CAAI,EACpG,OAAOS,CACT,CACF,CAEA,IAAIT,EAAM,CACR,OAAO,KAAK,QAAQ,MAAOA,CAAI,CACjC,CACA,KAAKA,EAAMM,EAAM,CACf,OAAO,KAAK,QAAQ,OAAQN,EAAMM,GAAQ,CAAC,CAAC,CAC9C,CACA,MAAMN,EAAMM,EAAM,CAChB,OAAO,KAAK,QAAQ,QAASN,EAAMM,GAAQ,CAAC,CAAC,CAC/C,CACA,IAAIN,EAAMM,EAAM,CACd,OAAO,KAAK,QAAQ,MAAON,EAAMM,GAAQ,CAAC,CAAC,CAC7C,CACA,OAAON,EAAM,CACX,OAAO,KAAK,QAAQ,SAAUA,CAAI,CACpC,CACF,EAEaW,EAAM,mBCpEZ,IAAMC,EAAeC,GAAO,KAAKA,CAAE,IAE7BC,EAAkBD,GAAO,KAAKA,CAAE,IAMtC,SAASE,EAAeC,EAAO,CACpC,IAAMC,EAAU,OAAOD,GAAU,SAAW,CAAE,QAASA,CAAM,EAAIA,GAAS,CAAC,EACrEE,GAAUD,EAAQ,QAAU,CAAC,GAAG,IAAKE,GAAW,OAAOA,GAAO,QAAW,WAAaA,EAAM,OAAO,EAAIA,CAAM,EAC7GC,GAASH,EAAQ,cAAgB,CAAC,GAAG,IAAKJ,GAAO,SAASA,CAAE,EAAE,EACpE,MAAO,CACL,KAAMI,EAAQ,SAAW,GACzB,GAAIC,EAAO,OAAS,CAAE,OAAAA,CAAO,EAAI,CAAC,EAClC,GAAID,EAAQ,UAAU,QAAUG,EAAM,QAAUH,EAAQ,SACpD,CAAE,SAAU,CAAC,GAAIA,EAAQ,UAAY,CAAC,EAAI,GAAGG,EAAO,GAAIH,EAAQ,SAAW,CAAC,WAAW,EAAI,CAAC,CAAE,CAAE,EAChG,CAAC,EACL,GAAIA,EAAQ,MAAQ,CAAE,QAAS,OAAOA,EAAQ,OAAU,SAAWA,EAAQ,MAAQA,EAAQ,MAAM,EAAG,EAAI,CAAC,CAC3G,CACF,CAEO,IAAMI,EAAN,KAAW,CAEhB,YAAYC,EAAQC,EAAM,CACxB,KAAK,OAASD,EACd,KAAK,GAAKC,EAAK,GACf,KAAK,SAAWA,EAAK,UAAY,KACjC,KAAK,YAAcA,EAAK,aAAeA,EAAK,MAAQA,EAAK,UAAY,GACrE,KAAK,UAAYA,EAAK,WAAa,KACnC,KAAK,IAAMA,EAAK,MAAQ,GACxB,KAAK,MAAQA,EAAK,OAAS,CAAC,CAC9B,CAEA,UAAW,CACT,OAAOX,EAAY,KAAK,EAAE,CAC5B,CACF,EAEaY,EAAN,KAAc,CAEnB,YAAYF,EAAQG,EAAOF,EAAM,CAC/B,KAAK,OAASD,EACd,KAAK,MAAQG,EACb,KAAK,GAAKF,EAAK,GACf,KAAK,KAAOA,EAAK,KAEjB,KAAK,KAAOA,EAAK,KACjB,KAAK,WAAaA,EAAK,YAAc,KACrC,KAAK,MAAQA,EAAK,OAAS,EAC7B,CACA,IAAI,QAAS,CACX,OAAO,KAAK,OAAS,MACvB,CACA,IAAI,MAAO,CACT,MAAO,eAAeG,EAAI,KAAK,MAAM,EAAE,CAAC,aAAaA,EAAI,KAAK,EAAE,CAAC,EACnE,CAEA,MAAM,KAAKC,EAAS,CAClB,IAAMJ,EAAO,MAAM,KAAK,OAAO,KAAK,KAAK,GAAG,KAAK,IAAI,YAAaR,EAAeY,CAAO,CAAC,EACzF,OAAO,IAAIC,EAAQ,KAAK,OAAQL,EAAK,QAAS,KAAK,OAAO,IAAI,CAChE,CAEA,MAAM,YAAa,CACjB,MAAM,KAAK,OAAO,KAAK,KAAK,GAAG,KAAK,IAAI,UAAW,CAAE,OAAQ,EAAK,CAAC,CACrE,CAKA,MAAM,cAAcN,EAAU,CAAC,EAAG,CAChC,IAAMY,EAAQ,IAAI,gBAClB,OAAIZ,EAAQ,OAAOY,EAAM,IAAI,QAAS,OAAOZ,EAAQ,KAAK,CAAC,EACvDA,EAAQ,OAAOY,EAAM,IAAI,QAASZ,EAAQ,KAAK,GACtC,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,aAAaY,CAAK,EAAE,GAC5D,SAAS,IAAKC,GAAY,IAAIF,EAAQ,KAAK,OAAQE,CAAO,CAAC,CACzE,CAEA,MAAM,aAAajB,EAAI,CACrB,IAAMU,EAAO,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,aAAaG,EAAIb,CAAE,CAAC,EAAE,EAC1E,OAAO,IAAIe,EAAQ,KAAK,OAAQL,EAAK,OAAO,CAC9C,CACA,UAAW,CACT,MAAO,KAAK,KAAK,EAAE,GACrB,CACF,EAEaQ,EAAN,KAAY,CAEjB,YAAYT,EAAQC,EAAM,CACxB,KAAK,OAASD,EACd,KAAK,OAAOC,CAAI,CAClB,CAEA,OAAOA,EAAM,CACX,KAAK,GAAKA,EAAK,GACf,KAAK,KAAOA,EAAK,KACjB,KAAK,QAAUA,EAAK,SAAW,KAC/B,KAAK,QAAUA,EAAK,SAAW,KAC/B,KAAK,YAAcA,EAAK,aAAe,EAEvC,KAAK,MAAQA,EAAK,OAAS,CAAC,EAE5B,KAAK,YAAcA,EAAK,aAAe,CAAC,EAExC,KAAK,SAAW,IAAI,KAAKA,EAAK,UAAY,CAAC,GAAG,IAAKS,GAAY,CAACA,EAAQ,GAAI,IAAIR,EAAQ,KAAK,OAAQ,KAAMQ,CAAO,CAAC,CAAC,CAAC,CACvH,CAEA,QAAQC,EAAU,CAChB,OAAO,KAAK,SAAS,IAAIA,CAAQ,GAAK,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,EAAE,KAAMD,GAAYA,EAAQ,OAASC,CAAQ,GAAK,IACpH,CAEA,MAAM,cAAe,CAEnB,OADa,MAAM,KAAK,OAAO,KAAK,IAAI,eAAeP,EAAI,KAAK,EAAE,CAAC,UAAU,GACjE,QAAQ,IAAKQ,IAAY,CAAE,GAAGA,EAAQ,KAAM,KAAK,OAAO,WAAWA,CAAM,CAAE,EAAE,CAC3F,CACA,IAAI,MAAO,CACT,MAAO,eAAeR,EAAI,KAAK,EAAE,CAAC,EACpC,CAEA,IAAIS,EAAK,CACP,OAAO,KAAK,YAAY,gBAAkB,IAAQ,KAAK,YAAYA,CAAG,IAAM,EAC9E,CAEA,MAAM,KAAKC,EAAQ,CACjB,MAAM,KAAK,OAAO,KAAK,KAAK,GAAG,KAAK,IAAI,YAAYV,EAAIU,CAAM,CAAC,QAAS,CAAC,CAAC,CAC5E,CAEA,MAAM,IAAIA,EAAQC,EAAQ,CACxB,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAASX,EAAIU,CAAM,CAAC,GAAIC,EAAS,CAAE,OAAAA,CAAO,EAAI,CAAC,CAAC,CACzF,CAEA,MAAM,MAAMD,EAAQ,CAClB,MAAM,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,SAASV,EAAIU,CAAM,CAAC,EAAE,CAClE,CAEA,MAAM,WAAY,CAEhB,OADa,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAC/C,IACd,CAEA,MAAM,QAAQA,EAAQE,EAAQ,CAE5B,OADa,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,YAAYZ,EAAIU,CAAM,CAAC,UAAUV,EAAIY,CAAM,CAAC,EAAE,GACtF,OACd,CAEA,MAAM,WAAWF,EAAQE,EAAQ,CAE/B,OADa,MAAM,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,YAAYZ,EAAIU,CAAM,CAAC,UAAUV,EAAIY,CAAM,CAAC,EAAE,GACzF,OACd,CAEA,MAAM,OAAQ,CACZ,MAAM,KAAK,OAAO,KAAK,KAAK,GAAG,KAAK,IAAI,SAAU,CAAC,CAAC,CACtD,CAEA,KAAKL,EAAU,CACb,OAAO,KAAK,MAAM,KAAMM,GAASA,EAAK,KAAON,GAAYM,EAAK,OAASN,CAAQ,GAAK,IACtF,CACF,EAEaL,EAAN,MAAMY,CAAQ,CAMnB,YAAYlB,EAAQC,EAAMkB,EAAQ,CAChC,KAAK,OAASnB,EACd,KAAK,GAAKC,EAAK,GACf,KAAK,QAAUA,EAAK,QACpB,KAAK,UAAYA,EAAK,UAEtB,KAAK,QAAUA,EAAK,MAAQ,GAC5B,KAAK,OAASA,EAAK,QAAU,CAAC,EAC9B,KAAK,YAAcA,EAAK,aAAe,CAAC,EACxC,KAAK,OAASA,EAAK,QAAU,CAAC,EAC9B,KAAK,UAAYA,EAAK,WAAa,CAAC,EACpC,KAAK,QAAUA,EAAK,SAAW,KAC/B,KAAK,UAAY,IAAI,KAAKA,EAAK,IAAM,KAAK,IAAI,CAAC,EAC/C,KAAK,SAAWA,EAAK,SAAW,IAAI,KAAKA,EAAK,QAAQ,EAAI,KAC1D,KAAK,OAAS,EAAQA,EAAK,SAC3B,KAAK,QAAU,EAAQA,EAAK,QAC5B,IAAMmB,EAAWnB,EAAK,UAAY,CAAC,EACnC,KAAK,SAAW,CAEd,MAAOmB,EAAS,OAAQC,GAAU,CAACA,EAAM,WAAW,GAAG,CAAC,EAExD,MAAOD,EAAS,OAAQC,GAAUA,EAAM,WAAW,QAAQ,CAAC,EAAE,IAAKA,GAAUA,EAAM,MAAM,CAAC,CAAC,EAC3F,SAAUD,EAAS,SAAS,WAAW,EACvC,IAAKA,CACP,EACA,KAAK,OACHD,aAAkBpB,EACdoB,EACAA,EACEnB,EAAO,WAAWmB,CAAM,EACxBnB,EAAO,MAAM,IAAIC,EAAK,IAAI,GAAK,IAAIF,EAAKC,EAAQ,CAAE,GAAIC,EAAK,KAAM,KAAMA,EAAK,QAAS,CAAC,CAChG,CACA,IAAI,OAAQ,CACV,OAAO,KAAK,OAAO,OAAO,IAAI,KAAK,OAAO,GAAK,IACjD,CACA,IAAI,SAAU,CACZ,OAAO,KAAK,OAAO,SAAS,IAAI,KAAK,SAAS,GAAK,IACrD,CAEA,IAAI,cAAe,CACjB,OAAO,KAAK,QAAQ,QAAQ,wBAAyB,CAACqB,EAAO/B,IAAO,CAClE,IAAMgC,EAAO,KAAK,OAAO,MAAM,IAAIhC,CAAE,EACrC,OAAOgC,EAAO,IAAIA,EAAK,WAAW,GAAKD,CACzC,CAAC,CACH,CAEA,IAAI,YAAa,CACf,OAAO,KAAK,SAAS,MAAM,SAAS,KAAK,OAAO,MAAM,EAAE,GAAK,KAAK,SAAS,QAC7E,CACA,IAAI,MAAO,CACT,MAAO,eAAelB,EAAI,KAAK,OAAO,CAAC,aAAaA,EAAI,KAAK,SAAS,CAAC,WACzE,CAEA,MAAM,MAAMC,EAAS,CACnB,IAAMmB,EAAU/B,EAAeY,CAAO,EAChCJ,EAAO,MAAM,KAAK,OAAO,KAAK,KAAK,KAAK,KAAM,CAAE,GAAGuB,EAAS,QAAS,KAAK,EAAG,CAAC,EACpF,OAAO,IAAIN,EAAQ,KAAK,OAAQjB,EAAK,QAAS,KAAK,OAAO,IAAI,CAChE,CAEA,MAAM,KAAKI,EAAS,CAClB,IAAMmB,EAAU/B,EAAeY,CAAO,EAChCJ,EAAO,MAAM,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI,IAAIG,EAAI,KAAK,EAAE,CAAC,GAAI,CAAE,KAAMoB,EAAQ,KAAM,GAAIA,EAAQ,OAAS,CAAE,OAAQA,EAAQ,MAAO,EAAI,CAAC,CAAG,CAAC,EACvJ,OAAO,IAAIN,EAAQ,KAAK,OAAQjB,EAAK,QAAS,KAAK,MAAM,CAC3D,CAEA,MAAM,KAAM,CACV,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIG,EAAI,KAAK,EAAE,CAAC,MAAM,CAC/D,CAEA,MAAM,OAAQ,CACZ,MAAM,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,IAAIA,EAAI,KAAK,EAAE,CAAC,MAAM,CAClE,CAEA,MAAM,QAAS,CACb,MAAM,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,IAAIA,EAAI,KAAK,EAAE,CAAC,EAAE,CAC9D,CAEA,MAAM,MAAMqB,EAAO,CACjB,MAAM,KAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIrB,EAAI,KAAK,EAAE,CAAC,cAAcA,EAAIqB,CAAK,CAAC,EAAE,CACnF,CAEA,MAAM,QAAQA,EAAO,CACnB,MAAM,KAAK,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI,IAAIrB,EAAI,KAAK,EAAE,CAAC,cAAcA,EAAIqB,CAAK,CAAC,EAAE,CACtF,CACF,EF7OA,IAAMC,EAAc,8BACdC,EAAe,IACfC,EAAiB,IAEvB,eAAeC,GAAc,CAC3B,GAAI,OAAO,WAAW,WAAc,WAAY,OAAO,WAAW,UAClE,GAAI,CACF,IAAMC,EAAM,KAAM,QAAO,IAAI,EAC7B,OAAOA,EAAI,SAAWA,EAAI,SAC5B,MAAQ,CACN,MAAM,IAAI,MAAM,qGAA+F,CACjH,CACF,CAEO,IAAMC,EAAN,cAAqBC,CAAa,CAUvC,YAAYC,EAAS,CAEnB,GADA,MAAM,EACF,CAACA,GAAS,OAAS,CAAC,OAAOA,EAAQ,KAAK,EAAE,WAAW,IAAI,EAC3D,MAAM,IAAI,MAAM,4FAAyF,EAE3G,KAAK,MAAQA,EAAQ,MACrB,KAAK,QAAUA,EAAQ,QAAUP,GAAa,QAAQ,MAAO,EAAE,EAC/D,KAAK,WAAaO,EAAQ,YAAc,GAAG,KAAK,OAAO,QAAQ,QAAS,IAAI,CAAC,MAC7E,KAAK,OAASA,EAAQ,QAAU,IAChC,KAAK,WAAaA,EAAQ,YAAc,GACxC,KAAK,KAAO,IAAIC,EAAK,CAAE,MAAO,KAAK,MAAO,OAAQ,KAAK,MAAO,CAAC,EAE/D,KAAK,KAAO,KAEZ,KAAK,OAAS,IAAI,IAElB,KAAK,MAAQ,IAAI,IAEjB,KAAK,SAAW,IAAI,IACpB,KAAK,IAAM,KACX,KAAK,OAAS,GACd,KAAK,SAAW,GAChB,KAAK,SAAW,EAChB,KAAK,WAAa,IACpB,CAQA,QAAQC,EAAS,CACf,KAAK,SAAS,IAAIA,EAAQ,KAAK,YAAY,EAAGA,CAAO,EACrD,QAAWC,KAASD,EAAQ,SAAW,CAAC,EAAG,KAAK,SAAS,IAAIC,EAAM,YAAY,EAAGD,CAAO,EACzF,OAAO,IACT,CAGA,MAAM,YAAYE,EAAS,CACzB,GAAI,CAAC,KAAK,SAAS,MAAQ,CAACA,EAAQ,QAAQ,WAAW,KAAK,MAAM,EAAG,OACrE,GAAM,CAACC,EAAM,GAAGC,CAAI,EAAIF,EAAQ,QAAQ,MAAM,KAAK,OAAO,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,EAC9EF,EAAU,KAAK,SAAS,KAAKG,GAAQ,IAAI,YAAY,CAAC,EAC5D,GAAI,CAACH,EAAS,OACd,IAAMK,EAAU,CAAE,QAAAH,EAAS,KAAAE,EAAM,OAAQ,KAAM,MAAQE,GAAYJ,EAAQ,MAAMI,CAAO,CAAE,EAC1F,GAAI,CACF,MAAMN,EAAQ,IAAIK,CAAO,CAC3B,OAASE,EAAK,CACR,KAAK,cAAc,cAAc,EAAG,KAAK,KAAK,eAAgBA,EAAKF,CAAO,EACzE,KAAK,KAAK,QAASE,CAAG,CAC7B,CACF,CAKA,MAAM,OAAQ,CACZ,IAAMC,EAAK,MAAM,KAAK,KAAK,IAAI,UAAU,EACzC,YAAK,KAAO,KAAK,WAAW,CAAE,GAAGA,EAAG,IAAK,IAAK,EAAK,CAAC,EACpD,MAAM,KAAK,YAAY,EACvB,KAAK,SAAW,GAChB,MAAM,KAAK,SAAS,EACb,KAAK,IACd,CAGA,SAAU,CACR,KAAK,SAAW,GAChB,cAAc,KAAK,UAAU,EAC7B,GAAI,CACF,KAAK,KAAK,MAAM,CAClB,MAAQ,CAER,CACF,CAEA,MAAM,aAAc,CAClB,IAAMC,EAAO,MAAM,KAAK,KAAK,IAAI,aAAa,EACxCC,EAAO,IAAI,IACjB,QAAWC,KAAOF,EAAK,OAAQ,CAC7BC,EAAK,IAAIC,EAAI,EAAE,EACf,IAAMC,EAAO,KAAK,OAAO,IAAID,EAAI,EAAE,EAC/BC,EAAMA,EAAK,OAAOD,CAAG,EACpB,KAAK,OAAO,IAAIA,EAAI,GAAI,IAAIE,EAAM,KAAMF,CAAG,CAAC,CACnD,CACA,QAAWG,IAAM,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,EAAQJ,EAAK,IAAII,CAAE,GAAG,KAAK,OAAO,OAAOA,CAAE,CACpF,CAGA,MAAM,WAAWA,EAAI,CACnB,IAAML,EAAO,MAAM,KAAK,KAAK,IAAI,eAAe,mBAAmBK,CAAE,CAAC,EAAE,EAClEF,EAAO,KAAK,OAAO,IAAIE,CAAE,EAC/B,OAAIF,EAAMA,EAAK,OAAOH,EAAK,KAAK,EAC3B,KAAK,OAAO,IAAIK,EAAI,IAAID,EAAM,KAAMJ,EAAK,KAAK,CAAC,EAC7C,KAAK,OAAO,IAAIK,CAAE,CAC3B,CAGA,MAAM,UAAUA,EAAI,CAClB,IAAML,EAAO,MAAM,KAAK,KAAK,IAAI,cAAc,mBAAmBK,CAAE,CAAC,EAAE,EACvE,OAAO,KAAK,WAAWL,EAAK,IAAI,CAClC,CAGA,WAAWA,EAAM,CACf,IAAMM,EAAO,IAAIC,EAAK,KAAMP,CAAI,EAChC,YAAK,MAAM,IAAIM,EAAK,GAAIA,CAAI,EACrBA,CACT,CAEA,MAAM,UAAW,CACf,IAAME,EAAS,MAAMvB,EAAY,EACjC,OAAO,IAAI,QAAQ,CAACwB,EAASC,IAAW,CACtC,IAAMC,EAAK,IAAIH,EAAO,KAAK,UAAU,EACrC,KAAK,IAAMG,EACX,IAAIC,EAAU,GACRC,EAAQC,GAAY,CACpBH,EAAG,aAAe,GAAGA,EAAG,KAAK,KAAK,UAAUG,CAAO,CAAC,CAC1D,EACAH,EAAG,OAAS,IAAM,CAChBE,EAAK,CAAE,KAAM,WAAY,KAAM,KAAK,KAAK,aAAe,KAAK,KAAK,SAAU,MAAO,KAAK,KAAM,CAAC,EAC/F,cAAc,KAAK,UAAU,EAE7B,KAAK,WAAa,YAAY,IAAMA,EAAK,CAAE,KAAM,YAAa,GAAI,KAAK,IAAI,CAAE,CAAC,EAAG9B,CAAY,CAC/F,EACA4B,EAAG,UAAaI,GAAU,CACxB,IAAIC,EACJ,GAAI,CACFA,EAAM,KAAK,MAAM,OAAOD,EAAM,MAAS,SAAWA,EAAM,KAAOA,EAAM,KAAK,SAAS,CAAC,CACtF,MAAQ,CACN,MACF,CACA,GAAIC,EAAI,OAAS,aAAc,CAC7B,IAAMC,EAAQ,CAAC,KAAK,OACpB,KAAK,OAAS,GACd,KAAK,SAAW,EACXL,IACHA,EAAU,GACVH,EAAQ,GAENQ,EAAO,KAAK,KAAK,QAAS,KAAK,IAAI,EAClC,KAAK,KAAK,aAAa,EAC5B,MACF,CACA,GAAID,EAAI,OAAS,iBAAkB,CACjC,KAAK,SAAW,GAChB,IAAMlB,EAAM,IAAI,MAAMkB,EAAI,SAAW,qCAAqC,EACrEJ,EAGE,KAAK,KAAK,QAASd,CAAG,GAF3Bc,EAAU,GACVF,EAAOZ,CAAG,GAEZ,MACF,CACA,KAAK,UAAUkB,CAAG,EAAE,MAAOlB,GAAQ,KAAK,KAAK,QAASA,CAAG,CAAC,CAC5D,EACAa,EAAG,QAAWI,GAAU,CAClB,CAACH,GAAW,KAAK,WAAa,GAAK,CAAC,KAAK,SAC3CA,EAAU,GACVF,EAAO,IAAI,MAAM,sCAAgC,KAAK,UAAU,KAAKK,GAAO,SAAW,cAAc,EAAE,CAAC,EAE5G,EACAJ,EAAG,QAAU,IAAM,CACjB,cAAc,KAAK,UAAU,EAC7B,KAAK,KAAK,YAAY,EAClB,OAAK,UAAY,CAAC,KAAK,SAC3B,KAAK,WAAW,CAClB,CACF,CAAC,CACH,CAEA,YAAa,CACX,KAAK,UAAY,EACjB,IAAMO,EAAQ,KAAK,IAAIlC,EAAgB,IAAO,GAAK,KAAK,IAAI,KAAK,SAAW,EAAG,CAAC,CAAC,EAAI,KAAK,OAAO,EAAI,IACrG,KAAK,KAAK,eAAgB,KAAK,QAAQ,EACvC,WAAW,SAAY,CACrB,GAAI,MAAK,SACT,GAAI,CAEF,MAAM,KAAK,YAAY,EACvB,MAAM,KAAK,SAAS,CACtB,MAAQ,CACN,KAAK,WAAW,CAClB,CACF,EAAGkC,CAAK,CACV,CAGA,MAAM,UAAUF,EAAK,CACnB,OAAQA,EAAI,KAAM,CAChB,IAAK,gBAAiB,CACpB,GAAI,CAACA,EAAI,QAAS,OAClB,IAAMvB,EAAU,IAAI0B,EAAQ,KAAMH,EAAI,QAASA,EAAI,OAAS,CAAE,GAAGA,EAAI,MAAO,EAAI,MAAS,EAEzF,GADIvB,EAAQ,OAAO,KAAO,KAAK,MAAM,IACjC,KAAK,YAAcA,EAAQ,OAAO,IAAK,OAC3C,KAAK,KAAK,gBAAiBA,CAAO,EAClC,MAAM,KAAK,YAAYA,CAAO,EAC9B,MACF,CACA,IAAK,wBACCuB,EAAI,SAAS,KAAK,KAAK,gBAAiB,IAAIG,EAAQ,KAAMH,EAAI,OAAO,CAAC,EAC1E,OACF,IAAK,wBACH,KAAK,KAAK,gBAAiB,CAAE,GAAIA,EAAI,UAAW,QAASA,EAAI,QAAS,UAAWA,EAAI,SAAU,CAAC,EAChG,OACF,IAAK,0BACH,KAAK,KAAK,iBAAkB,CAAE,UAAWA,EAAI,UAAW,QAASA,EAAI,QAAS,UAAWA,EAAI,UAAW,UAAWA,EAAI,WAAa,CAAC,CAAE,CAAC,EACxI,OACF,IAAK,eACCA,EAAI,SAAW,KAAK,MAAM,IAAMA,EAAI,SAAW,IACjD,KAAK,KAAK,cAAe,CAAE,OAAQA,EAAI,OAAQ,KAAMA,EAAI,KAAM,QAASA,EAAI,QAAS,UAAWA,EAAI,SAAU,CAAC,EAEjH,OACF,IAAK,eAAgB,CACnB,IAAMI,EAAQ,MAAM,KAAK,WAAWJ,EAAI,OAAO,EAC/C,KAAK,KAAK,YAAaI,CAAK,EAC5B,MACF,CACA,IAAK,gBAAiB,CACpB,GAAI,CAAC,KAAK,OAAO,IAAIJ,EAAI,OAAO,EAAG,OACnC,IAAMI,EAAQ,MAAM,KAAK,WAAWJ,EAAI,OAAO,EAAE,MAAM,IAAM,IAAI,EAC7DI,GAAO,KAAK,KAAK,cAAeA,CAAK,EACzC,MACF,CACA,IAAK,mBAAoB,CACvB,GAAI,CAACJ,EAAI,OAAQ,OACjB,IAAMV,EAAO,KAAK,WAAWU,EAAI,MAAM,EACjCI,EAAQ,KAAK,OAAO,IAAIJ,EAAI,OAAO,GAAM,MAAM,KAAK,WAAWA,EAAI,OAAO,EAAE,MAAM,IAAM,IAAI,EAC9FI,IAAOA,EAAM,aAAe,GAChC,KAAK,KAAK,YAAa,CAAE,KAAAd,EAAM,MAAAc,EAAO,QAASJ,EAAI,QAAS,IAAKA,EAAI,KAAO,IAAK,CAAC,EAClF,MACF,CACA,IAAK,sBAAuB,CAC1B,IAAMI,EAAQ,KAAK,OAAO,IAAIJ,EAAI,OAAO,GAAK,KAC1CI,IAAOA,EAAM,YAAc,KAAK,IAAI,EAAGA,EAAM,YAAc,CAAC,GAChE,KAAK,KAAK,eAAgB,CAAE,OAAQJ,EAAI,OAAQ,KAAM,KAAK,MAAM,IAAIA,EAAI,MAAM,GAAK,KAAM,MAAAI,EAAO,QAASJ,EAAI,QAAS,OAAQA,EAAI,QAAU,KAAM,GAAIA,EAAI,IAAM,IAAK,CAAC,EACvK,MACF,CACA,IAAK,gBACH,KAAK,OAAO,OAAOA,EAAI,OAAO,EAC9B,KAAK,KAAK,aAAc,CAAE,GAAIA,EAAI,QAAS,OAAQA,EAAI,QAAU,IAAK,CAAC,EACvE,OACF,QACE,KAAK,KAAK,MAAOA,CAAG,CACxB,CACF,CACF,EG5RA,SAASK,EAAQC,EAAO,CACtB,GAAI,OAAOA,GAAU,SAAU,OAAOA,EACtC,IAAMC,EAAM,OAAOD,CAAK,EAAE,QAAQ,KAAM,EAAE,EAC1C,MAAO,iBAAiB,KAAKC,CAAG,EAAI,SAASA,EAAK,EAAE,EAAI,MAC1D,CAEO,IAAMC,EAAN,KAAmB,CAExB,YAAYC,EAAO,CAAC,EAAG,CAErB,KAAK,KAAO,CAAE,GAAGA,CAAK,CACxB,CACA,SAASC,EAAO,CACd,YAAK,KAAK,MAAQA,EACX,IACT,CACA,eAAeC,EAAa,CAC1B,YAAK,KAAK,YAAcA,EACjB,IACT,CACA,OAAOC,EAAK,CACV,YAAK,KAAK,IAAMA,EACT,IACT,CAEA,SAASN,EAAO,CACd,YAAK,KAAK,MAAQD,EAAQC,CAAK,EACxB,IACT,CAEA,UAAUO,EAAQ,CAChB,YAAK,KAAK,OAAS,CAAE,KAAMA,EAAO,KAAM,IAAKA,EAAO,IAAK,SAAUA,EAAO,OAAQ,EAC3E,IACT,CAEA,UAAUC,EAAQ,CAChB,YAAK,KAAK,OAAS,CAAE,KAAMA,EAAO,KAAM,SAAUA,EAAO,OAAQ,EAC1D,IACT,CACA,SAASF,EAAK,CACZ,YAAK,KAAK,MAAQ,CAAE,IAAAA,CAAI,EACjB,IACT,CACA,aAAaA,EAAK,CAChB,YAAK,KAAK,UAAY,CAAE,IAAAA,CAAI,EACrB,IACT,CAEA,aAAaG,EAAY,IAAI,KAAQ,CACnC,YAAK,KAAK,UAAY,IAAI,KAAKA,CAAS,EAAE,YAAY,EAC/C,IACT,CAEA,aAAaC,EAAQ,CACnB,YAAK,KAAK,OAAS,CAAC,GAAI,KAAK,KAAK,QAAU,CAAC,EAAI,GAAGA,EAAO,KAAK,CAAC,EAC1D,IACT,CACA,QAAS,CACP,OAAO,KAAK,IACd,CACF",
|
|
6
|
-
"names": ["EventEmitter", "FiveLiveAPIError", "message", "status", "method", "path", "sleep", "ms", "resolve", "REST", "options", "body", "attempt", "res", "data", "seconds", "enc", "userMention", "id", "channelMention", "messagePayload", "input", "options", "embeds", "embed", "roles", "User", "client", "data", "Channel", "group", "enc", "content", "Message", "query", "message", "Group", "channel", "idOrName", "member", "key", "userId", "reason", "roleId", "role", "_Message", "author", "mentions", "entry", "whole", "user", "payload", "emoji", "DEFAULT_API", "KEEPALIVE_MS", "MAX_BACKOFF_MS", "socketClass", "mod", "Client", "EventEmitter", "options", "REST", "command", "alias", "
|
|
4
|
+
"sourcesContent": ["// O Client: conecta no WebSocket do Five Live com o token do bot, mant\u00E9m a\n// conex\u00E3o viva (e reconecta sozinho), transforma os avisos da API em eventos\n// e guarda grupos e usu\u00E1rios conhecidos.\n//\n// Eventos:\n// ready(user) conectou e carregou os grupos\n// messageCreate(message) mensagem nova num grupo do bot\n// messageUpdate(message) mensagem editada\n// messageDelete({ id, groupId, channelId })\n// reactionUpdate({ messageId, groupId, channelId, reactions })\n// typingStart({ userId, name, groupId, channelId })\n// groupJoin(group) / groupLeave({ id, reason }) / groupUpdate(group)\n// reconnecting(attempt) / reconnected() / disconnect() / error(err)\n// commandError(err, context)\n\nimport { EventEmitter } from \"node:events\";\nimport { REST } from \"./rest.js\";\nimport { Group, Message, User } from \"./structures.js\";\n\nconst DEFAULT_API = \"https://api.fivenetwork.dev\";\nconst KEEPALIVE_MS = 30_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nasync function socketClass() {\n if (typeof globalThis.WebSocket === \"function\") return globalThis.WebSocket;\n try {\n const mod = await import(\"ws\");\n return mod.default ?? mod.WebSocket;\n } catch {\n throw new Error(\"Este Node n\u00E3o tem WebSocket nativo (\u00E9 do Node 22+). Rode `npm install ws` ou atualize o Node.\");\n }\n}\n\nexport class Client extends EventEmitter {\n /**\n * @param {{\n * token: string,\n * apiUrl?: string,\n * gatewayUrl?: string,\n * prefix?: string,\n * ignoreBots?: boolean,\n * }} options\n */\n constructor(options) {\n super();\n if (!options?.token || !String(options.token).startsWith(\"b_\")) {\n throw new Error(\"Passe o token do bot (come\u00E7a com b_). Pegue em https://live.fivenetwork.dev/developers.\");\n }\n this.token = options.token;\n this.apiUrl = (options.apiUrl ?? DEFAULT_API).replace(/\\/$/, \"\");\n this.gatewayUrl = options.gatewayUrl ?? `${this.apiUrl.replace(/^http/, \"ws\")}/ws`;\n this.prefix = options.prefix ?? \"!\";\n this.ignoreBots = options.ignoreBots ?? true;\n this.rest = new REST({ token: this.token, apiUrl: this.apiUrl });\n /** @type {User | null} */\n this.user = null;\n /** @type {Map<string, Group>} */\n this.groups = new Map();\n /** @type {Map<string, User>} */\n this.users = new Map();\n /** @type {Map<string, { name: string, description?: string, aliases?: string[], run: Function }>} */\n this.commands = new Map();\n this._ws = null;\n this._ready = false;\n this._closing = false;\n this._attempt = 0;\n this._keepalive = null;\n }\n\n // \u2500\u2500\u2500 Comandos com prefixo \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Registra um comando: `!nome arg1 arg2`.\n *\n * Com `description`, ele tamb\u00E9m vira um comando de barra (`/`): quem\n * escrever \"/\" numa sala em que o bot est\u00E1 v\u00EA o comando na lista, com a\n * descri\u00E7\u00E3o e os `options` como o jeito de escrever os argumentos \u2014 do\n * jeito do Discord. `login()` manda esse manifesto para a API sozinho; para\n * mandar de novo depois de registrar mais comandos, chame `syncCommands()`.\n * @param {{\n * name: string,\n * description?: string,\n * aliases?: string[],\n * options?: { name: string, description: string, required?: boolean, type?: \"string\" | \"number\" | \"boolean\" | \"user\" }[],\n * run: (ctx: { message: Message, args: string[], client: Client, reply: (content: any) => Promise<Message> }) => any,\n * }} command\n */\n command(command) {\n this.commands.set(command.name.toLowerCase(), command);\n for (const alias of command.aliases ?? []) this.commands.set(alias.toLowerCase(), command);\n return this;\n }\n\n /**\n * Manda para a API o manifesto de comandos de barra: todo comando com\n * `description` registrado at\u00E9 agora. Chamado sozinho ao fim de `login()`;\n * chame de novo se registrar comandos depois disso. Nunca lan\u00E7a \u2014 um erro\n * aqui n\u00E3o deveria derrubar o bot, s\u00F3 sai como o evento \"error\".\n */\n async syncCommands() {\n const seen = new Set();\n const commands = [];\n for (const command of this.commands.values()) {\n if (seen.has(command.name) || !command.description) continue;\n seen.add(command.name);\n commands.push({ name: command.name, description: command.description, options: command.options ?? [] });\n }\n try {\n await this.rest.put(\"/bot/commands\", { prefix: this.prefix, commands });\n } catch (err) {\n this.emit(\"error\", err);\n }\n }\n\n /** @param {Message} message */\n async _runCommand(message) {\n if (!this.commands.size || !message.content.startsWith(this.prefix)) return;\n const [name, ...args] = message.content.slice(this.prefix.length).trim().split(/\\s+/);\n const command = this.commands.get((name ?? \"\").toLowerCase());\n if (!command) return;\n const context = { message, args, client: this, reply: (content) => message.reply(content) };\n try {\n await command.run(context);\n } catch (err) {\n if (this.listenerCount(\"commandError\")) this.emit(\"commandError\", err, context);\n else this.emit(\"error\", err);\n }\n }\n\n // \u2500\u2500\u2500 Conex\u00E3o \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Conecta. Resolve quando o bot estiver pronto (evento \"ready\"). */\n async login() {\n const me = await this.rest.get(\"/bot/@me\");\n this.user = this._cacheUser({ ...me.bot, bot: true });\n await this._loadGroups();\n await this.syncCommands();\n this._closing = false;\n await this._connect();\n return this.user;\n }\n\n /** Desconecta de vez (sem reconectar). */\n destroy() {\n this._closing = true;\n clearInterval(this._keepalive);\n try {\n this._ws?.close();\n } catch {\n // j\u00E1 fechado\n }\n }\n\n async _loadGroups() {\n const data = await this.rest.get(\"/bot/groups\");\n const seen = new Set();\n for (const raw of data.groups) {\n seen.add(raw.id);\n const held = this.groups.get(raw.id);\n if (held) held._patch(raw);\n else this.groups.set(raw.id, new Group(this, raw));\n }\n for (const id of [...this.groups.keys()]) if (!seen.has(id)) this.groups.delete(id);\n }\n\n /** Um grupo, relido da API. @param {string} id */\n async fetchGroup(id) {\n const data = await this.rest.get(`/bot/groups/${encodeURIComponent(id)}`);\n const held = this.groups.get(id);\n if (held) held._patch(data.group);\n else this.groups.set(id, new Group(this, data.group));\n return this.groups.get(id);\n }\n\n /** Uma pessoa pelo id. @param {string} id */\n async fetchUser(id) {\n const data = await this.rest.get(`/bot/users/${encodeURIComponent(id)}`);\n return this._cacheUser(data.user);\n }\n\n /** @param {Record<string, any>} data */\n _cacheUser(data) {\n const user = new User(this, data);\n this.users.set(user.id, user);\n return user;\n }\n\n async _connect() {\n const Socket = await socketClass();\n return new Promise((resolve, reject) => {\n const ws = new Socket(this.gatewayUrl);\n this._ws = ws;\n let settled = false;\n const send = (payload) => {\n if (ws.readyState === 1) ws.send(JSON.stringify(payload));\n };\n ws.onopen = () => {\n send({ type: \"register\", name: this.user.displayName || this.user.username, token: this.token });\n clearInterval(this._keepalive);\n // O proxy da hospedagem derruba conex\u00E3o parada: uma mensagem leve de tempos em tempos.\n this._keepalive = setInterval(() => send({ type: \"time-sync\", t0: Date.now() }), KEEPALIVE_MS);\n };\n ws.onmessage = (event) => {\n let msg;\n try {\n msg = JSON.parse(typeof event.data === \"string\" ? event.data : event.data.toString());\n } catch {\n return;\n }\n if (msg.type === \"registered\") {\n const first = !this._ready;\n this._ready = true;\n this._attempt = 0;\n if (!settled) {\n settled = true;\n resolve();\n }\n if (first) this.emit(\"ready\", this.user);\n else this.emit(\"reconnected\");\n return;\n }\n if (msg.type === \"register-error\") {\n this._closing = true;\n const err = new Error(msg.message || \"O Five Live recusou o token do bot.\");\n if (!settled) {\n settled = true;\n reject(err);\n } else this.emit(\"error\", err);\n return;\n }\n this._dispatch(msg).catch((err) => this.emit(\"error\", err));\n };\n ws.onerror = (event) => {\n if (!settled && this._attempt === 0 && !this._ready) {\n settled = true;\n reject(new Error(`N\u00E3o foi poss\u00EDvel conectar em ${this.gatewayUrl}: ${event?.message ?? \"erro de rede\"}`));\n }\n };\n ws.onclose = () => {\n clearInterval(this._keepalive);\n this.emit(\"disconnect\");\n if (this._closing || !this._ready) return;\n this._reconnect();\n };\n });\n }\n\n _reconnect() {\n this._attempt += 1;\n const delay = Math.min(MAX_BACKOFF_MS, 1000 * 2 ** Math.min(this._attempt - 1, 5)) + Math.random() * 500;\n this.emit(\"reconnecting\", this._attempt);\n setTimeout(async () => {\n if (this._closing) return;\n try {\n // O que mudou enquanto estava fora (grupos que entrou/saiu).\n await this._loadGroups();\n await this._connect();\n } catch {\n this._reconnect();\n }\n }, delay);\n }\n\n /** @param {Record<string, any>} msg */\n async _dispatch(msg) {\n switch (msg.type) {\n case \"group-message\": {\n if (!msg.message) return;\n const message = new Message(this, msg.message, msg.author ? { ...msg.author } : undefined);\n if (message.author.id === this.user?.id) return;\n if (this.ignoreBots && message.author.bot) return;\n this.emit(\"messageCreate\", message);\n await this._runCommand(message);\n return;\n }\n case \"group-message-updated\":\n if (msg.message) this.emit(\"messageUpdate\", new Message(this, msg.message));\n return;\n case \"group-message-deleted\":\n this.emit(\"messageDelete\", { id: msg.messageId, groupId: msg.groupId, channelId: msg.channelId });\n return;\n case \"group-message-reactions\":\n this.emit(\"reactionUpdate\", { messageId: msg.messageId, groupId: msg.groupId, channelId: msg.channelId, reactions: msg.reactions ?? [] });\n return;\n case \"group-typing\":\n if (msg.userId !== this.user?.id && msg.typing !== false) {\n this.emit(\"typingStart\", { userId: msg.userId, name: msg.name, groupId: msg.groupId, channelId: msg.channelId });\n }\n return;\n case \"group-joined\": {\n const group = await this.fetchGroup(msg.groupId);\n this.emit(\"groupJoin\", group);\n return;\n }\n case \"group-updated\": {\n if (!this.groups.has(msg.groupId)) return;\n const group = await this.fetchGroup(msg.groupId).catch(() => null);\n if (group) this.emit(\"groupUpdate\", group);\n return;\n }\n case \"group-member-add\": {\n if (!msg.member) return;\n const user = this._cacheUser(msg.member);\n const group = this.groups.get(msg.groupId) ?? (await this.fetchGroup(msg.groupId).catch(() => null));\n if (group) group.memberCount += 1;\n this.emit(\"memberAdd\", { user, group, groupId: msg.groupId, via: msg.via ?? null });\n return;\n }\n case \"group-member-remove\": {\n const group = this.groups.get(msg.groupId) ?? null;\n if (group) group.memberCount = Math.max(0, group.memberCount - 1);\n this.emit(\"memberRemove\", { userId: msg.userId, user: this.users.get(msg.userId) ?? null, group, groupId: msg.groupId, reason: msg.reason ?? null, by: msg.by ?? null });\n return;\n }\n case \"group-removed\":\n this.groups.delete(msg.groupId);\n this.emit(\"groupLeave\", { id: msg.groupId, reason: msg.reason ?? null });\n return;\n default:\n this.emit(\"raw\", msg);\n }\n }\n}\n", "// As rotas HTTP da API de bots (api/botApi.mjs), com o token no cabe\u00E7alho\n// `Authorization: Bot <token>`. Trata o limite de envio (429) esperando o\n// tempo que a API pede e tentando de novo.\n\nexport class FiveLiveAPIError extends Error {\n /**\n * @param {string} message\n * @param {number} status\n * @param {string} method\n * @param {string} path\n */\n constructor(message, status, method, path) {\n super(message);\n this.name = \"FiveLiveAPIError\";\n this.status = status;\n this.method = method;\n this.path = path;\n }\n}\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class REST {\n /** @param {{ token: string, apiUrl: string, retries?: number }} options */\n constructor(options) {\n this.token = options.token;\n this.apiUrl = options.apiUrl.replace(/\\/$/, \"\");\n this.retries = options.retries ?? 3;\n }\n\n /**\n * @param {string} method\n * @param {string} path\n * @param {unknown} [body]\n */\n async request(method, path, body) {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(this.apiUrl + path, {\n method,\n headers: {\n Authorization: `Bot ${this.token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n \"User-Agent\": \"fivelive.js (https://live.fivenetwork.dev/developers, 0.1.0)\",\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n const data = await res.json().catch(() => ({}));\n if (res.status === 429 && attempt < this.retries) {\n const seconds = Number(data.retryAfter ?? res.headers.get(\"retry-after\") ?? 5);\n await sleep(Math.max(1, seconds) * 1000);\n continue;\n }\n if (!res.ok) throw new FiveLiveAPIError(data.error ?? `HTTP ${res.status}`, res.status, method, path);\n return data;\n }\n }\n\n get(path) {\n return this.request(\"GET\", path);\n }\n post(path, body) {\n return this.request(\"POST\", path, body ?? {});\n }\n patch(path, body) {\n return this.request(\"PATCH\", path, body ?? {});\n }\n put(path, body) {\n return this.request(\"PUT\", path, body ?? {});\n }\n delete(path) {\n return this.request(\"DELETE\", path);\n }\n}\n\nexport const enc = encodeURIComponent;\n", "// Os objetos que o bot recebe: User, Group, Channel, Message. Cada um sabe\n// agir sobre si mesmo (message.reply, channel.send, \u2026) usando o client.\n\nimport { enc } from \"./rest.js\";\n\n/** `<@id>` \u2014 como mencionar algu\u00E9m no texto. */\nexport const userMention = (id) => `<@${id}>`;\n/** `<#id>` \u2014 como apontar uma sala no texto. */\nexport const channelMention = (id) => `<#${id}>`;\n\n/**\n * Normaliza o que se manda: um texto, ou { content, embeds, mentions, reply }.\n * @param {string | Record<string, any>} input\n */\nexport function messagePayload(input) {\n const options = typeof input === \"string\" ? { content: input } : input ?? {};\n const embeds = (options.embeds ?? []).map((embed) => (typeof embed?.toJSON === \"function\" ? embed.toJSON() : embed));\n const roles = (options.roleMentions ?? []).map((id) => `@role:${id}`);\n return {\n text: options.content ?? \"\",\n ...(embeds.length ? { embeds } : {}),\n ...(options.mentions?.length || roles.length || options.everyone\n ? { mentions: [...(options.mentions ?? []), ...roles, ...(options.everyone ? [\"@everyone\"] : [])] }\n : {}),\n ...(options.reply ? { replyTo: typeof options.reply === \"string\" ? options.reply : options.reply.id } : {}),\n };\n}\n\nexport class User {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this.id = data.id;\n this.username = data.username ?? null;\n this.displayName = data.displayName ?? data.name ?? data.username ?? \"\";\n this.avatarURL = data.avatarUrl ?? null;\n this.bot = data.bot === true;\n this.flags = data.flags ?? [];\n }\n /** `<@id>`, para colocar no texto. */\n toString() {\n return userMention(this.id);\n }\n}\n\nexport class Channel {\n /** @param {import(\"./client.js\").Client} client @param {Group} group @param {Record<string, any>} data */\n constructor(client, group, data) {\n this.client = client;\n this.group = group;\n this.id = data.id;\n this.name = data.name;\n /** \"text\" | \"voice\" */\n this.kind = data.kind;\n this.categoryId = data.categoryId ?? null;\n this.topic = data.topic ?? \"\";\n }\n get isText() {\n return this.kind === \"text\";\n }\n get path() {\n return `/bot/groups/${enc(this.group.id)}/channels/${enc(this.id)}`;\n }\n /** Manda uma mensagem. @param {string | Record<string, any>} content */\n async send(content) {\n const data = await this.client.rest.post(`${this.path}/messages`, messagePayload(content));\n return new Message(this.client, data.message, this.client.user);\n }\n /** \"Digitando\u2026\" por alguns segundos. */\n async sendTyping() {\n await this.client.rest.post(`${this.path}/typing`, { typing: true });\n }\n /**\n * As \u00FAltimas mensagens (a mais nova por \u00FAltimo).\n * @param {{ limit?: number, after?: string }} [options]\n */\n async fetchMessages(options = {}) {\n const query = new URLSearchParams();\n if (options.limit) query.set(\"limit\", String(options.limit));\n if (options.after) query.set(\"after\", options.after);\n const data = await this.client.rest.get(`${this.path}/messages?${query}`);\n return data.messages.map((message) => new Message(this.client, message));\n }\n /** Uma mensagem pelo id. */\n async fetchMessage(id) {\n const data = await this.client.rest.get(`${this.path}/messages/${enc(id)}`);\n return new Message(this.client, data.message);\n }\n toString() {\n return `<#${this.id}>`;\n }\n}\n\nexport class Group {\n /** @param {import(\"./client.js\").Client} client @param {Record<string, any>} data */\n constructor(client, data) {\n this.client = client;\n this._patch(data);\n }\n /** @param {Record<string, any>} data */\n _patch(data) {\n this.id = data.id;\n this.name = data.name;\n this.iconURL = data.iconUrl ?? null;\n this.ownerId = data.ownerId ?? null;\n this.memberCount = data.memberCount ?? 0;\n /** @type {{ id: string, name: string, color: string | null, position: number, mentionable: boolean }[]} */\n this.roles = data.roles ?? [];\n /** O que o bot pode fazer aqui (kickMembers, banMembers, manageRoles, manageMessages\u2026). */\n this.permissions = data.permissions ?? {};\n /** @type {Map<string, Channel>} */\n this.channels = new Map((data.channels ?? []).map((channel) => [channel.id, new Channel(this.client, this, channel)]));\n }\n /** A sala pelo id ou pelo nome. @param {string} idOrName */\n channel(idOrName) {\n return this.channels.get(idOrName) ?? [...this.channels.values()].find((channel) => channel.name === idOrName) ?? null;\n }\n /** Os membros, com cargos e quem est\u00E1 online. */\n async fetchMembers() {\n const data = await this.client.rest.get(`/bot/groups/${enc(this.id)}/members`);\n return data.members.map((member) => ({ ...member, user: this.client._cacheUser(member) }));\n }\n get path() {\n return `/bot/groups/${enc(this.id)}`;\n }\n /** Se o bot tem a permiss\u00E3o (administrator vale por todas). @param {string} key */\n can(key) {\n return this.permissions.administrator === true || this.permissions[key] === true;\n }\n /** Expulsa algu\u00E9m (precisa de kickMembers e de um cargo acima do da pessoa). @param {string} userId */\n async kick(userId) {\n await this.client.rest.post(`${this.path}/members/${enc(userId)}/kick`, {});\n }\n /** Bane algu\u00E9m, mesmo que n\u00E3o esteja no grupo (banMembers). @param {string} userId @param {string} [reason] */\n async ban(userId, reason) {\n await this.client.rest.put(`${this.path}/bans/${enc(userId)}`, reason ? { reason } : {});\n }\n /** Tira o banimento (banMembers). @param {string} userId */\n async unban(userId) {\n await this.client.rest.delete(`${this.path}/bans/${enc(userId)}`);\n }\n /** Quem est\u00E1 banido (banMembers). */\n async fetchBans() {\n const data = await this.client.rest.get(`${this.path}/bans`);\n return data.bans;\n }\n /** D\u00E1 um cargo (manageRoles; s\u00F3 cargos abaixo do mais alto do bot). @param {string} userId @param {string} roleId */\n async addRole(userId, roleId) {\n const data = await this.client.rest.put(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** Tira um cargo (manageRoles). @param {string} userId @param {string} roleId */\n async removeRole(userId, roleId) {\n const data = await this.client.rest.delete(`${this.path}/members/${enc(userId)}/roles/${enc(roleId)}`);\n return data.roleIds;\n }\n /** O bot sai do grupo. */\n async leave() {\n await this.client.rest.post(`${this.path}/leave`, {});\n }\n /** `<@&id>` n\u00E3o existe aqui: para mencionar um cargo, use { roleMentions: [id] } no envio. */\n role(idOrName) {\n return this.roles.find((role) => role.id === idOrName || role.name === idOrName) ?? null;\n }\n}\n\nexport class Message {\n /**\n * @param {import(\"./client.js\").Client} client\n * @param {Record<string, any>} data\n * @param {User | Record<string, any>} [author]\n */\n constructor(client, data, author) {\n this.client = client;\n this.id = data.id;\n this.groupId = data.groupId;\n this.channelId = data.channelId;\n /** O texto como est\u00E1 gravado \u2014 men\u00E7\u00F5es como `<@id>`. */\n this.content = data.text ?? \"\";\n this.embeds = data.embeds ?? [];\n this.attachments = data.attachments ?? [];\n this.images = data.images ?? [];\n this.reactions = data.reactions ?? [];\n this.replyTo = data.replyTo ?? null;\n this.createdAt = new Date(data.ts ?? Date.now());\n this.editedAt = data.editedAt ? new Date(data.editedAt) : null;\n this.pinned = Boolean(data.pinnedAt);\n this.webhook = Boolean(data.webhook);\n const mentions = data.mentions ?? [];\n this.mentions = {\n /** ids das pessoas mencionadas */\n users: mentions.filter((entry) => !entry.startsWith(\"@\")),\n /** ids dos cargos mencionados */\n roles: mentions.filter((entry) => entry.startsWith(\"@role:\")).map((entry) => entry.slice(6)),\n everyone: mentions.includes(\"@everyone\"),\n raw: mentions,\n };\n this.author =\n author instanceof User\n ? author\n : author\n ? client._cacheUser(author)\n : client.users.get(data.from) ?? new User(client, { id: data.from, name: data.fromName });\n }\n get group() {\n return this.client.groups.get(this.groupId) ?? null;\n }\n get channel() {\n return this.group?.channels.get(this.channelId) ?? null;\n }\n /** O texto com `<@id>` trocado por `@nome` (quando o nome \u00E9 conhecido). */\n get cleanContent() {\n return this.content.replace(/<@([A-Za-z0-9:_-]+)>/g, (whole, id) => {\n const user = this.client.users.get(id);\n return user ? `@${user.displayName}` : whole;\n });\n }\n /** Se a mensagem menciona o bot (pelo id, cargo n\u00E3o conta). */\n get mentionsMe() {\n return this.mentions.users.includes(this.client.user?.id) || this.mentions.everyone;\n }\n get path() {\n return `/bot/groups/${enc(this.groupId)}/channels/${enc(this.channelId)}/messages`;\n }\n /** Responde citando esta mensagem. @param {string | Record<string, any>} content */\n async reply(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.post(this.path, { ...payload, replyTo: this.id });\n return new Message(this.client, data.message, this.client.user);\n }\n /** Edita (s\u00F3 as mensagens do pr\u00F3prio bot). @param {string | Record<string, any>} content */\n async edit(content) {\n const payload = messagePayload(content);\n const data = await this.client.rest.patch(`${this.path}/${enc(this.id)}`, { text: payload.text, ...(payload.embeds ? { embeds: payload.embeds } : {}) });\n return new Message(this.client, data.message, this.author);\n }\n /** Fixa na sala (manageMessages). */\n async pin() {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Desafixa (manageMessages). */\n async unpin() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/pin`);\n }\n /** Apaga: as do pr\u00F3prio bot sempre; as dos outros, com manageMessages. */\n async delete() {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}`);\n }\n /** Reage com um emoji. @param {string} emoji */\n async react(emoji) {\n await this.client.rest.put(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n /** Tira a rea\u00E7\u00E3o do bot. @param {string} emoji */\n async unreact(emoji) {\n await this.client.rest.delete(`${this.path}/${enc(this.id)}/reactions/${enc(emoji)}`);\n }\n}\n", "// Construtor de embeds no mesmo formato do discord.js (e do webhook do Five\n// Live): t\u00EDtulo, descri\u00E7\u00E3o, cor, autor, campos, imagem, miniatura, rodap\u00E9.\n\n/** @param {string | number} color */\nfunction toColor(color) {\n if (typeof color === \"number\") return color;\n const hex = String(color).replace(/^#/, \"\");\n return /^[0-9a-f]{6}$/i.test(hex) ? parseInt(hex, 16) : undefined;\n}\n\nexport class EmbedBuilder {\n /** @param {Record<string, unknown>} [data] */\n constructor(data = {}) {\n /** @type {Record<string, any>} */\n this.data = { ...data };\n }\n setTitle(title) {\n this.data.title = title;\n return this;\n }\n setDescription(description) {\n this.data.description = description;\n return this;\n }\n setURL(url) {\n this.data.url = url;\n return this;\n }\n /** @param {string | number} color \"#3b6cf6\" ou 0x3b6cf6 */\n setColor(color) {\n this.data.color = toColor(color);\n return this;\n }\n /** @param {{ name: string, url?: string, iconURL?: string }} author */\n setAuthor(author) {\n this.data.author = { name: author.name, url: author.url, icon_url: author.iconURL };\n return this;\n }\n /** @param {{ text: string, iconURL?: string }} footer */\n setFooter(footer) {\n this.data.footer = { text: footer.text, icon_url: footer.iconURL };\n return this;\n }\n setImage(url) {\n this.data.image = { url };\n return this;\n }\n setThumbnail(url) {\n this.data.thumbnail = { url };\n return this;\n }\n /** @param {Date | number | string} [timestamp] */\n setTimestamp(timestamp = new Date()) {\n this.data.timestamp = new Date(timestamp).toISOString();\n return this;\n }\n /** @param {...{ name: string, value: string, inline?: boolean }} fields */\n addFields(...fields) {\n this.data.fields = [...(this.data.fields ?? []), ...fields.flat()];\n return this;\n }\n toJSON() {\n return this.data;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EventEmitter", "FiveLiveAPIError", "message", "status", "method", "path", "sleep", "ms", "resolve", "REST", "options", "body", "attempt", "res", "data", "seconds", "enc", "userMention", "id", "channelMention", "messagePayload", "input", "options", "embeds", "embed", "roles", "User", "client", "data", "Channel", "group", "enc", "content", "Message", "query", "message", "Group", "channel", "idOrName", "member", "key", "userId", "reason", "roleId", "role", "_Message", "author", "mentions", "entry", "whole", "user", "payload", "emoji", "DEFAULT_API", "KEEPALIVE_MS", "MAX_BACKOFF_MS", "socketClass", "mod", "Client", "EventEmitter", "options", "REST", "command", "alias", "seen", "commands", "err", "message", "name", "args", "context", "content", "me", "data", "raw", "held", "Group", "id", "user", "User", "Socket", "resolve", "reject", "ws", "settled", "send", "payload", "event", "msg", "first", "delay", "Message", "group", "toColor", "color", "hex", "EmbedBuilder", "data", "title", "description", "url", "author", "footer", "timestamp", "fields"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fivelive.js",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SDK oficial para criar bots do Five Live — eventos em tempo real,
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "SDK oficial para criar bots do Five Live — eventos em tempo real, comandos de barra (/), embeds, reações e moderação. Parecido com o discord.js.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -38,9 +38,14 @@
|
|
|
38
38
|
},
|
|
39
39
|
"keywords": [
|
|
40
40
|
"fivelive",
|
|
41
|
+
"five-live",
|
|
41
42
|
"bot",
|
|
42
43
|
"sdk",
|
|
43
|
-
"chat"
|
|
44
|
+
"chat",
|
|
45
|
+
"slash-commands",
|
|
46
|
+
"embeds",
|
|
47
|
+
"moderation",
|
|
48
|
+
"discord.js-like"
|
|
44
49
|
],
|
|
45
50
|
"license": "MIT",
|
|
46
51
|
"homepage": "https://live.fivenetwork.dev/developers"
|