diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..9d23dd86 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use o IntelliSense para saber mais sobre os atributos possíveis. + // Focalizar para exibir as descrições dos atributos existentes. + // Para obter mais informações, acesse: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "bun", + "internalConsoleOptions": "neverOpen", + "request": "launch", + "name": "Debug core", + "program": "src/app.ts", + "cwd": "${workspaceFolder}/core", + "stopOnEntry": false, + "watchMode": false + } + ] +} \ No newline at end of file diff --git a/build/bun.ts b/build/bun.ts index df0527e1..bd2dd01d 100644 --- a/build/bun.ts +++ b/build/bun.ts @@ -14,9 +14,9 @@ await build('core') async function build (plugin: string) { const pkg = JSON.parse(await readFile(join(plugin, 'package.json'), { encoding: 'utf-8' })) - const appName = pkg.name + const appName = `${pkg.name}-${process.platform}-${process.arch}` execSync(`cd ${plugin} && bun build ./src/app.ts --target=bun --minify --compile --outfile=${appName}`, { stdio: 'inherit' }) - execSync(`cd ${plugin} && 7z a -m0=lzma2 -mx9 -sfx ${appName}-minify ${appName}`, { stdio: 'inherit' }) - execSync(`mv ${plugin}/${appName} release/ && mv ${plugin}/${appName}-minify release/`) + execSync(`cd ${plugin} && 7z a -m0=lzma2 -mx9 -sfx ${appName}-installer ${appName}`, { stdio: 'inherit' }) + execSync(`rm ${plugin}/${appName} && mv ${plugin}/${appName}-installer release/`) } \ No newline at end of file diff --git a/core/package.json b/core/package.json index a5952d55..a30df260 100644 --- a/core/package.json +++ b/core/package.json @@ -8,7 +8,7 @@ "scripts": { "start": "node .", "build": "tsc && tsc-alias", - "dev": "tsx src/app.ts", + "dev": "bun --inspect src/app.ts", "lint": "eslint -c eslint.config.js --fix" }, "author": { diff --git a/core/src/controller/auth.ts b/core/src/controller/auth.ts index 0055c439..482d62c6 100644 --- a/core/src/controller/auth.ts +++ b/core/src/controller/auth.ts @@ -52,7 +52,7 @@ export class Auth { throw new Error(i18('error.no_reply')) } - await crypt.write(JSON.stringify(response)) + await crypt.write(response) return response } diff --git a/core/src/controller/plugins.ts b/core/src/controller/plugins.ts index a997112d..cf0119b8 100644 --- a/core/src/controller/plugins.ts +++ b/core/src/controller/plugins.ts @@ -8,15 +8,13 @@ import { existsSync, watch } from 'fs' import { mkdir, readFile, writeFile } from 'fs/promises' import { glob } from 'glob' import { isBinaryFile } from 'isbinaryfile' -import { basename, dirname, join } from 'path' +import { basename, join } from 'path' import { cwd } from 'process' import { Socket } from 'socket.io' import { BaseEntity } from 'typeorm' -import { fileURLToPath } from 'url' import { Config, ConfigOptions } from './config.js' import { Database, EntityImport } from './database.js' -const __dirname = dirname(fileURLToPath(import.meta.url)) const cacheWatcher = new Map() interface Metadata { name: string @@ -130,7 +128,7 @@ export class Plugins { async validate (filePath: string): Promise { const binary = await readFile(filePath) - const publicKey = await readFile(join(__dirname, '../../public_key.pem'), 'utf8') + const publicKey = await readFile(join(process.cwd(), 'publicKey.pem'), 'utf8') const data = binary.subarray(0, binary.length - 512) const signature = binary.subarray(binary.length - 512) @@ -306,6 +304,7 @@ export class Plugins { await writeFile(`${path}/${fileName}`, code, { encoding: 'utf-8' }) const pluginIndex = Plugins.running.findIndex((plugin) => plugin.id === socket.id) + if (pluginIndex !== -1) { Plugins.running[pluginIndex].entries.push(`${path}/${fileName}`) } else { diff --git a/core/src/register.ts b/core/src/register.ts index f99dc967..06e11665 100644 --- a/core/src/register.ts +++ b/core/src/register.ts @@ -3,4 +3,4 @@ import 'src/discord/commands/lang.js' import * as ptBR from 'locales/pt-BR/translation.json' assert { type: 'json' } import * as en from 'locales/en/translation.json' assert { type: 'json' } -export const languages: Record = { 'pt-br': ptBR.default, en: en.default } \ No newline at end of file +export const languages: Record = { 'pt-BR': ptBR.default, en: en.default } \ No newline at end of file diff --git a/locales/en/translation.json b/locales/en/translation.json new file mode 100644 index 00000000..76bb21ef --- /dev/null +++ b/locales/en/translation.json @@ -0,0 +1,81 @@ +{ + "discord": { + "start": "📌 Starting Discord", + "create": "💡 Creating the Discord client", + "close": "💥 Destroying connection with Discord", + "connected": "📡 Connected with {{botName}}", + "isConnected": "⛔ Sorry, but I'm already connected to Discord!", + "commands": "📝 {{length}} Commands successfully defined!", + "token_send": "⚠️ Token{{isEncrypted}} being sent to: {{pluginId}}", + "token_not_found": "❌ Discord token is empty!" + }, + "plugins": { + "new": "✨ New plugin added!", + "starting": "✅ Starting Plugin {{name}}", + "disconnect": "🔌 Plugin Disconnected: {{name}}", + "commands": "🤖 Commands: {{length}}", + "components": "🧩 Components: {{length}}", + "events": "🎉 Events: {{length}}", + "configs": "⚙️ Configs: {{length}}", + "crons": "🕑 Crons: {{length}}", + "entry_load": "⏳ Loading entry: {{name}}", + "hasLoaded": "⚠️ Attention: Plugin added after the first registration, it may be necessary to remove the bot and add it again to the server!", + "devlop": "🚨 Development mode", + "last_plugin": "🚩 Last plugin loaded ({{current}}/{{total}})", + "invalid": "❌ Valid Plugin!", + "duplicate": "❌ Plugin {{name}} is duplicated!", + "invalid_file": "❌ Invalid file: {{fileName}}", + "invalid_signature": "❌ Signature verification failed: {{fileName}}", + "reject": "❌ The Plugin {{filePath}} exited with error code {{code}} and signal {{signal}}" + }, + "crypt": { + "question": "How would you like to protect your local information?", + "generate_title": "Generate random password", + "generate_description": "It will be used to encrypt your information", + "define_title": "Define password", + "define_description": "It will be used to encrypt your information", + "your_password": "🔐 Your Password:", + "weak_password": "Password too weak! (1 Uppercase letter, 1 Lowercase letter, 1 Number, 1 Special character)", + "file_change": "⚠️ A change was detected in a protected file!", + "delete_file": "🗑️ Deleting encrypted files!", + "sensitive_information": "⚠️ Sensitive information being read" + }, + "license": { + "accept": "❓ Do you agree with the terms presented above?" + }, + "authenticate": { + "registered": "📝 Registered at:", + "hello": "👋 Hello {{name}}", + "change_token": "🔄 Change Token", + "try_again": "🔁 Try Again", + "logout": "↪️ Logout" + }, + "websocket": { + "initialized": "🚀 Server initialized on port {{port}}" + }, + "database": { + "starting": "🗂️ Starting Database", + "initialized": "✨ Database initialized with {{length}} entries", + "invalid_entity": "⛔ {{tableName}} Invalid entity, loaded entities:" + }, + "error": { + "unstable": "🔴 {{element}} unstable", + "no_found": "🚫 No {{name}} found", + "not_exist": "❌ {{name}} does not exist!", + "not_select": "❌ No option selected!", + "no_possible": "❌ It is not possible to continue!", + "undefined": "❌ {{element}} undefined!", + "invalid": "❌ {{element}} invalid!", + "no_reply": "❌ Form not replied!", + "expired": "❌ {{element}} expired!", + "disabled": "❌ {{element}} disabled!", + "an_error_occurred": "❌ An error occurred:", + "timeout": "⏳ Timeout of {{time}} seconds... trying after the timeout" + }, + "commands": { + "lang": { + "sucess": "✅ Language changed successfully!", + "error": "❌ Unable to change the bot's language!" + } + } +} \ No newline at end of file diff --git a/locales/pt-BR/translation.json b/locales/pt-BR/translation.json new file mode 100644 index 00000000..3ec7f5b1 --- /dev/null +++ b/locales/pt-BR/translation.json @@ -0,0 +1,81 @@ +{ + "discord": { + "start": "📌 Iniciando Discord", + "create": "💡 Criando o client do Discord", + "close": "💥 Destruindo conexão com o Discord", + "connected": "📡 Connected with {{botName}}", + "isConnected": "⛔ Desculpe, mas já estou conectado ao Discord!", + "commands": "📝 {{length}} Comandos definidos com sucesso!", + "token_send": "⚠️ Token{{isEncrypted}} sendo enviado para: {{pluginId}}", + "token_not_found": "❌ Token do Discord está vazio!" + }, + "plugins": { + "new": "✨ Novo plugin adicionado!", + "starting": "✅ Iniciando Plugin {{name}}", + "disconnect": "🔌 Plugin Desconectado: {{name}}", + "commands": "🤖 Commands: {{length}}", + "components": "🧩 Components: {{length}}", + "events": "🎉 Events: {{length}}", + "configs": "⚙️ Configs: {{length}}", + "crons": "🕑 Crons: {{length}}", + "entry_load": "⏳ Carregando entry: {{name}}", + "hasLoaded": "⚠️ Atenção: Plugin adicionado após o primeiro registro, talvez seja necessário expulsar o bot, e adicioná-lo novamente ao servidor!", + "devlop": "🚨 Modo de desenvolvimento", + "last_plugin": "🚩 Último plugin carregado ({{current}}/{{total}})", + "invalid": "❌ Plugin Valido!", + "duplicate": "❌ Plugin {{name}} está duplicado!", + "invalid_file": "❌ Arquivo invalido: {{fileName}}", + "invalid_signature": "❌ Falha na verificação da assinatura: {{fileName}}", + "reject": "❌ O Plugin {{filePath}} saiu com código de erro {{code}} e sinal {{signal}}" + }, + "crypt": { + "question": "Como deseja proteger suas informações locais?", + "generate_title": "Gerar senha aleatória", + "generate_description": "Será usada para criptografar suas informações", + "define_title": "Definir senha", + "define_description": "Será usada para criptografar suas informações", + "your_password": "🔐 Sua Senha:", + "weak_password": "Senha muito fraca! (1 Letra maiúscula, 1 Letra Minuscula, 1 Numero, 1 Carácter especial)", + "file_change": "⚠️ Foi detectado uma mudança em um arquivo protegido!", + "delete_file": "🗑️ Deletando arquivos encriptados!", + "sensitive_information": "⚠️ Informações sensíveis sendo lidas" + }, + "license": { + "accept": "❓ Você concorda com os termos apresentados acima?" + }, + "authenticate": { + "registered": "📝 Cadastrado em:", + "hello": "👋 Olá {{name}}", + "change_token": "🔄 Mudar Token", + "try_again": "🔁 Tentar Novamente", + "logout": "↪️ Deslogar" + }, + "websocket": { + "initialized": "🚀 Servidor inicializado na porta {{port}}" + }, + "database": { + "starting": "🗂️ Iniciando Banco de dados", + "initialized": "✨ Banco de dados inicializado com {{length}} entries", + "invalid_entity": "⛔ {{tableName}} Entidade invalida, Entidades carregadas:" + }, + "error": { + "unstable": "🔴 {{element}} instável", + "no_found": "🚫 Nenhum {{name}} encontrado", + "not_exist": "❌ {{name}} não existe!", + "not_select": "❌ Nenhuma opção selecionada!", + "no_possible": "❌ Não é possivel continuar!", + "undefined": "❌ {{element}} indefinido!", + "invalid": "❌ {{element}} invalido!", + "no_reply": "❌ Formulário não respondido!", + "expired": "❌ {{element}} expired!", + "disabled": "❌ {{element}} disabled!", + "an_error_occurred": "❌ Ocorreu um erro:", + "timeout": "⏳ Timeout de {{time}} segundos... tentando após o timeout" + }, + "commands": { + "lang": { + "sucess": "✅ Linguagem alterado com sucesso!", + "error": "❌ Não foi possivel alterar a linguagem do bot!" + } + } +} \ No newline at end of file diff --git a/packages/discord/src/class/Client.ts b/packages/discord/src/class/Client.ts index 6b1abe09..59d38d40 100644 --- a/packages/discord/src/class/Client.ts +++ b/packages/discord/src/class/Client.ts @@ -17,15 +17,18 @@ export class Discord { constructor () {} public static async register () { - const dir = join(__plugin_dirname, 'src') + const dir = join(__plugin_dirname, 'src/discord') const paths = await glob([ 'commands/**/*.{ts,js}', 'events/**/*.{ts,js}', 'components/**/*.{ts,js}', 'configs/**/*.{ts,js}' ], { cwd: dir }) + + console.log(__plugin_dirname) for (const path of paths) { + console.log(path) await import (join(dir, path)) } } diff --git a/packages/discord/src/class/CustomIntetaction.ts b/packages/discord/src/class/CustomIntetaction.ts index 720397bb..24394917 100644 --- a/packages/discord/src/class/CustomIntetaction.ts +++ b/packages/discord/src/class/CustomIntetaction.ts @@ -78,7 +78,7 @@ export class YouSure { this.title = title } - async question () { + async question (): Promise { const embed = new EmbedBuilder({ title: this.title ?? 'Tem certeza que deseja fazer isso?' }).setColor('Orange') const buttons = ActionDrawer([ new Button({ customId: 'confirm-button', label: 'Confirmar', style: ButtonStyle.Success }), @@ -89,25 +89,28 @@ export class YouSure { : await this.interaction.reply({ embeds: [embed], components: buttons }) const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, maxUsers: 1 }) - collector.once('collect', async (subInteraction) => { - switch (subInteraction.customId) { - case 'confirm-button': { - return true - } - case 'cancel-button': { - if (subInteraction.isRepliable()) { - const embed = new EmbedBuilder({ - title: 'Ação cancelada!' - }).setColor('Red') - await subInteraction.update({ embeds: [embed], components: [] }).catch(async () => { - if (subInteraction.deferred) { await this.interaction.editReply({ embeds: [embed], components: [] }); return } - await this.interaction.reply({ ephemeral: true, embeds: [embed], components: [] }) - }) - setTimeout(async () => await subInteraction.deleteReply().catch(() => undefined), 5000) + return new Promise((resolve) => { + collector.once('collect', async (subInteraction) => { + switch (subInteraction.customId) { + case 'confirm-button': { + resolve(true) + break } - return false - } - } + case 'cancel-button': { + if (subInteraction.isRepliable()) { + const embed = new EmbedBuilder({ + title: 'Ação cancelada!' + }).setColor('Red') + await subInteraction.update({ embeds: [embed], components: [] }).catch(async () => { + if (subInteraction.deferred) { await this.interaction.editReply({ embeds: [embed], components: [] }); return } + await this.interaction.reply({ ephemeral: true, embeds: [embed], components: [] }) + }) + setTimeout(async () => await subInteraction.deleteReply().catch(() => undefined), 5000) + } + resolve(false) + } + } + }) }) } } \ No newline at end of file diff --git a/plugins/tickets/package.json b/plugins/tickets/package.json index 8a389751..ed56a894 100644 --- a/plugins/tickets/package.json +++ b/plugins/tickets/package.json @@ -1,9 +1,9 @@ { "name": "plugin-ticket", - "module": "src/index.ts", + "module": "src/app.ts", "type": "module", "scripts": { - "dev": "bun run src/index.ts", + "dev": "bun run src/app.ts", "lint": "eslint -c eslint.config.js --fix" }, "dependencies": { diff --git a/plugins/tickets/src/discord/commands/ticket.ts b/plugins/tickets/src/discord/commands/ticket.ts index fc199165..d2ec5058 100644 --- a/plugins/tickets/src/discord/commands/ticket.ts +++ b/plugins/tickets/src/discord/commands/ticket.ts @@ -1,6 +1,8 @@ +import { Template } from '@/class/Template' +import { TemplateBuilder } from '@/class/TemplateBuilder' import TemplateTable from '@/entity/Template.entry.js' import { templateDB } from '@/utils/database' -import { Command } from 'discord' +import { Command, Error } from 'discord' import { type ApplicationCommandOptionChoiceData, ApplicationCommandOptionType, ApplicationCommandType, Colors, EmbedBuilder, PermissionFlagsBits } from 'discord.js' import { Database } from 'socket-client' @@ -15,7 +17,24 @@ new Command({ options: [ { name: 'template', - description: 'Editar Template', + description: 'Criar template', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'title_create', + description: 'Título do template', + type: ApplicationCommandOptionType.String, + }, + { + name: 'description_create', + description: 'Descrição do template', + type: ApplicationCommandOptionType.String, + }, + ] + }, + { + name: 'change', + description: '🔄 Editar Template', type: ApplicationCommandOptionType.Subcommand, options: [ { @@ -211,7 +230,7 @@ new Command({ }, async run(interaction) { await interaction.deferReply({ ephemeral: true }) - const { options } = interaction + const { options, channelId } = interaction if (options.getSubcommandGroup() !== null) { switch (options.getSubcommandGroup()) { @@ -239,9 +258,9 @@ new Command({ case 'rem': { const title = options.getString('category', true) const templateId = options.getString('message_id', true) - const templateData = await templateDB.findOne({ where: { messageId: templateId } }) if (templateData === null) throw await new Error({ element: 'template', interaction }).notFound({ type: 'Database' }).reply() + templateData.categories = templateData?.categories.filter((category) => category.title !== title) await new TemplateBuilder({ interaction }).setData(templateData).edit({ messageId: templateId }).then(async () => { @@ -260,8 +279,24 @@ new Command({ } else { switch (options.getSubcommand()) { case 'template': { - const builder = new TemplateBuilder({ interaction }) + if (!interaction.inCachedGuild()) throw await new Error({ element: 'a ação não foi realizada dentro de um servidor', interaction }).notPossible().reply() + const sendChannel = await interaction.guild.channels.fetch(channelId) + if (!sendChannel?.isTextBased()) throw await new Error({ element: 'concluir a ação, pois o channel não é um TextBased', interaction }).notPossible().reply() + const template = new Template({ interaction }) + const title = options.getString('title_create') + const description = options.getString('description_create') + + if (sendChannel !== undefined) template.create({ + title: title ?? 'Pedir suporte', + description: description ?? 'Se você estiver precisando de ajuda clique no botão abaixo', + channelId: sendChannel.id, + guildId: interaction.guildId + }).then(async () => await interaction.deleteReply()) + break + } + case 'change': { + const builder = new TemplateBuilder({ interaction }) const templateId = options.getString('message_id', true) const switchMode = options.getString('mode') const title = options.getString('title') diff --git a/plugins/tickets/src/discord/components/Claim/ButtonClaim.ts b/plugins/tickets/src/discord/components/Claim/ButtonClaim.ts index ab6e4b24..a4e2f376 100644 --- a/plugins/tickets/src/discord/components/Claim/ButtonClaim.ts +++ b/plugins/tickets/src/discord/components/Claim/ButtonClaim.ts @@ -4,7 +4,6 @@ import { Component, Error } from 'discord' import { EmbedBuilder } from 'discord.js' import { buttonRedirect } from 'utils' - new Component({ customId: 'Claim', type: 'Button', @@ -14,7 +13,9 @@ new Component({ const { message, user, guildId, guild, channel } = interaction const claimData = await claimDB.findOne({ where: { messageId: message.id }, relations: { ticket: true } }) + if (claimData === undefined || claimData?.ticket === undefined) return await new Error({ element: 'Claim', interaction }).notFound({ type: 'Database' }).reply() + const userTicket = await guild.client.users.fetch(claimData.ticket.ownerId).catch(() => undefined) if (userTicket === undefined) { diff --git a/plugins/tickets/src/discord/components/Claim/ButtonDel.ts b/plugins/tickets/src/discord/components/Claim/ButtonDel.ts index 3cc49f6d..def52240 100644 --- a/plugins/tickets/src/discord/components/Claim/ButtonDel.ts +++ b/plugins/tickets/src/discord/components/Claim/ButtonDel.ts @@ -1,8 +1,6 @@ import { TicketBuilder } from '@/class/TicketBuilder.js' -import { Component } from '@/discord/base/Components.js' -import { YouSure } from '@/discord/base/CustomIntetaction.js' -import { Error } from '@/discord/base/CustomResponse.js' -import { claimDB } from '@/functions/database.js' +import { Component, YouSure, Error } from 'discord' +import { claimDB } from '@/utils/database' new Component({ customId: 'Delete', diff --git a/plugins/tickets/src/discord/components/Claim/ButtonTranscript.ts b/plugins/tickets/src/discord/components/Claim/ButtonTranscript.ts index 29285426..9061cc8e 100644 --- a/plugins/tickets/src/discord/components/Claim/ButtonTranscript.ts +++ b/plugins/tickets/src/discord/components/Claim/ButtonTranscript.ts @@ -1,11 +1,12 @@ import { Ticket } from '@/class/Ticket.js' -import { Component } from '@/discord/base/Components.js' +import { Component } from 'discord' new Component({ customId: 'Transcript', type: 'Button', async run(interaction) { if (!interaction.inCachedGuild()) return + await interaction.deferReply({ ephemeral: true }) await new Ticket({ interaction }).transcript({ messageId: interaction.message.id }) } diff --git a/plugins/tickets/src/discord/components/Template/AddSelectActions.ts b/plugins/tickets/src/discord/components/Template/AddSelectActions.ts index a9e72642..397a2ad2 100644 --- a/plugins/tickets/src/discord/components/Template/AddSelectActions.ts +++ b/plugins/tickets/src/discord/components/Template/AddSelectActions.ts @@ -1,9 +1,8 @@ import { TemplateButtonBuilder } from '@/class/TemplateButtonBuilder.js' -import { Database } from '@/controller/database.js' -import { Component } from '@/discord/base/index.js' -import { ModalBuilder } from '@/discord/base/CustomIntetaction.js' +import { Database } from 'socket-client' +import { Component, ModalBuilder } from 'discord' import TemplateTable from '@/entity/Template.entry.js' -import { ActionRowBuilder, APITextInputComponent, ComponentType, EmbedBuilder, TextInputBuilder } from 'discord.js' +import { ActionRowBuilder, type APITextInputComponent, ComponentType, EmbedBuilder, TextInputBuilder } from 'discord.js' const templateDb = new Database({ table: 'Template' }) const notFound = new EmbedBuilder({ @@ -107,7 +106,7 @@ new Component({ .setProperties(templateData.properties) .setSelects(templateData.selects) .setType(templateData.type) - .setSystem(templateData.systems) + .setSystem(templateData.systems ?? []) .render() await interaction.message?.edit({ components }) diff --git a/plugins/tickets/src/discord/components/Template/ButtonCategory.ts b/plugins/tickets/src/discord/components/Template/ButtonCategory.ts index 5cee069a..a5ef5da5 100644 --- a/plugins/tickets/src/discord/components/Template/ButtonCategory.ts +++ b/plugins/tickets/src/discord/components/Template/ButtonCategory.ts @@ -1,4 +1,4 @@ -import { Component } from '@/discord/base/Components.js' +import { Component } from 'discord' import { EmbedBuilder } from 'discord.js' new Component({ diff --git a/plugins/tickets/src/discord/components/Template/ButtonConfig.ts b/plugins/tickets/src/discord/components/Template/ButtonConfig.ts index cb81173b..4d4f7cd0 100644 --- a/plugins/tickets/src/discord/components/Template/ButtonConfig.ts +++ b/plugins/tickets/src/discord/components/Template/ButtonConfig.ts @@ -1,5 +1,5 @@ import { TemplateBuilder } from '@/class/TemplateBuilder.js' -import { Component } from '@/discord/base/index.js' +import { Component } from 'discord' new Component({ customId: 'Config', diff --git a/plugins/tickets/src/discord/components/Template/ButtonDelete.ts b/plugins/tickets/src/discord/components/Template/ButtonDelete.ts index 19c6049b..bc3781fe 100644 --- a/plugins/tickets/src/discord/components/Template/ButtonDelete.ts +++ b/plugins/tickets/src/discord/components/Template/ButtonDelete.ts @@ -1,6 +1,6 @@ import { TemplateBuilder } from '@/class/TemplateBuilder.js' -import { Component } from '@/discord/base/index.js' -import { ActionDrawer } from '@/functions/actionDrawer.js' +import { Component } from 'discord' +import { ActionDrawer } from 'utils' import { ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder } from 'discord.js' new Component({ diff --git a/plugins/tickets/src/discord/components/Template/ButtonSave.ts b/plugins/tickets/src/discord/components/Template/ButtonSave.ts index b2716e15..9d37254f 100644 --- a/plugins/tickets/src/discord/components/Template/ButtonSave.ts +++ b/plugins/tickets/src/discord/components/Template/ButtonSave.ts @@ -1,5 +1,5 @@ import { TemplateBuilder } from '@/class/TemplateBuilder.js' -import { Component } from '@/discord/base/index.js' +import { Component } from 'discord' new Component({ customId: 'Save', diff --git a/plugins/tickets/src/discord/components/Template/ButtonsSetType.ts b/plugins/tickets/src/discord/components/Template/ButtonsSetType.ts index 02d91923..21b79732 100644 --- a/plugins/tickets/src/discord/components/Template/ButtonsSetType.ts +++ b/plugins/tickets/src/discord/components/Template/ButtonsSetType.ts @@ -1,6 +1,6 @@ import { TemplateButtonBuilder } from '@/class/TemplateButtonBuilder.js' -import { Database } from '@/controller/database.js' -import { Component } from '@/discord/base/index.js' +import { Database } from 'socket-client' +import { Component } from 'discord' import TemplateTable, { TypeTemplate } from '@/entity/Template.entry.js' import { EmbedBuilder } from 'discord.js' @@ -36,7 +36,7 @@ for (const [action, type] of Object.entries(actions)) { .setMode('debug') .setProperties(templateData.properties) .setSelects(templateData.selects) - .setSystem(templateData.systems) + .setSystem(templateData.systems ?? []) .setType(type) .render() diff --git a/plugins/tickets/src/discord/components/Template/EditTicket.ts b/plugins/tickets/src/discord/components/Template/EditTicket.ts index ce17f7e9..6ded9648 100644 --- a/plugins/tickets/src/discord/components/Template/EditTicket.ts +++ b/plugins/tickets/src/discord/components/Template/EditTicket.ts @@ -165,7 +165,7 @@ for (const [action, data] of Object.entries(modalData)) { .setProperties(templateData.properties) .setSelects(templateData.selects) .setType(templateData.type) - .setSystem(templateData.systems) + .setSystem(templateData.systems ?? []) .render() interaction.message?.edit({ embeds: [embed], components }) diff --git a/plugins/tickets/src/discord/components/Template/OpenActions.ts b/plugins/tickets/src/discord/components/Template/OpenActions.ts index 41be7a57..b647f4a7 100644 --- a/plugins/tickets/src/discord/components/Template/OpenActions.ts +++ b/plugins/tickets/src/discord/components/Template/OpenActions.ts @@ -23,7 +23,8 @@ new Component({ const templateData = await templateDB.findOne({ where: { messageId: message.id } }) if (templateData === null) throw await new Error({ element: 'template', interaction }).notFound({ type: 'Database' }).reply() - const moreDetails = templateData.systems.find((system) => system.name === 'MoreDetails')?.isEnabled + + const moreDetails = (templateData.systems ?? []).find((system) => system.name === 'MoreDetails')?.isEnabled if ((templateData.categories ?? []).length > 0) { await interaction.deferReply({ ephemeral: true }) @@ -200,7 +201,7 @@ new Component({ const typeTicket = templateData?.selects[Number(select)] if (typeTicket === undefined) throw await new Error({ element: 'select', interaction }).notFound({ type: 'Database' }).reply() - const moreDetails = templateData.systems.find((system) => system.name === 'MoreDetails')?.isEnabled + const moreDetails = (templateData.systems ?? []).find((system) => system.name === 'MoreDetails')?.isEnabled if (moreDetails) { const modal = new ModalBuilder({ customId: 'MoreDetails', title: 'Conte-nos mais sobre o seu problema' }) const row = ActionDrawer([ diff --git a/plugins/tickets/src/discord/components/Ticket/ActionsClose.ts b/plugins/tickets/src/discord/components/Ticket/ActionsClose.ts index aece55c0..03d47ce8 100644 --- a/plugins/tickets/src/discord/components/Ticket/ActionsClose.ts +++ b/plugins/tickets/src/discord/components/Ticket/ActionsClose.ts @@ -1,8 +1,7 @@ import { TicketBuilder } from '@/class/TicketBuilder.js' -import { ModalBuilder } from '@/discord/base/CustomIntetaction.js' -import { Component } from '@/discord/base/index.js' -import { ActionDrawer } from '@/functions/actionDrawer.js' +import { ModalBuilder, Component } from 'discord' import { ButtonBuilder, ButtonStyle, ComponentType, EmbedBuilder, TextInputBuilder, TextInputStyle } from 'discord.js' +import { ActionDrawer } from 'utils' new Component({ customId: 'Close', @@ -50,7 +49,6 @@ new Component({ }).setColor('Red')] }) await new Promise((resolve) => setTimeout(() => resolve(), 5000)) - await (await ticketBuilder.setTicket(channelId).loader()).delete() } }) @@ -81,6 +79,7 @@ new Component({ placeholder: 'O player abriu ticket para informar que...' }) ], 1) + modal.setComponents(components) await interaction.showModal(modal) }, diff --git a/plugins/tickets/src/discord/components/Ticket/ButtonSwitch.ts b/plugins/tickets/src/discord/components/Ticket/ButtonSwitch.ts index 7f3c5a91..fb85edbd 100644 --- a/plugins/tickets/src/discord/components/Ticket/ButtonSwitch.ts +++ b/plugins/tickets/src/discord/components/Ticket/ButtonSwitch.ts @@ -1,9 +1,8 @@ import { ClaimBuilder } from '@/class/ClaimBuilder.js' import { TicketBuilder } from '@/class/TicketBuilder.js' -import { Error } from '@/discord/base/CustomResponse.js' -import { Component } from '@/discord/base/index.js' +import { Error, Component } from 'discord' import Ticket from '@/entity/Ticket.entry.js' -import { claimDB, ticketDB } from '@/functions/database.js' +import { claimDB, ticketDB } from '@/utils/database.js' import { EmbedBuilder } from 'discord.js' new Component({ diff --git a/plugins/tickets/src/discord/components/Ticket/Panel/ButtonPanel.ts b/plugins/tickets/src/discord/components/Ticket/Panel/ButtonPanel.ts index 5a6481d8..8637bc09 100644 --- a/plugins/tickets/src/discord/components/Ticket/Panel/ButtonPanel.ts +++ b/plugins/tickets/src/discord/components/Ticket/Panel/ButtonPanel.ts @@ -1,6 +1,5 @@ -import { StringSelectMenuBuilder } from '@/discord/base/CustomIntetaction.js' -import { Component } from '@/discord/base/index.js' -import { ActionRowBuilder, EmbedBuilder, SelectMenuComponentOptionData } from 'discord.js' +import { StringSelectMenuBuilder, Component } from 'discord' +import { ActionRowBuilder, EmbedBuilder, type SelectMenuComponentOptionData } from 'discord.js' new Component({ customId: 'Panel', diff --git a/plugins/tickets/src/discord/components/Ticket/Panel/SelectPanel.ts b/plugins/tickets/src/discord/components/Ticket/Panel/SelectPanel.ts index 4c922296..a95bbfde 100644 --- a/plugins/tickets/src/discord/components/Ticket/Panel/SelectPanel.ts +++ b/plugins/tickets/src/discord/components/Ticket/Panel/SelectPanel.ts @@ -1,6 +1,6 @@ import { Ticket } from '@/class/Ticket.js' import { TicketPanel } from '@/class/TicketPanel.js' -import { Component } from '@/discord/base/index.js' +import { Component } from 'discord' new Component({ customId: 'PanelSelect', diff --git a/plugins/tickets/src/discord/configs/config.ts b/plugins/tickets/src/discord/configs/config.ts index cd50070c..2d0adaa3 100644 --- a/plugins/tickets/src/discord/configs/config.ts +++ b/plugins/tickets/src/discord/configs/config.ts @@ -1,4 +1,3 @@ -import { Template } from '@/class/Template.js' import { configDB } from '@/utils/database' import { Config } from 'discord' import { type ApplicationCommandOptionChoiceData, ApplicationCommandOptionType, ChannelType, EmbedBuilder } from 'discord.js' @@ -8,13 +7,6 @@ new Config({ description: '[ 🎫 Ticket ] Configurar o sistema de Tickets', type: ApplicationCommandOptionType.Subcommand, options: [ - { - name: 'panel-embed', - description: '[ 🎫 Ticket ] Envia a embed de configuração.', - required: false, - type: ApplicationCommandOptionType.Channel, - channelTypes: [ChannelType.GuildText] - }, { name: 'limit', description: '[ 🎫 Ticket ] Limita a quantidade tickets por 24h.', @@ -87,14 +79,12 @@ new Config({ const { options, guildId, guild } = interaction if (guildId === null || guild == null) return await interaction.deferReply({ ephemeral: true }) - const channel = options.getChannel('panel-embed') const limit = options.getNumber('limit') const claimChannel = options.getChannel('claim-channel') const claimLimit = options.getNumber('claim-limit') const logs = options.getChannel('logs-channel') const addRole = options.getRole('add-role-team') const remRole = options.getString('rem-role-team') - const template = new Template({ interaction }) const dataDB = await configDB.findOne({ where: { guild: { guildId } }}) // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -132,26 +122,6 @@ new Config({ text.push(`Cargo ${remRole} removido dos tickets`) } - if (channel !== null) { - const sendChannel = await guild.channels.fetch(channel.id) - if (typeof sendChannel?.id !== 'string' || sendChannel?.isTextBased() !== true) { - await interaction.editReply({ - embeds: [ - new EmbedBuilder({ - title: 'O channel definido em panel-embed não é valido!' - }).setColor ('Red') - ] - }) - return - } - - if (sendChannel !== undefined) template.create({ - title: 'Pedir suporte', - description: 'Se você estiver precisando de ajuda clique no botão abaixo', - channelId: sendChannel.id, - guildId - }) - } if (limit !== null) { data = Object.assign(data, { limit }) text.push(`Limite de tickets por pessoa agora é de ${limit}!`) diff --git a/plugins/tickets/src/discord/events/joinGuild.ts b/plugins/tickets/src/discord/events/joinGuild.ts index 86a52221..c5de9526 100644 --- a/plugins/tickets/src/discord/events/joinGuild.ts +++ b/plugins/tickets/src/discord/events/joinGuild.ts @@ -1,6 +1,6 @@ -import { Event } from '@/discord/base/index.js' +import { Event } from 'discord' import Guild from '@/entity/Guild.entry.js' -import { configDB, guildDB } from '@/functions/database.js' +import { configDB, guildDB } from '@/utils/database' /** * Crie o registro no banco de dados caso ele seja associado a um guild novo diff --git a/plugins/tickets/src/discord/events/leaveVoiceChannel.ts b/plugins/tickets/src/discord/events/leaveVoiceChannel.ts index 71f2f178..48358778 100644 --- a/plugins/tickets/src/discord/events/leaveVoiceChannel.ts +++ b/plugins/tickets/src/discord/events/leaveVoiceChannel.ts @@ -1,6 +1,6 @@ -import { guildDB } from '@/functions/database.js' +import { guildDB } from '@/utils/database' import { TextChannel } from 'discord.js' -import { Event } from '../base/Event.js' +import { Event } from 'discord' /** * Caso a última pessoa se desconecte do channel voice do ticket: apague-o diff --git a/plugins/tickets/src/discord/events/messageCreate.ts b/plugins/tickets/src/discord/events/messageCreate.ts index 8eca9829..ad089dd5 100644 --- a/plugins/tickets/src/discord/events/messageCreate.ts +++ b/plugins/tickets/src/discord/events/messageCreate.ts @@ -1,8 +1,8 @@ import { TicketBuilder } from '@/class/TicketBuilder.js' -import { Database } from '@/controller/database.js' +import { Database } from 'socket-client' import Ticket from '@/entity/Ticket.entry.js' import { MessageFlagsBitField } from 'discord.js' -import { Event } from '../base/Event.js' +import { Event } from 'discord' const ticket = new Database({ table: 'Ticket' }) diff --git a/plugins/tickets/src/discord/events/messageDelete.ts b/plugins/tickets/src/discord/events/messageDelete.ts index 73ed6e23..ef4dd6b3 100644 --- a/plugins/tickets/src/discord/events/messageDelete.ts +++ b/plugins/tickets/src/discord/events/messageDelete.ts @@ -2,12 +2,12 @@ import { ClaimBuilder } from '@/class/ClaimBuilder.js' import { TemplateBuilder } from '@/class/TemplateBuilder.js' import { TemplateButtonBuilder } from '@/class/TemplateButtonBuilder.js' import { TicketBuilder } from '@/class/TicketBuilder.js' -import { Database } from '@/controller/database.js' +import { Database } from 'socket-client' import Claim from '@/entity/Claim.entry.js' import Ticket from '@/entity/Ticket.entry.js' -import { templateDB } from '@/functions/database.js' +import { templateDB } from '@/utils/database.js' import { AuditLogEvent, EmbedBuilder, Message, MessageFlagsBitField } from 'discord.js' -import { Event } from '../base/Event.js' +import { Event } from 'discord' const ticket = new Database({ table: 'Ticket' }) const claim = new Database({ table: 'Claim' }) diff --git a/plugins/tickets/src/entity/Claim.entry.ts b/plugins/tickets/src/entity/Claim.entry.ts index b559d147..307837eb 100644 --- a/plugins/tickets/src/entity/Claim.entry.ts +++ b/plugins/tickets/src/entity/Claim.entry.ts @@ -1,4 +1,4 @@ -import { BaseEntity, PrimaryGeneratedColumn, Column, OneToOne, Entity, Relation } from 'typeorm' +import { BaseEntity, PrimaryGeneratedColumn, Column, OneToOne, Entity, type Relation } from 'typeorm' import Ticket from './Ticket.entry.js' @Entity({ name: 'claim' }) diff --git a/plugins/tickets/src/entity/Config.entry.ts b/plugins/tickets/src/entity/Config.entry.ts index 14681463..f2307041 100644 --- a/plugins/tickets/src/entity/Config.entry.ts +++ b/plugins/tickets/src/entity/Config.entry.ts @@ -1,4 +1,4 @@ -import { BaseEntity, Column, Entity, OneToOne, PrimaryGeneratedColumn, Relation } from 'typeorm' +import { BaseEntity, Column, Entity, OneToOne, PrimaryGeneratedColumn, type Relation } from 'typeorm' import Guild from './Guild.entry.js' export interface Roles { diff --git a/plugins/tickets/src/entity/Guild.entry.ts b/plugins/tickets/src/entity/Guild.entry.ts index ef79bea5..fc4b383b 100644 --- a/plugins/tickets/src/entity/Guild.entry.ts +++ b/plugins/tickets/src/entity/Guild.entry.ts @@ -1,4 +1,4 @@ -import { BaseEntity, Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn, Relation } from 'typeorm' +import { BaseEntity, Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn, type Relation } from 'typeorm' import Config from './Config.entry.js' import Template from './Template.entry.js' import Ticket from './Ticket.entry.js' diff --git a/plugins/tickets/src/entity/Template.entry.ts b/plugins/tickets/src/entity/Template.entry.ts index 81215b25..dd6da19f 100644 --- a/plugins/tickets/src/entity/Template.entry.ts +++ b/plugins/tickets/src/entity/Template.entry.ts @@ -1,5 +1,5 @@ -import { APIEmbed } from 'discord.js' -import { BaseEntity, Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, Relation, UpdateDateColumn } from 'typeorm' +import { type APIEmbed } from 'discord.js' +import { BaseEntity, Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, type Relation, UpdateDateColumn } from 'typeorm' import Guild from './Guild.entry.js' import Ticket from './Ticket.entry.js' @@ -112,7 +112,7 @@ export default class Template extends BaseEntity { to(value: string): string { return JSON.stringify(value) }, } }) - systems!: System[] + systems!: System[] | null @CreateDateColumn() createAt!: Date diff --git a/plugins/tickets/src/entity/Ticket.entry.ts b/plugins/tickets/src/entity/Ticket.entry.ts index 4f776899..a765ffe9 100644 --- a/plugins/tickets/src/entity/Ticket.entry.ts +++ b/plugins/tickets/src/entity/Ticket.entry.ts @@ -1,4 +1,4 @@ -import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn, Relation, UpdateDateColumn } from 'typeorm' +import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn, type Relation, UpdateDateColumn } from 'typeorm' import Guild from './Guild.entry.js' import Claim from './Claim.entry.js' import Template from './Template.entry.js' @@ -95,7 +95,7 @@ export default class Ticket extends BaseEntity { @OneToOne(() => Claim, (claim) => claim.ticket) @JoinColumn() - claim!: Claim + claim!: Relation @Column({ type: 'simple-json', diff --git a/plugins/tickets/tsconfig.json b/plugins/tickets/tsconfig.json index 8745f4ae..a2a31137 100644 --- a/plugins/tickets/tsconfig.json +++ b/plugins/tickets/tsconfig.json @@ -24,6 +24,9 @@ "noUnusedParameters": false, "noPropertyAccessFromIndexSignature": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "rootDir": "./", "baseUrl": "./", "paths": {