fivelive.js 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -176,6 +176,26 @@ try {
176
176
  }
177
177
  ```
178
178
 
179
- ## Sem o SDK
179
+ ## Comandos de barra (/)
180
180
 
181
- A API por trás é HTTP + WebSocket e pode ser usada de qualquer linguagem. A documentação está em https://live.fivenetwork.dev/developers.
181
+ Todo `client.command` com `description` vira um comando de barra: quem digitar `/` numa sala em que o bot está vê o comando na lista, com a descrição e os argumentos — do jeito do Discord. O `login()` manda a lista sozinho.
182
+
183
+ ```js
184
+ const client = new Client({ token: process.env.FIVELIVE_TOKEN, prefix: "/" });
185
+
186
+ client.command({
187
+ name: "ban",
188
+ description: "Bane alguém do grupo",
189
+ options: [
190
+ { name: "usuario", description: "Quem banir", required: true, type: "user" },
191
+ { name: "motivo", description: "Por quê" },
192
+ ],
193
+ run: async ({ message, args, reply }) => { /* ... */ },
194
+ });
195
+ ```
196
+
197
+ Até 25 comandos por bot. Registrou mais depois do `login()`? Chame `client.syncCommands()`.
198
+
199
+ ## Documentação
200
+
201
+ Tudo em https://live.fivenetwork.dev/developers/docs — gateway, permissões, moderação, OAuth2, webhooks e exemplos.
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
@@ -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", "message", "name", "args", "context", "content", "err", "me", "data", "seen", "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"]
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
@@ -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": "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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", "message", "name", "args", "context", "content", "err", "me", "data", "seen", "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"]
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,6 +1,6 @@
1
1
  {
2
2
  "name": "fivelive.js",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "SDK oficial para criar bots do Five Live — eventos em tempo real, mensagens, embeds, reações e comandos.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",