diff --git a/package-lock.json b/package-lock.json index 7048e50..cf74de7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "ISC", "dependencies": { "axios": "^1.3.4", - "websocket": "^1.0.34" + "websocket": "^1.0.34", + "ws": "^8.13.0" }, "devDependencies": { "@types/node": "^18.15.3" @@ -253,6 +254,26 @@ "node": ">=4.0.0" } }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", diff --git a/package.json b/package.json index 7803794..2c3d9b1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ }, "dependencies": { "axios": "^1.3.4", - "websocket": "^1.0.34" - } + "websocket": "^1.0.34", + "ws": "^8.13.0" + }, + "type": "module" } diff --git a/structures/client/client.js b/structures/client/client.js index ecadae7..f491b9c 100644 --- a/structures/client/client.js +++ b/structures/client/client.js @@ -1,24 +1,23 @@ -const opts = require('./clientOpts.js'); -const gateWayIntents = require('../gateway/intents.js'); -const gateWayEvents = require('../gateway/dispatch.js'); -var WebSocketClient = require('websocket').client; -const WebSocketConnection = require('websocket').connection; -const handleResponses = require('./handleEvents.js'); -const { EventEmitter } = require('events'); -const axios = require('axios'); -const { exit } = require('process'); -const Guild = require('../guilds/guild.js'); +import gateWayEvents from '../gateway/dispatch.js'; +//import WebSocketClient from 'websocket'; +//import WebSocketConnection from 'websocket'; +import WebSocket from 'ws'; +import handleResponses from './handleEvents.js'; +import { EventEmitter } from 'events'; +import axios from 'axios'; +import { exit } from 'process'; +import Guild from '../guilds/Guild.js'; -class Client extends EventEmitter { - /** @type {WebSocketClient} */ +export class Client extends EventEmitter { + /** @type {WebSocket} */ ws; /** @type {Number} */ heartBeatInterval; - /** @type {Array} */ + /** @type {gateWayEvents[]} */ gwintents; /** @type {String} */ @@ -51,10 +50,10 @@ class Client extends EventEmitter { async #heartbeat(hbInt, hbSequence) { const toSend = JSON.stringify({ op: 1, d: 0 }); - this.connection.send((toSend)); + this.ws.send((toSend)); setInterval(() => { - this.connection.send(toSend); + this.ws.send(toSend); }, hbInt); } @@ -65,27 +64,6 @@ class Client extends EventEmitter { { this.heartBeatInterval = hbint; console.log("INTERVAL SET TO: " + this.heartBeatInterval); - - //Get the user intents - let iCount = 0; - for (let i of this.gwintents) { - iCount += (i) ? i : 0; - } - - var idObj = { - op: 2, - d: { - token: this.#token.replace("Bot ", ""), - intents: iCount, //61440, - properties: { - os: "linux", - browser: "ion_", - device: "my_library" - } - } - }; - - this.connection.send(JSON.stringify(idObj)); this.#heartbeat(hbint); } @@ -134,61 +112,79 @@ class Client extends EventEmitter { if (!isUser) token = "Bot " + token; return new Promise((resolve, reject) => { - this.ws = new WebSocketClient({maxReceivedFrameSize: Infinity}); + this.ws = new WebSocket("wss://gateway.discord.gg/?v=10&encoding=json"); this.#token = token; - this.ws.on('connect', async (connection) => { - connection.on('message', async (msg) => { - const data = JSON.parse(msg.utf8Data); - const response = await handleResponses(data, token, this.id); - - if (response.op == 10) { this.#startHeartBeat(response.heartBeat, token); } - else if (response.op == 0) { - if (response.t == gateWayEvents.Ready) { - this.user_profile = response.profile; - this.user_settings = response.config; - this.id = response.profile.id; - console.log(response.guilds); - this.ready(); + this.ws.on('open', () => { + //Get the user intents + let iCount = 0; + for (let i of this.gwintents) { + iCount += (i) ? i : 0; + } + + var idObj = { + op: 2, + d: { + token: token.replace("Bot ", ""), + intents: iCount, //61440, + properties: { + os: "linux", + browser: "ion_", + device: "my_library" } - else if (response.t == gateWayEvents.MessageCreate) { - if (data["d"]["author"]["id"] != this.user_profile.id){ - this.messageRecieved(response.message); - } - } - else if (response.t == gateWayEvents.InteractionCreate) { - if (data["d"]["user"]["id"] != this.user_profile.id) { - this.interactionRecieved(response.interaction); - } - } - else if (response.t == gateWayEvents.GuildCreate) this.guildCreate(response.guild); - else if (response.t == gateWayEvents.GuildDelete) this.guildDelete(response.guild); - else if (response.t == gateWayEvents.GuildMemberAdd) this.guildMemberAdd(response.member); - else console.log(response.t); - } else { - console.log(response.t); } - }); - - connection.on('close', (code, desc) => { - console.log(`CONNECTION CLOSED WITH CODE ${code}\nREASON:\n ${desc}`); - exit(1); - }); - - connection.on('error', (err) => { - reject(err); - }); - - this.connection = connection; + }; + + this.ws.send(JSON.stringify(idObj)); }); - this.ws.on('connectFailed', (err) => { reject(err); }); + this.ws.on('message', async (msg) => { + const data = JSON.parse(msg.toString()); + const response = await handleResponses(data, token, this.id); - this.ws.connect("wss://gateway.discord.gg/?v=10&encoding=json"); + if (response.op == 10) { this.#startHeartBeat(response.heartBeat, token); } + else if (response.op == 0) { + if (response.t == gateWayEvents.Ready) { + this.user_profile = response.profile; + this.user_settings = response.config; + this.id = response.profile.id; + console.log(response.guilds); + this.ready(); + } + else if (response.t == gateWayEvents.MessageCreate) { + if (data["d"]["author"]["id"] != this.user_profile.id){ + response.message.guild = this.guilds.get(response.message.guild_id); + this.messageRecieved(response.message); + } + } + else if (response.t == gateWayEvents.InteractionCreate) { + if (data["d"]["user"]["id"] != this.user_profile.id) { + this.interactionRecieved(response.interaction); + } + } + else if (response.t == gateWayEvents.GuildCreate) this.guildCreate(response.guild); + else if (response.t == gateWayEvents.GuildDelete) this.guildDelete(response.guild); + else if (response.t == gateWayEvents.GuildMemberAdd) this.guildMemberAdd(response.member); + else console.log(response.t); + } else { + console.log(response.t); + } + }); + + this.ws.on('close', (code, desc) => { + console.log(`CONNECTION CLOSED WITH CODE ${code}\nREASON:\n ${desc}`); + exit(1); + }); + + this.ws.on('error', (err) => { + reject(err); + }); + + this.ws.on('error', (err) => { reject(err); }); }); } } //All client properties will be re-routed through this export -module.exports = { Client, gateWayIntents } \ No newline at end of file +export {gateWayIntents} from '../gateway/intents.js'; \ No newline at end of file diff --git a/structures/client/clientOpts.js b/structures/client/clientOpts.js deleted file mode 100644 index e5d30d0..0000000 --- a/structures/client/clientOpts.js +++ /dev/null @@ -1,7 +0,0 @@ -const intents = require('../gateway/intents.js'); - - -module.exports = { - /**@type {Array} */ - intents: [] -} \ No newline at end of file diff --git a/structures/client/handleEvents.js b/structures/client/handleEvents.js index 4c0a970..d2c2014 100644 --- a/structures/client/handleEvents.js +++ b/structures/client/handleEvents.js @@ -1,8 +1,7 @@ -const { exit } = require('process'); -const gateWayEvents = require('../gateway/dispatch.js'); -const { message } = require('../messages/message.js'); -const Interaction = require('../interactions/interaction.js'); -const Guild = require('../guilds/guild.js'); +import gateWayEvents from '../gateway/dispatch.js' +import { message } from '../messages/message.js'; +import {Interaction} from '../interactions/interaction.js'; +import Guild from '../guilds/Guild.js'; /** @@ -10,7 +9,7 @@ const Guild = require('../guilds/guild.js'); * @param {Object} msg * @returns {Promise} */ -module.exports = async function handleEvents(msgObj, token, id) { +export default async function handleEvents(msgObj, token, id) { return new Promise((resolve, reject) => { const op = msgObj["op"]; const t = msgObj["t"]; diff --git a/structures/gateway/dispatch.js b/structures/gateway/dispatch.js index abb85b5..9bf794e 100644 --- a/structures/gateway/dispatch.js +++ b/structures/gateway/dispatch.js @@ -1,4 +1,4 @@ -module.exports = Object.freeze({ +export default Object.freeze({ ApplicationCommandPermissionsUpdate: "APPLICATION_COMMAND_PERMISSIONS_UPDATE", ChannelCreate: "CHANNEL_CREATE", ChannelDelete: "CHANNEL_DELETE", diff --git a/structures/gateway/intents.js b/structures/gateway/intents.js index 78acf20..231d483 100644 --- a/structures/gateway/intents.js +++ b/structures/gateway/intents.js @@ -1,4 +1,4 @@ -module.exports = Object.freeze({ +export const gateWayIntents = Object.freeze({ Guilds: 1 << 0, GuildMembers: 1 << 1, GuildModeration: 1 << 2, diff --git a/structures/guilds/guild.js b/structures/guilds/guild.js index 691d554..996395c 100644 --- a/structures/guilds/guild.js +++ b/structures/guilds/guild.js @@ -1,12 +1,14 @@ -const axios = require('axios'); -const member = require('./member.js'); -const guildRole = require('./guildRoles.js'); -const GuildEmoji = require('./guildEmoji.js'); -const { Channel } = require('../messages/message.js'); +import axios from 'axios'; +import member from './member.js'; +import {guildRole, guildRoleManager, guildMemberRoleManager} from './guildRoles.js'; +import GuildEmoji from './guildEmoji.js'; +import {Channel} from '../messages/message.js'; +import guildInvite from './guildInvite.js'; //See https://discord.com/developers/docs/resources/guild -class Guild { +export default class Guild { + #token; /** @type {String[]} */ embeded_activities; @@ -26,7 +28,7 @@ class Guild { /** @type {Boolean} */ nsfw; - /** @type {member[]} */ + /** @type {Map} */ members; /** @type {String} */ @@ -44,7 +46,7 @@ class Guild { /** @type {Map} */ members; - /** @type {guildRole[]} */ + /** @type {guildRoleManager} */ roles; /** @type {String} */ @@ -107,39 +109,74 @@ class Guild { for (const channel of response.data) { if (channel.type == 4) continue; - this.channels.set(channel.id, new Channel(token, channel.id)); + this.channels.set(channel.id, new Channel(token, channel, this)); } } + + async #getMembers(membersObj, token) { + for (const m of membersObj) { + var tempRoles = []; + for (const rid of m["roles"]) { + tempRoles.push(this.roles.cache.get(rid)); + } + + const roleTemp = new guildMemberRoleManager(tempRoles, m["user"]["id"], token); + roleTemp.guild = this; + const mem = new member(m, roleTemp); + + this.members.set(mem.user.id, mem); + } + } + + /** + * @returns {Promise} + */ + getInvites() { + return new Promise(async (resolve, reject) => { + const config = { + headers: { + Authorization: this.#token + } + } + + const response = await axios.get(`https://discord.com/api/guilds/${this.id}/invites`, config); + const invites = []; + for (const i of response.data) { + invites.push(new guildInvite(i, this, this.#token)); + } + + resolve(invites); + }); + } + + /** + * @param {Object} o + * @param {String} token + */ constructor(o, token) { this.members = new Map(); this.channels = new Map(); - this.roles = []; this.stickers = []; + this.#token = token; for (const field in this) { - if (o[field] == undefined || field == "channels") continue; + if (o[field] == undefined || field == "channels" || field == "members") continue; - if (field == 'members') { - for (const m of o[field]) { - const mem = new member(m); - this.members.set(mem.user.id); - } - } - else if (field == 'roles') { + if (field == 'roles') { + var temp = []; for (const r of o[field]) { - this.roles.push(new guildRole(r)); + temp.push(new guildRole(r)); } + this.roles = new guildRoleManager(temp, false, token); + this.roles.guild = this; } else { this[field] = o[field]; } } + this.#getMembers(o["members"], token); this.#getChannels(token); } } - - - -module.exports = Guild; \ No newline at end of file diff --git a/structures/guilds/guildEmoji.js b/structures/guilds/guildEmoji.js index 8b6ed96..4b71692 100644 --- a/structures/guilds/guildEmoji.js +++ b/structures/guilds/guildEmoji.js @@ -1,4 +1,4 @@ -class GuildEmoji { +export default class GuildEmoji { /** @type {Number} */ version; @@ -22,7 +22,4 @@ class GuildEmoji { /** @type {Boolean} */ animated; -} - - -module.exports = GuildEmoji; \ No newline at end of file +} \ No newline at end of file diff --git a/structures/guilds/guildInvite.js b/structures/guilds/guildInvite.js new file mode 100644 index 0000000..6942183 --- /dev/null +++ b/structures/guilds/guildInvite.js @@ -0,0 +1,58 @@ +import author from '../messages/author.js'; +import Guild from './Guild.js' +import { Channel } from '../messages/message.js'; +import axios from 'axios'; + + +export default class invite { + #token; + + code; + + /** @type {Guild} */ + guild; + + /** @type {Channel?} */ + channel; + + /** @type {member?} */ + inviter; + + /** @type {EpochTimeStamp} */ + expires_at; + + /** @type {Number} */ + uses; + + /** @type {Number} */ + max_uses; + + /** @type {Number} */ + max_age; + + /** @type {Boolean} */ + temporary; + + /** @type {String} */ + created_at; + + async delete() { + return new Promise(async (resolve) => { + // const headers = { Authorization: this.#token } + // const response = await axios.delete(`https://discord.com/api/guilds/${this.guild.id}/roles`, role.toObj(), { headers }); + // resolve(response.data); + }); + } + + constructor(o, guild, token) { + this.#token = token; + for (const k in this) { + if (o[k]) { + if (k == 'guild') { this.guild = guild } + else if (k == 'channel') { this.channel = this.guild.channels.get(o[k]['id']); } + else if (k == 'inviter') { this.inviter = new author(o[k], null); } + else { this[k] = o[k]; } + } else { this[k] = 0; } + } + } +} \ No newline at end of file diff --git a/structures/guilds/guildRoles.js b/structures/guilds/guildRoles.js index 6accfc0..5b876e1 100644 --- a/structures/guilds/guildRoles.js +++ b/structures/guilds/guildRoles.js @@ -1,4 +1,11 @@ -class guildRole { +import axios from 'axios'; +import Guild from './Guild.js'; + +// Maybe add support for this +// https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + + +export class guildRole { /** @type {Number} */ version; @@ -47,5 +54,203 @@ class guildRole { } } +export class newGuildRoleObj { + /** @type {String} */ + name; -module.exports = guildRole; \ No newline at end of file + /** @type {WHAT} */ + permissions; + + /** @type {String} */ + color; + + /** @type {Boolean} */ + hoist; + + /** @type {WHAT} */ + icon; + + /** @type {String} */ + unicode_emoji; + + /** @type {Boolean} */ + mentionable; + + /** + * @param {{ name: String, permissions?: any, color?: Number, hoist>: Boolean, icon?: String, unicode_emoji?: String, mentionable?: Boolean }} o + */ + constructor(o = undefined) { + for (const f in this) { + if (f in o) { + this[f] = o[f]; + } + } + } + + toObj() { + let obj = {}; + for (const f in this) { + obj[f] = this[f]; + } + return obj; + } +} + + +export class guildMemberRoleManager { + #uid; + #token; + + /** @type {Guild} */ + guild; + + /** @type {Map} */ + cache; + + /** + * @param {String | guildRole} role + */ + async remove(role) { + return new Promise(async (resolve, reject) => { + const rid = (typeof role == 'string') ? role : role.id; + if (!this.cache.has(rid)) throw "USER DOESN'T HAVE THIS ROLE"; + + const config = { + headers: { + Authorization: this.#token + } + } + + this.cache.delete(rid); + + const response = await axios.delete(`https://discord.com/api/guilds/${this.guild.id}/members/${this.#uid}/roles/${rid}`, config); + + resolve(response); + }); + } + + /** + * @param {String | guildRole} role + * @returns { import('axios').AxiosResponse | String } + */ + async add(role) { + return new Promise(async (resolve, reject) => { + const rid = (typeof role == 'string') ? role : role.id; + const grole = this.guild.roles.cache?.get(rid) + if (this.cache.has(rid)) throw "USER ALREADY HAS THIS ROLE"; + if (!grole) throw "ROLE NOT FOUND"; + + const headers = { Authorization: this.#token } + this.cache.set(rid, grole); + + const response = await axios.put(`https://discord.com/api/guilds/${this.guild.id}/members/${this.#uid}/roles/${rid}`, {}, { headers }); + + resolve(response); + }); + } + + /** + * @param {String | guildRole} role + */ + has(role) { + return this.cache.has(role); + } + + /** + * @param {Array} roles + * @param {String} uid UID or GuildId + */ + constructor(roles, uid, token) { + this.#token = token; + this.#uid = uid; + this.cache = new Map(); + roles.forEach((gr) => this.cache.set(gr.id, gr)); + } +} + + +export class guildRoleManager { + #uid; + #token; + + /** @type {Guild} */ + guild; + + /** @type {Map} */ + cache; + + /** + * @param {String | guildRole} role + */ + has(role) { + const rid = (typeof role == 'string') ? role : role.id; + return this.cache.has(rid); + } + + /** + * @param {String} name + */ + findByName(name) { + return [...this.cache.values()].find(r => (r.name == name)); + } + + /** + * @param {newGuildRoleObj} role + * @returns {Promise} + */ + create(role) { + return new Promise(async (resolve, reject) => { + try { + const mrole = [...this.cache.values()].find(r => (r.name == role.name)); + if (mrole) throw "ROLE ALREADY EXISTS!"; + + const headers = { Authorization: this.#token } + // this.cache.set(rid, grole); + + const response = await axios.post(`https://discord.com/api/guilds/${this.guild.id}/roles`, role.toObj(), { headers }); + + const newRole = new guildRole(response.data); + this.cache.set(newRole.id, newRole); + resolve(newRole); + } catch (err) { + throw err; + } + }); + } + + + /** + * @description returns true if succeeded and throws error otherwise + * @param {guildRole} role + * @returns {Promise} + */ + delete(role) { + return new Promise(async (resolve, reject) => { + try { + const grole = this.guild.roles.cache?.get(role.id); + if (!grole) throw "ROLE DOES NOT EXIST!"; + + const headers = { Authorization: this.#token } + // this.cache.set(rid, grole); + + const response = await axios.delete(`https://discord.com/api/guilds/${this.guild.id}/roles/${role.id}`, { headers }); + resolve(true); + } catch (err) { + throw err; + } + }); + } + + + + /** + * @param {Array} roles + * @param {String} uid UID or GuildId + */ + constructor(roles, uid, token) { + this.#token = token; + this.#uid = uid; + this.cache = new Map(); + roles.forEach((gr) => this.cache.set(gr.id, gr)); + } +} \ No newline at end of file diff --git a/structures/guilds/member.js b/structures/guilds/member.js index 03d4249..5ac4760 100644 --- a/structures/guilds/member.js +++ b/structures/guilds/member.js @@ -1,8 +1,13 @@ -class member { +import axios from 'axios'; +import {guildRole, guildMemberRoleManager} from "./guildRoles.js"; +// https://discord.com/developers/docs/resources/guild#modify-guild-member + + +export default class member { /** @type {Object} */ user; - /** @type {Object[]} */ + /** @type {guildMemberRoleManager} */ roles; /** @type {String} */ @@ -32,14 +37,12 @@ class member { /** @type {String} */ avatar; - constructor(o) { + constructor(o, roles) { + this.roles = roles; for (const k in this) { - if (o[k]) { + if (o[k] && k != 'roles') { this[k] = o[k]; } } } -} - - -module.exports = member; \ No newline at end of file +} \ No newline at end of file diff --git a/structures/interactions/interaction.js b/structures/interactions/interaction.js index 3697469..7421eb4 100644 --- a/structures/interactions/interaction.js +++ b/structures/interactions/interaction.js @@ -1,10 +1,10 @@ -const axios = require('axios'); -const author = require('../messages/author.js'); -const { Channel, message } = require('../messages/message.js'); -const Embed = require('../messages/embed.js'); +import axios from 'axios'; +import author from '../messages/author.js'; +import { Channel, message } from '../messages/message.js'; +import {Embed} from '../messages/embed.js'; -class Interaction { +export class Interaction { /** @type {author} */ user; @@ -177,7 +177,4 @@ class Interaction { } } } -} - - -module.exports = Interaction; \ No newline at end of file +} \ No newline at end of file diff --git a/structures/media/photoEncoder.js b/structures/media/photoEncoder.js new file mode 100644 index 0000000..4f9a4ef --- /dev/null +++ b/structures/media/photoEncoder.js @@ -0,0 +1 @@ +// see https://discord.com/developers/docs/reference#image-data diff --git a/structures/messages/author.js b/structures/messages/author.js index 6f3af77..8cba8ea 100644 --- a/structures/messages/author.js +++ b/structures/messages/author.js @@ -1,4 +1,4 @@ -class msgAuthor { +export default class msgAuthor { /** @type {String} */ id; @@ -30,8 +30,4 @@ class msgAuthor { } } } -} - - - -module.exports = msgAuthor; \ No newline at end of file +} \ No newline at end of file diff --git a/structures/messages/embed.js b/structures/messages/embed.js index 4f81961..6fada99 100644 --- a/structures/messages/embed.js +++ b/structures/messages/embed.js @@ -1,6 +1,6 @@ -const colConvert = require('../../utils/color_functions.js'); +import colConvert from '../../utils/color_functions.js'; -class Embed { +export class Embed { /** @type {Number} */ color; @@ -122,6 +122,4 @@ class Embed { return retObj; } //#endregion -} - -module.exports = Embed; \ No newline at end of file +} \ No newline at end of file diff --git a/structures/messages/message.js b/structures/messages/message.js index e230153..6cd64f0 100644 --- a/structures/messages/message.js +++ b/structures/messages/message.js @@ -1,19 +1,68 @@ -const messageChannelTypes = require('./messageChannelTypes.js'); -const author = require('./author.js'); -const axios = require('axios'); -const Embed = require('./embed'); +import author from './author.js'; +import axios from 'axios'; -class Channel { +export class Channel { /** @type {String} */ id; + /** @type {String} */ + name; + + /** @type {String} */ + last_message_id; + + /** @type {Number} */ + type; + + /** @type {Number} */ + position; + + /** @type {Number} */ + flags; + + /** @type {String} */ + parent_id; + + /** @type {import('../guilds/Guild.js').def} */ + guild; + + /** @type {[{id: String, type: String, allow: Number, deny: Number, allow_new: String, deny_nwe: String}]} */ + permission_overwrites; + + /** @type {Number} */ + rate_limit_per_user; + + /** @type {Boolean} */ + nsfw; + /** @type {String} */ #token; - constructor(token, id) { + + async getChannelData() { + const headers = { + Authorization: this.#token + } + + const response = await axios.get(`https://discord.com/api/channels/${this.id}`, { headers }); + const channelData = response.data; + + for (const k in this) { + if (channelData[k]) { + this[k] = channelData[k]; + } + } + } + + + constructor(token, channel, guild) { this.#token = token; - this.id = id; + for (const k in this) { + if (channel[k]) this[k] = channel[k]; + } + + this.guild = guild; } /** @@ -49,11 +98,11 @@ class Channel { } -class message { +export class message { /** @type {author} */ author; - /** @type {Object} */ + /** @type {String} */ channel_id; /** @type {Object[]} */ @@ -89,6 +138,9 @@ class message { /** @type {Object[]} */ embeds; + /** @type {Guild} */ + guild; + /** @type {String} */ guild_id; @@ -96,7 +148,7 @@ class message { type; /** @type {Channel} */ - channel + channel; /** @type {String} */ #token; @@ -167,7 +219,7 @@ class message { /** * @param {Object} msgRaw */ - constructor(msgRaw, token) { + constructor(msgRaw, token, guild) { this.#token = token; for (const k in this) { @@ -180,7 +232,7 @@ class message { } else { if (k == 'channel_id') { - this.channel = new Channel(this.#token, msgRaw[k]); + this.channel = new Channel(this.#token, {id: msgRaw[k]}, null); } this[k] = msgRaw[k]; @@ -191,4 +243,4 @@ class message { } -module.exports = { message, messageChannelTypes, Channel }; \ No newline at end of file +export {messageChannelTypes} from './messageChannelTypes.js'; \ No newline at end of file diff --git a/structures/messages/messageChannelTypes.js b/structures/messages/messageChannelTypes.js index 1e140ea..f571b3e 100644 --- a/structures/messages/messageChannelTypes.js +++ b/structures/messages/messageChannelTypes.js @@ -1,7 +1,7 @@ //Blatantly stolen from https://github.com/discordjs/discord-api-types/blob/main/gateway/v10.ts -module.exports = Object.freeze({ +export const messageChannelTypes = Object.freeze({ /** * A text channel within a guild */ diff --git a/structures/types.js b/structures/types.js index 32d037c..839cd81 100644 --- a/structures/types.js +++ b/structures/types.js @@ -1,8 +1,5 @@ -const {message} = require('./messages/message'); -const {Client, gateWayIntents} = require('./client/client.js'); -const Embed = require('./messages/embed'); -const messageChannelTypes = require('./messages/messageChannelTypes'); -const Interaction = require('./interactions/interaction.js'); - - -module.exports = { message, Client, gateWayIntents, Embed, messageChannelTypes, Interaction } \ No newline at end of file +export {message} from './messages/message.js'; +export {Client, gateWayIntents} from './client/client.js'; +export {Embed} from './messages/embed.js'; +export {messageChannelTypes} from './messages/messageChannelTypes.js'; +export {Interaction} from './interactions/interaction.js'; \ No newline at end of file diff --git a/tests/guildTests.js b/tests/guildTests.js index 1f20ef7..4310320 100644 --- a/tests/guildTests.js +++ b/tests/guildTests.js @@ -1,9 +1,43 @@ -const Guild = require("../structures/guilds/guild"); -const { Client } = require("../structures/types"); +import Guild from "../structures/guilds/Guild.js"; +import { guildRole, newGuildRoleObj } from "../structures/guilds/guildRoles.js"; +import { Client } from "../structures/types.js"; const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); -module.exports = /** @param {Client} c */ async (c) => { - c.guilds.forEach(/** @param {Guild} guild */ (guild) => { - console.log(guild); +/** @param {Client} c */ +export default async function temp(c) { + // c.guilds.forEach(/** @param {Guild} guild */ (guild) => { + // console.log(guild); + // }); + + const guild = c.guilds.get("930148608400035860"); + const member = guild.members.get("720349017829015633"); + console.log(member.roles.cache); + + if (!member.roles.has('946610800418762792')) { + const response = await member.roles.add('946610800418762792'); + // console.log(response); + } + + const newRole = new newGuildRoleObj({ + name: 'newrole' }); + + if (!guild.roles.findByName(newRole.name)) { + const response2 = await guild.roles.create(newRole); + // console.log(response2); + await delay(2000); + + const response3 = await guild.roles.delete(response); + // console.log(response3); + } + + const invites = await guild.getInvites(); + await delay(1000); + + //Delete any invite that's gonna expire + for (const invite of invites) { + if (invite.max_age != 0) { + console.log(await invite.delete()); + } + } } \ No newline at end of file diff --git a/tests/interactionTests.js b/tests/interactionTests.js index bf7e9fb..063c917 100644 --- a/tests/interactionTests.js +++ b/tests/interactionTests.js @@ -1,7 +1,8 @@ -const { Interaction } = require('../structures/types'); +import { Interaction } from '../structures/types.js'; const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); -module.exports = /** @param {Interaction} interaction */ async (interaction) => { +/** @param {Interaction} interaction */ +export default async (interaction) => { interaction.reply({content: "HELLO WORLD", ephemeral: true}); await delay(3000); interaction.update({content: "NOOOOOOOOOOOOOOOOOO"}); diff --git a/tests/messageTests.js b/tests/messageTests.js index acb65b8..a0ce796 100644 --- a/tests/messageTests.js +++ b/tests/messageTests.js @@ -1,7 +1,9 @@ const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); -const {message, Embed, messageChannelTypes} = require('../structures/types'); +import {message, Embed, messageChannelTypes} from '../structures/types.js'; -module.exports = /** @param {message} message */ async (message) => { + +/** @param {message} message */ +export default async (message) => { if (message.type == messageChannelTypes.DM) { const embd = new Embed() .setTitle("hello world") @@ -17,5 +19,7 @@ module.exports = /** @param {message} message */ async (message) => { const response3 = await response.edit("KAT"); console.log(response3); + } else { + console.log(message); } } \ No newline at end of file diff --git a/tests/test.js b/tests/test.js index 448f09b..d57bcc8 100644 --- a/tests/test.js +++ b/tests/test.js @@ -1,6 +1,6 @@ -const { Client, gateWayIntents, message, Interaction } = require('../structures/types'); -const { bottoken } = require('../config.json'); - +import { Client, gateWayIntents, message, Interaction } from '../structures/types.js'; +import config from '../config.json' assert { type: 'json' }; +const { bottoken } = config; var c = new Client({ intents: [ @@ -23,17 +23,17 @@ c.login(bottoken); c.on('messageRecieved', /**@param {message} message*/ async (message) => { - require('./messageTests.js')(message); + (await import('./messageTests.js')).default(message); }); c.on('interactionRecieved', /** @param {Interaction} interaction*/ async (interaction) => { - require('./interactionTests.js')(interaction); + (await import('./interactionTests.js')).default(interaction); }); c.on('guildCreate', async (guild) => { - require('./guildTests.js')(c); + (await import('./guildTests.js')).default(c); }); diff --git a/utils/color_functions.js b/utils/color_functions.js index 54532f8..4f39eff 100644 --- a/utils/color_functions.js +++ b/utils/color_functions.js @@ -1,11 +1,11 @@ -const Colors = require('./colors.js'); +import Colors from './colors.js'; /** * Resolves a ColorResolvable into a color number. * @param {String} color Color to resolve * @returns {Number} A color */ -function resolveColor(color) { +export default function resolveColor(color) { if (typeof color === 'string') { if (color === 'Random') return Math.floor(Math.random() * (0xffffff + 1)); if (color === 'Default') return 0; @@ -18,7 +18,4 @@ function resolveColor(color) { else if (Number.isNaN(color)) throw new TypeError('COLOR_CONVERT'); return color; -} - - -module.exports = resolveColor; \ No newline at end of file +} \ No newline at end of file diff --git a/utils/colors.js b/utils/colors.js index f5ab0a8..334701f 100644 --- a/utils/colors.js +++ b/utils/colors.js @@ -1,4 +1,4 @@ -module.exports = { +export default { Default: 0x000000, White: 0xffffff, Aqua: 0x1abc9c,