diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2022-08-13 17:16:23 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2022-09-04 10:48:54 +0200 |
commit | 8769c7625cafd14e6f304601cc99a195e833d38b (patch) | |
tree | 94d37b1ef271490a032cde0605e1b1fb0fe01e0c | |
parent | Plugins finally load! (diff) | |
download | server-8769c7625cafd14e6f304601cc99a195e833d38b.tar.xz |
Fix config table, add plugin events, implement onPreMessageEvent, add
http error data field, migrations
47 files changed, 1746 insertions, 133 deletions
diff --git a/scripts/build.js b/scripts/build.js index 7421aa4f..704909ce 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -29,7 +29,7 @@ if (silent) console.error = console.log = function () {}; if (argv.includes("clean")) { console.log(`[${++i}/${steps}] Cleaning...`); - let d = "../" + "/dist"; + let d = "dist"; if (fs.existsSync(d)) { fs.rmSync(d, { recursive: true }); if (verbose) console.log(`Deleted ${d}!`); diff --git a/src/Server.ts b/src/Server.ts index e672bd0c..85de728f 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -8,6 +8,7 @@ import { Config, getOrInitialiseDatabase } from "@fosscord/util"; import * as Sentry from "@sentry/node"; import * as Tracing from "@sentry/tracing"; import { PluginLoader } from "@fosscord/util"; +import { PluginConfig } from "util/plugin/PluginConfig"; const app = express(); const server = http.createServer(); @@ -34,6 +35,7 @@ process.on("SIGTERM", () => { async function main() { await getOrInitialiseDatabase(); await Config.init(); + await PluginConfig.init(); //Sentry if (Config.get().sentry.enabled) { @@ -61,7 +63,7 @@ async function main() { } console.log(`[Server] ${green(`listening on port ${bold(port)}`)}`); - PluginLoader.loadPlugins(); + await PluginLoader.loadPlugins(); } main().catch(console.error); diff --git a/src/api/Server.ts b/src/api/Server.ts index 560014d0..a3e6f23b 100644 --- a/src/api/Server.ts +++ b/src/api/Server.ts @@ -12,6 +12,7 @@ import TestClient from "./middlewares/TestClient"; import { initTranslation } from "./middlewares/Translation"; import { initInstance } from "./util/handlers/Instance"; import fs from "fs"; +import { PluginConfig } from "util/plugin/PluginConfig"; export interface FosscordServerOptions extends ServerOptions {} @@ -35,6 +36,7 @@ export class FosscordServer extends Server { async start() { await getOrInitialiseDatabase(); await Config.init(); + await PluginConfig.init(); await initEvent(); await initInstance(); diff --git a/src/api/middlewares/ErrorHandler.ts b/src/api/middlewares/ErrorHandler.ts index 813adc18..a3333be5 100644 --- a/src/api/middlewares/ErrorHandler.ts +++ b/src/api/middlewares/ErrorHandler.ts @@ -10,8 +10,12 @@ export function ErrorHandler(error: Error, req: Request, res: Response, next: Ne let httpcode = code; let message = error?.toString(); let errors = undefined; + let data = undefined; - if (error instanceof HTTPError && error.code) code = httpcode = error.code; + if (error instanceof HTTPError && error.code) { + code = httpcode = error.code; + if(error.data) data = error.data; + } else if (error instanceof ApiError) { code = error.code; message = error.message; @@ -35,7 +39,7 @@ export function ErrorHandler(error: Error, req: Request, res: Response, next: Ne if (httpcode > 511) httpcode = 400; - res.status(httpcode).json({ code: code, message, errors }); + res.status(httpcode).json({ code: code, message, errors, data }); } catch (error) { console.error(`[Internal Server Error] 500`, error); return res.status(500).json({ code: 500, message: "Internal Server Error" }); diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index 5fdcb6f9..d542ea0f 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -13,7 +13,11 @@ import { MessageCreateEvent, MessageCreateSchema, Snowflake, - uploadFile + uploadFile, + Member, + MessageCreateSchema, + PluginEventHandler, + PreMessageEventArgs } from "@fosscord/util"; import { Request, Response, Router } from "express"; import multer from "multer"; @@ -206,9 +210,9 @@ router.post( }) ); } - - //Defining member fields - var member = await Member.findOneOrFail({ where: { id: req.user_id }, relations: ["roles"] }); + + //Defining member fields + var member = await Member.findOneOrFail({ where: { id: req.user_id }, relations: ["roles", "user"] }); // TODO: This doesn't work either // member.roles = member.roles.filter((role) => { // return role.id !== role.guild_id; @@ -220,6 +224,11 @@ router.post( // delete message.member.last_message_id; // delete message.member.index; + let blocks = (await PluginEventHandler.preMessageEvent({ + message + } as PreMessageEventArgs)).filter(x=>x.cancel); + if(blocks.length > 0) throw new HTTPError("Message denied.", 400, blocks.filter(x=>x.blockReason).map(x=>x.blockReason)); + await Promise.all([ message.save(), emitEvent({ event: "MESSAGE_CREATE", channel_id: channel_id, data: message } as MessageCreateEvent), diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index d760d27c..07ed11ad 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -21,6 +21,13 @@ import { Role, ROLE_MENTION, User, + Application, + Webhook, + Attachment, + Config, + MessageCreateSchema, + PluginEventHandler, + PreMessageEventArgs, USER_MENTION, Webhook } from "@fosscord/util"; @@ -205,6 +212,10 @@ export async function postHandleMessage(message: Message) { export async function sendMessage(opts: MessageOptions) { const message = await handleMessage({ ...opts, timestamp: new Date() }); + if((await PluginEventHandler.preMessageEvent({ + message + } as PreMessageEventArgs)).filter(x=>x.cancel).length > 0) return; + //TODO: check this, removed toJSON call await Promise.all([ Message.insert(message), diff --git a/src/cdn/Server.ts b/src/cdn/Server.ts index 9cedaa02..8b684b53 100644 --- a/src/cdn/Server.ts +++ b/src/cdn/Server.ts @@ -5,6 +5,8 @@ import path from "path"; import avatarsRoute from "./routes/avatars"; import guildProfilesRoute from "./routes/guild-profiles"; import iconsRoute from "./routes/role-icons"; +import bodyParser from "body-parser"; +import { PluginConfig } from "util/plugin/PluginConfig"; export interface CDNServerOptions extends ServerOptions {} @@ -18,6 +20,7 @@ export class CDNServer extends Server { async start() { await getOrInitialiseDatabase(); await Config.init(); + await PluginConfig.init(); this.app.use((req, res, next) => { res.set("Access-Control-Allow-Origin", "*"); // TODO: use better CSP policy diff --git a/src/gateway/Server.ts b/src/gateway/Server.ts index 97da3fa0..60a82d8f 100644 --- a/src/gateway/Server.ts +++ b/src/gateway/Server.ts @@ -3,6 +3,8 @@ import dotenv from "dotenv"; import http from "http"; import ws from "ws"; import { Connection } from "./events/Connection"; +import http from "http"; +import { PluginConfig } from "util/plugin/PluginConfig"; dotenv.config(); export class Server { @@ -40,6 +42,7 @@ export class Server { async start(): Promise<void> { await getOrInitialiseDatabase(); await Config.init(); + await PluginConfig.init(); await initEvent(); if (!this.server.listening) { this.server.listen(this.port); diff --git a/src/plugins/example-plugin/TestPlugin.ts b/src/plugins/example-plugin/TestPlugin.ts index 7a86aab2..18e634f7 100644 --- a/src/plugins/example-plugin/TestPlugin.ts +++ b/src/plugins/example-plugin/TestPlugin.ts @@ -1,12 +1,26 @@ -import { Plugin } from "@fosscord/util"; +import { setupListener } from "@fosscord/gateway"; +import { Channel, Guild, Plugin, PluginLoadedEventArgs, PluginLoader, PluginManifest, PreMessageEventArgs, PreMessageEventResult } from "@fosscord/util"; +import { TestSettings } from "./TestSettings"; export default class TestPlugin implements Plugin { - pluginPath: string; - async initConfig(): Promise<void> { - - } - onPluginLoaded() { + pluginManifest?: PluginManifest | undefined; + settings: TestSettings = new TestSettings(); + async onPluginLoaded(env: PluginLoadedEventArgs) { console.log("Test plugin active!"); + if(this.pluginManifest) this.settings = PluginLoader.getPluginConfig(this.pluginManifest.id, this.settings) as TestSettings; + } + async onPreMessage(data: PreMessageEventArgs): Promise<PreMessageEventResult> { + let channel = await Channel.findOne({ where: { id: data.message.channel_id } }); + let guild = await Guild.findOne({ where: { id: data.message.guild_id } }); + let block = data.message.content?.includes('UwU'); + + let result = {cancel: block} as PreMessageEventResult; + + if(block) { + console.log(`[TestPlugin] Blocked message in ${guild?.name}/#${channel?.name} by ${data.message.author?.username}: ${data.message.content}`); + result.blockReason = "[TestPlugin] Your message contains UwU! Get bamboozled!"; + } + + return result; } - } \ No newline at end of file diff --git a/src/plugins/example-plugin/TestSettings.ts b/src/plugins/example-plugin/TestSettings.ts new file mode 100644 index 00000000..d8c52187 --- /dev/null +++ b/src/plugins/example-plugin/TestSettings.ts @@ -0,0 +1,11 @@ +export class TestSettings { + someInt: number = 10; + someStr: string = "asdf"; + someBool: boolean = true; + someDate: Date = new Date(); + subSettings: SubSettings = new SubSettings(); +} + +export class SubSettings { + someStr: string = "jklm"; +} \ No newline at end of file diff --git a/src/start.ts b/src/start.ts index cf1a42a5..9d01ce9c 100644 --- a/src/start.ts +++ b/src/start.ts @@ -7,6 +7,8 @@ import { bold, cyan, red, yellow } from "picocolors"; import "reflect-metadata"; import { initStats } from "./stats"; config(); +import { execSync } from "child_process"; +import { Logo } from "util/util/Logo"; // TODO: add socket event transmission let cores = 1; @@ -25,17 +27,15 @@ if (cluster.isMaster) { } } const commit = getCommitOrFail(); - - console.log( - bold(` -███████╗ ██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ -██╔════╝██╔═══██╗██╔════╝██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗ -█████╗ ██║ ██║███████╗███████╗██║ ██║ ██║██████╔╝██║ ██║ -██╔══╝ ██║ ██║╚════██║╚════██║██║ ██║ ██║██╔══██╗██║ ██║ -██║ ╚██████╔╝███████║███████║╚██████╗╚██████╔╝██║ ██║██████╔╝ -╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ - - fosscord-server | ${yellow(`Pre-release (${commit !== null ? commit.slice(0, 7) : "Unknown (Git cannot be found)"})`)} +Logo.printLogo(); +console.log(bold(` + fosscord-server | ${yellow( + `Pre-release (${ + commit !== null + ? commit.slice(0, 7) + : "Unknown (Git cannot be found)" + })` + )} Commit Hash: ${commit !== null ? `${cyan(commit)} (${yellow(commit.slice(0, 7))})` : "Unknown (Git cannot be found)"} Cores: ${cyan(os.cpus().length)} (Using ${cores} thread(s).) diff --git a/src/util/entities/PluginConfig.ts b/src/util/entities/PluginConfig.ts index a1364912..87de5167 100644 --- a/src/util/entities/PluginConfig.ts +++ b/src/util/entities/PluginConfig.ts @@ -7,5 +7,5 @@ export class PluginConfigEntity extends BaseClassWithoutId { key: string; @Column({ type: "simple-json", nullable: true }) - value: number | boolean | null | string | undefined; + value: number | boolean | null | string | Date | undefined; } \ No newline at end of file diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts index 1237b676..57afb132 100644 --- a/src/util/entities/User.ts +++ b/src/util/entities/User.ts @@ -233,6 +233,26 @@ export class User extends BaseClass { } } + /** + * + * + * @static + * @param {{ + * username: string; + * password?: string; + * email?: string; + * date_of_birth?: Date; // "2000-04-03" + * req?: any; + * }} { + * email, + * username, + * password, + * date_of_birth, + * req, + * } + * @return {*} + * @memberof User + */ static async register({ email, username, diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts index 2b91c2ba..444a7e49 100644 --- a/src/util/entities/index.ts +++ b/src/util/entities/index.ts @@ -31,3 +31,8 @@ export * from "./User"; export * from "./UserSettings"; export * from "./VoiceState"; export * from "./Webhook"; +export * from "./ClientRelease"; +export * from "./BackupCodes"; +export * from "./Note"; +export * from "./UserSettings"; +export * from "./PluginConfig"; diff --git a/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts b/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts new file mode 100644 index 00000000..73953ca8 --- /dev/null +++ b/src/util/migrations/mariadb/1660404644371-PluginConfigs.ts @@ -0,0 +1,42 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class PluginConfigs1660404644371 implements MigrationInterface { + name = 'PluginConfigs1660404644371' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` + `); + await queryRunner.query(` + CREATE TABLE \`plugin_config\` ( + \`key\` varchar(255) NOT NULL, + \`value\` text NULL, + PRIMARY KEY (\`key\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`flags\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`default_thread_rate_limit_per_user\` int NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`default_thread_rate_limit_per_user\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + DROP TABLE \`plugin_config\` + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) + `); + } + +} diff --git a/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts b/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts new file mode 100644 index 00000000..d799fe80 --- /dev/null +++ b/src/util/migrations/mariadb/1660534571948-UpdateMigrations.ts @@ -0,0 +1,229 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateMigrations1660534571948 implements MigrationInterface { + name = 'UpdateMigrations1660534571948' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_e5bf78cdbbe9ba91062d74c5aba\` + `); + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` + `); + await queryRunner.query(` + DROP INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` + `); + await queryRunner.query(` + CREATE TABLE \`plugin_config\` ( + \`key\` varchar(255) NOT NULL, + \`value\` text NULL, + PRIMARY KEY (\`key\`) + ) ENGINE = InnoDB + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`rpc_origins\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`primary_sku_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`slug\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`guild_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`type\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`hook\` tinyint NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`redirect_uris\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`rpc_application_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`store_application_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`verification_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`interactions_endpoint_url\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`integration_public\` tinyint NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`integration_require_code_grant\` tinyint NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`discoverability_state\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`discovery_eligibility_flags\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`tags\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`install_params\` text NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`bot_user_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD UNIQUE INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` (\`bot_user_id\`) + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`flags\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`channels\` + ADD \`default_thread_rate_limit_per_user\` int NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`flags\` int NOT NULL + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` (\`bot_user_id\`) + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_2ce5a55796fe4c2f77ece57a647\` FOREIGN KEY (\`bot_user_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE \`invites\` DROP FOREIGN KEY \`FK_15c35422032e0b22b4ada95f48f\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP FOREIGN KEY \`FK_2ce5a55796fe4c2f77ece57a647\` + `); + await queryRunner.query(` + DROP INDEX \`REL_2ce5a55796fe4c2f77ece57a64\` ON \`applications\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`flags\` varchar(255) NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` CHANGE \`description\` \`description\` varchar(255) NOT NULL + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`default_thread_rate_limit_per_user\` + `); + await queryRunner.query(` + ALTER TABLE \`channels\` DROP COLUMN \`flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP INDEX \`IDX_2ce5a55796fe4c2f77ece57a64\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`bot_user_id\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`install_params\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`tags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`discovery_eligibility_flags\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`discoverability_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`integration_require_code_grant\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`integration_public\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`interactions_endpoint_url\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`verification_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`store_application_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`rpc_application_state\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`redirect_uris\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`hook\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` DROP COLUMN \`type\` + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`guild_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`slug\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`primary_sku_id\` varchar(255) NULL + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD \`rpc_origins\` text NULL + `); + await queryRunner.query(` + DROP TABLE \`plugin_config\` + `); + await queryRunner.query(` + CREATE UNIQUE INDEX \`IDX_76ba283779c8441fd5ff819c8c\` ON \`users\` (\`settingsId\`) + `); + await queryRunner.query(` + ALTER TABLE \`invites\` + ADD CONSTRAINT \`FK_15c35422032e0b22b4ada95f48f\` FOREIGN KEY (\`inviter_id\`) REFERENCES \`users\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE \`applications\` + ADD CONSTRAINT \`FK_e5bf78cdbbe9ba91062d74c5aba\` FOREIGN KEY (\`guild_id\`) REFERENCES \`guilds\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + +} diff --git a/src/util/migrations/postgres/1660404619978-PluginConfigs.ts b/src/util/migrations/postgres/1660404619978-PluginConfigs.ts new file mode 100644 index 00000000..d8a5ab4d --- /dev/null +++ b/src/util/migrations/postgres/1660404619978-PluginConfigs.ts @@ -0,0 +1,22 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class PluginConfigs1660404619978 implements MigrationInterface { + name = 'PluginConfigs1660404619978' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "plugin_config" ( + "key" character varying NOT NULL, + "value" text, + CONSTRAINT "PK_aa929ece56c59233b85a16f62ef" PRIMARY KEY ("key") + ) + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + DROP TABLE "plugin_config" + `); + } + +} diff --git a/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts b/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts new file mode 100644 index 00000000..54a59fab --- /dev/null +++ b/src/util/migrations/sqlite/1660534525799-UpdateMigrations.ts @@ -0,0 +1,829 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateMigrations1660534525799 implements MigrationInterface { + name = 'UpdateMigrations1660534525799' + + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + await queryRunner.query(` + CREATE TABLE "temporary_applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_2ce5a55796fe4c2f77ece57a647" FOREIGN KEY ("bot_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "temporary_applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "applications" + `); + await queryRunner.query(` + DROP TABLE "applications" + `); + await queryRunner.query(` + ALTER TABLE "temporary_applications" + RENAME TO "applications" + `); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" integer NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "type" text, + "hook" boolean NOT NULL, + "redirect_uris" text, + "rpc_application_state" integer, + "store_application_state" integer, + "verification_state" integer, + "interactions_endpoint_url" varchar, + "integration_public" boolean, + "integration_require_code_grant" boolean, + "discoverability_state" integer, + "discovery_eligibility_flags" integer, + "tags" text, + "install_params" text, + "bot_user_id" varchar, + CONSTRAINT "UQ_b7f6e13565e920916d902e1f431" UNIQUE ("bot_user_id"), + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id", + "type", + "hook", + "redirect_uris", + "rpc_application_state", + "store_application_state", + "verification_state", + "interactions_endpoint_url", + "integration_public", + "integration_require_code_grant", + "discoverability_state", + "discovery_eligibility_flags", + "tags", + "install_params", + "bot_user_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + ) + SELECT "id", + "name", + "icon", + "description", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "cover_image", + "flags", + "owner_id", + "team_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + await queryRunner.query(` + ALTER TABLE "applications" + RENAME TO "temporary_applications" + `); + await queryRunner.query(` + CREATE TABLE "applications" ( + "id" varchar PRIMARY KEY NOT NULL, + "name" varchar NOT NULL, + "icon" varchar, + "description" varchar NOT NULL, + "rpc_origins" text, + "bot_public" boolean NOT NULL, + "bot_require_code_grant" boolean NOT NULL, + "terms_of_service_url" varchar, + "privacy_policy_url" varchar, + "summary" varchar, + "verify_key" varchar NOT NULL, + "primary_sku_id" varchar, + "slug" varchar, + "cover_image" varchar, + "flags" varchar NOT NULL, + "owner_id" varchar, + "team_id" varchar, + "guild_id" varchar, + CONSTRAINT "FK_e5bf78cdbbe9ba91062d74c5aba" FOREIGN KEY ("guild_id") REFERENCES "guilds" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT "FK_a36ed02953077f408d0f3ebc424" FOREIGN KEY ("team_id") REFERENCES "teams" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, + CONSTRAINT "FK_e57508958bf92b9d9d25231b5e8" FOREIGN KEY ("owner_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION + ) + `); + await queryRunner.query(` + INSERT INTO "applications"( + "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + ) + SELECT "id", + "name", + "icon", + "description", + "rpc_origins", + "bot_public", + "bot_require_code_grant", + "terms_of_service_url", + "privacy_policy_url", + "summary", + "verify_key", + "primary_sku_id", + "slug", + "cover_image", + "flags", + "owner_id", + "team_id", + "guild_id" + FROM "temporary_applications" + `); + await queryRunner.query(` + DROP TABLE "temporary_applications" + `); + } + +} diff --git a/src/util/plugin/Plugin.ts b/src/util/plugin/Plugin.ts index 0fb1732f..6a6f03f4 100644 --- a/src/util/plugin/Plugin.ts +++ b/src/util/plugin/Plugin.ts @@ -1,13 +1,22 @@ import EventEmitter from "events"; -import { PluginLoadedEventArgs, TypedEventEmitter } from "@fosscord/util"; +import { PluginLoadedEventArgs, PluginManifest, TypedEventEmitter } from "@fosscord/util"; +import { PluginConfig } from "./PluginConfig"; +import { PreRegisterEventArgs, PreRegisterEventResult, OnRegisterEventArgs } from '.'; +import { PreMessageEventArgs, PreMessageEventResult, OnMessageEventArgs } from '.'; +import { PreLoginEventArgs, PreLoginEventResult, OnLoginEventArgs } from '.'; +import { PreGuildCreateEventArgs, PreGuildCreateEventResult, OnGuildCreateEventArgs } from '.'; +import { PreChannelCreateEventArgs, PreChannelCreateEventResult, OnChannelCreateEventArgs } from '.'; +import { PreTypingEventArgs, PreTypingEventResult, OnTypingEventArgs } from '.'; +import { PreStatusChangeEventArgs, PreStatusChangeEventResult, OnStatusChangeEventArgs } from '.'; -type PluginEvents = { + +/*type PluginEvents = { error: (error: Error | unknown) => void; loaded: () => void; -}; +};*/ //this doesnt work, check later: - //EventEmitter as new () => TypedEventEmitter<PluginEvents> +//EventEmitter as new () => TypedEventEmitter<PluginEvents> export class Plugin { /** * Path the plugin resides in. @@ -15,23 +24,137 @@ export class Plugin { * @type {string} * @memberof Plugin */ - pluginPath: string; - /** - * - * - * @memberof Plugin - */ - async initConfig() { - // insert default config into database? - console.log("did you forget to implement initConfig?"); - } + pluginPath?: string; + pluginManifest?: PluginManifest; /** * * * @param {PluginLoadedEventArgs} args Info about plugin environment * @memberof Plugin */ - onPluginLoaded?(args?: PluginLoadedEventArgs) { - + async onPluginLoaded?(args?: PluginLoadedEventArgs) { + } + + //generated + /** + * RegisterEvent: document me + * + * @param {OnRegisterEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onRegister?(args: OnRegisterEventArgs): Promise<void>; + + /** + * RegisterEvent: Executed before changes are announced + * document me. + * + * @param {PreRegisterEventArgs} args Info about what's going on + * @return {PreRegisterEventResult} How event should be handled + * @memberof Plugin + */ + async onPreRegister?(args: PreRegisterEventArgs): Promise<PreRegisterEventResult>; + /** + * MessageEvent: document me + * + * @param {OnMessageEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onMessage?(args: OnMessageEventArgs): Promise<void>; + + /** + * MessageEvent: Executed before changes are announced + * document me. + * + * @param {PreMessageEventArgs} args Info about what's going on + * @return {PreMessageEventResult} How event should be handled + * @memberof Plugin + */ + async onPreMessage?(args: PreMessageEventArgs): Promise<PreMessageEventResult>; + /** + * LoginEvent: document me + * + * @param {OnLoginEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onLogin?(args: OnLoginEventArgs): Promise<void>; + + /** + * LoginEvent: Executed before changes are announced + * document me. + * + * @param {PreLoginEventArgs} args Info about what's going on + * @return {PreLoginEventResult} How event should be handled + * @memberof Plugin + */ + async onPreLogin?(args: PreLoginEventArgs): Promise<PreLoginEventResult>; + /** + * GuildCreateEvent: document me + * + * @param {OnGuildCreateEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onGuildCreate?(args: OnGuildCreateEventArgs): Promise<void>; + + /** + * GuildCreateEvent: Executed before changes are announced + * document me. + * + * @param {PreGuildCreateEventArgs} args Info about what's going on + * @return {PreGuildCreateEventResult} How event should be handled + * @memberof Plugin + */ + async onPreGuildCreate?(args: PreGuildCreateEventArgs): Promise<PreGuildCreateEventResult>; + /** + * ChannelCreateEvent: document me + * + * @param {OnChannelCreateEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onChannelCreate?(args: OnChannelCreateEventArgs): Promise<void>; + + /** + * ChannelCreateEvent: Executed before changes are announced + * document me. + * + * @param {PreChannelCreateEventArgs} args Info about what's going on + * @return {PreChannelCreateEventResult} How event should be handled + * @memberof Plugin + */ + async onPreChannelCreate?(args: PreChannelCreateEventArgs): Promise<PreChannelCreateEventResult>; + /** + * TypingEvent: document me + * + * @param {OnTypingEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onTyping?(args: OnTypingEventArgs): Promise<void>; + + /** + * TypingEvent: Executed before changes are announced + * document me. + * + * @param {PreTypingEventArgs} args Info about what's going on + * @return {PreTypingEventResult} How event should be handled + * @memberof Plugin + */ + async onPreTyping?(args: PreTypingEventArgs): Promise<PreTypingEventResult>; + /** + * StatusChangeEvent: document me + * + * @param {OnStatusChangeEventArgs} args Info about what's going on + * @memberof Plugin + */ + async onStatusChange?(args: OnStatusChangeEventArgs): Promise<void>; + + /** + * StatusChangeEvent: Executed before changes are announced + * document me. + * + * @param {PreStatusChangeEventArgs} args Info about what's going on + * @return {PreStatusChangeEventResult} How event should be handled + * @memberof Plugin + */ + async onPreStatusChange?(args: PreStatusChangeEventArgs): Promise<PreStatusChangeEventResult>; + } diff --git a/src/util/plugin/PluginConfig.ts b/src/util/plugin/PluginConfig.ts index c7a7db87..883bca7c 100644 --- a/src/util/plugin/PluginConfig.ts +++ b/src/util/plugin/PluginConfig.ts @@ -1,26 +1,26 @@ -import { ConfigEntity } from "../entities/Config"; import fs from "fs"; import { OrmUtils, Environment } from ".."; +import { PluginConfigEntity } from "util/entities/PluginConfig"; // TODO: yaml instead of json const overridePath = process.env.PLUGIN_CONFIG_PATH ?? ""; let config: any; -let pairs: ConfigEntity[]; +let pairs: PluginConfigEntity[]; // TODO: use events to inform about config updates // Config keys are separated with _ -export const Config = { +export const PluginConfig = { init: async function init() { if (config) return config; - console.log('[Config] Loading configuration...') - pairs = await ConfigEntity.find(); + console.log('[PluginConfig] Loading configuration...') + pairs = await PluginConfigEntity.find(); config = pairsToConfig(pairs); //config = (config || {}).merge(new ConfigValue()); //config = OrmUtils.mergeDeep(new ConfigValue(), config) - if(process.env.CONFIG_PATH) + if(process.env.PLUGIN_CONFIG_PATH) try { const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" })); config = overrideConfig.merge(config); @@ -48,26 +48,32 @@ export const Config = { function applyConfig(val: any) { async function apply(obj: any, key = ""): Promise<any> { - if (typeof obj === "object" && obj !== null) + if (typeof obj === "object" && obj !== null && !(obj instanceof Date)) return Promise.all(Object.keys(obj).map((k) => apply(obj[k], key ? `${key}_${k}` : k))); let pair = pairs.find((x) => x.key === key); - if (!pair) pair = new ConfigEntity(); + if (!pair) pair = new PluginConfigEntity(); pair.key = key; pair.value = obj; - return pair.save(); + if(!pair.key || pair.key == null) { + console.log(`[PluginConfig] WARN: Empty key`) + console.log(pair); + if(Environment.isDebug) debugger; + } + else + return pair.save(); } - if(process.env.CONFIG_PATH) { + if(process.env.PLUGIN_CONFIG_PATH) { if(Environment.isDebug) - console.log(`Writing config: ${process.env.CONFIG_PATH}`) + console.log(`Writing config: ${process.env.PLUGIN_CONFIG_PATH}`) fs.writeFileSync(overridePath, JSON.stringify(val, null, 4)); } return apply(val); } -function pairsToConfig(pairs: ConfigEntity[]) { +function pairsToConfig(pairs: PluginConfigEntity[]) { let value: any = {}; pairs.forEach((p) => { diff --git a/src/util/plugin/PluginEventHandler.ts b/src/util/plugin/PluginEventHandler.ts new file mode 100644 index 00000000..d5fc67f4 --- /dev/null +++ b/src/util/plugin/PluginEventHandler.ts @@ -0,0 +1,67 @@ +import { PreRegisterEventArgs, OnRegisterEventArgs, PreRegisterEventResult } from './event_types'; +import { PreMessageEventArgs, OnMessageEventArgs, PreMessageEventResult } from './event_types'; +import { PreLoginEventArgs, OnLoginEventArgs, PreLoginEventResult } from './event_types'; +import { PreGuildCreateEventArgs, OnGuildCreateEventArgs, PreGuildCreateEventResult } from './event_types'; +import { PreChannelCreateEventArgs, OnChannelCreateEventArgs, PreChannelCreateEventResult } from './event_types'; +import { PreTypingEventArgs, OnTypingEventArgs, PreTypingEventResult } from './event_types'; +import { PreStatusChangeEventArgs, OnStatusChangeEventArgs, PreStatusChangeEventResult } from './event_types'; +import { PluginStore } from "."; + +export class PluginEventHandler { + public static async preRegisterEvent(args: PreRegisterEventArgs): Promise<PreRegisterEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreRegister).map(x=>x.onPreRegister && x.onPreRegister(args)))).filter(x=>x) as PreRegisterEventResult[]; + } + + public static async onRegisterEvent(args: OnRegisterEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onRegister).map(x=>x.onRegister && x.onRegister(args))); + } + + public static async preMessageEvent(args: PreMessageEventArgs): Promise<PreMessageEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreMessage).map(x=>x.onPreMessage && x.onPreMessage(args)))).filter(x=>x) as PreMessageEventResult[]; + } + + public static async onMessageEvent(args: OnMessageEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onMessage).map(x=>x.onMessage && x.onMessage(args))); + } + + public static async preLoginEvent(args: PreLoginEventArgs): Promise<PreLoginEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreLogin).map(x=>x.onPreLogin && x.onPreLogin(args)))).filter(x=>x) as PreLoginEventResult[]; + } + + public static async onLoginEvent(args: OnLoginEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onLogin).map(x=>x.onLogin && x.onLogin(args))); + } + + public static async preGuildCreateEvent(args: PreGuildCreateEventArgs): Promise<PreGuildCreateEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreGuildCreate).map(x=>x.onPreGuildCreate && x.onPreGuildCreate(args)))).filter(x=>x) as PreGuildCreateEventResult[]; + } + + public static async onGuildCreateEvent(args: OnGuildCreateEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onGuildCreate).map(x=>x.onGuildCreate && x.onGuildCreate(args))); + } + + public static async preChannelCreateEvent(args: PreChannelCreateEventArgs): Promise<PreChannelCreateEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreChannelCreate).map(x=>x.onPreChannelCreate && x.onPreChannelCreate(args)))).filter(x=>x) as PreChannelCreateEventResult[]; + } + + public static async onChannelCreateEvent(args: OnChannelCreateEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onChannelCreate).map(x=>x.onChannelCreate && x.onChannelCreate(args))); + } + + public static async preTypingEvent(args: PreTypingEventArgs): Promise<PreTypingEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreTyping).map(x=>x.onPreTyping && x.onPreTyping(args)))).filter(x=>x) as PreTypingEventResult[]; + } + + public static async onTypingEvent(args: OnTypingEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onTyping).map(x=>x.onTyping && x.onTyping(args))); + } + + public static async preStatusChangeEvent(args: PreStatusChangeEventArgs): Promise<PreStatusChangeEventResult[]> { + return (await Promise.all(PluginStore.plugins.filter(x=>x.onPreStatusChange).map(x=>x.onPreStatusChange && x.onPreStatusChange(args)))).filter(x=>x) as PreStatusChangeEventResult[]; + } + + public static async onStatusChangeEvent(args: OnStatusChangeEventArgs): Promise<void> { + await Promise.all(PluginStore.plugins.filter(x=>x.onStatusChange).map(x=>x.onStatusChange && x.onStatusChange(args))); + } + +} diff --git a/src/util/plugin/PluginLoader.ts b/src/util/plugin/PluginLoader.ts index 8c140d29..4dc0129a 100644 --- a/src/util/plugin/PluginLoader.ts +++ b/src/util/plugin/PluginLoader.ts @@ -1,14 +1,17 @@ import path from "path"; import fs from "fs"; -import { Plugin, PluginLoadedEventArgs, PluginManifest } from "./"; +import { Plugin, PluginLoadedEventArgs, PluginManifest, PluginStore } from "./"; import { PluginIndex } from "plugins/PluginIndex"; +import { PluginConfig } from "./PluginConfig"; +import { OrmUtils, PluginConfigEntity } from ".."; const root = process.env.PLUGIN_LOCATION || "dist/plugins"; let pluginsLoaded = false; export class PluginLoader { - public static plugins: Plugin[] = []; - public static loadPlugins() { + public static async loadPlugins() { + if(pluginsLoaded) return; + PluginConfig.init(); console.log(`Plugin root directory: ${path.resolve(root)}`); const dirs = fs.readdirSync(root).filter((x) => { try { @@ -18,24 +21,45 @@ export class PluginLoader { return false; } }); - console.log(dirs); - PluginIndex.forEach((x: any)=>{ - console.log(x.onPluginLoaded) - }) + //console.log(dirs); + PluginIndex.forEach((x: any) => { + //console.log(x.onPluginLoaded) + }); dirs.forEach(async (x) => { let modPath = path.resolve(path.join(root, x)); - console.log(`Trying to load plugin: ${modPath}`); + //console.log(`Trying to load plugin: ${modPath}`); const manifest = require(path.join(modPath, "plugin.json")) as PluginManifest; console.log( `Plugin info: ${manifest.name} (${manifest.id}), written by ${manifest.authors}, available at ${manifest.repository}` ); - const module_ = PluginIndex["example-plugin"]; + const module_ = PluginIndex[manifest.id]; module_.pluginPath = modPath; - if(module_.onPluginLoaded) module_.onPluginLoaded({} as PluginLoadedEventArgs); - this.plugins.push(module_); + module_.pluginManifest = manifest; + Object.freeze(module_.pluginPath); + Object.freeze(module_.pluginManifest); + + if(module_.onPluginLoaded) await module_.onPluginLoaded({} as PluginLoadedEventArgs); + PluginStore.plugins.push(module_); }); - console.log(`Done loading ${this.plugins.length} plugins!`) + console.log(`Done loading ${PluginStore.plugins.length} plugins!`); + } + + public static getPluginConfig(id: string, defaults?: any): any { + let cfg = PluginConfig.get()[id]; + if(defaults) { + if(cfg) + cfg = OrmUtils.mergeDeep(defaults, cfg); + else + cfg = defaults; + this.setPluginConfig(id, cfg); + } + if(!cfg) console.log(`[PluginConfig/WARN] Getting plugin settings for '${id}' returned null! (Did you forget to add settings?)`); + return cfg; + } + public static async setPluginConfig(id: string, config: Partial<any>): Promise<void> { + if(!config) console.log(`[PluginConfig/WARN] ${id} tried to set config=null!`); + await PluginConfig.set({ [id]: OrmUtils.mergeDeep(PluginLoader.getPluginConfig(id) || {}, config) }); } } diff --git a/src/util/plugin/PluginStore.ts b/src/util/plugin/PluginStore.ts new file mode 100644 index 00000000..60d7f7b7 --- /dev/null +++ b/src/util/plugin/PluginStore.ts @@ -0,0 +1,12 @@ +import path from "path"; +import fs from "fs"; +import { Plugin, PluginLoadedEventArgs, PluginManifest } from "./"; +import { PluginIndex } from "plugins/PluginIndex"; +import { PluginConfig } from "./PluginConfig"; +import { OrmUtils, PluginConfigEntity } from ".."; + +const root = process.env.PLUGIN_LOCATION || "dist/plugins"; + +export class PluginStore { + public static plugins: Plugin[] = []; +} diff --git a/src/util/plugin/event_types/ChannelCreateEventArgs.ts b/src/util/plugin/event_types/ChannelCreateEventArgs.ts new file mode 100644 index 00000000..87fa3691 --- /dev/null +++ b/src/util/plugin/event_types/ChannelCreateEventArgs.ts @@ -0,0 +1,17 @@ +import { Channel, Guild, User } from "util/entities"; +import { EventResult } from "."; + +export interface PreChannelCreateEventArgs { + channel: Channel, + guild: Guild, + user: User +} +export interface PreChannelCreateEventResult extends EventResult { + channel: Partial<Channel> +} + +export interface OnChannelCreateEventArgs { + channel: Channel, + guild: Guild, + user: User +} diff --git a/src/util/plugin/event_types/GuildCreateEventArgs.ts b/src/util/plugin/event_types/GuildCreateEventArgs.ts new file mode 100644 index 00000000..7724b4f3 --- /dev/null +++ b/src/util/plugin/event_types/GuildCreateEventArgs.ts @@ -0,0 +1,15 @@ +import { Guild, User } from "util/entities"; +import { EventResult } from "."; + +export interface PreGuildCreateEventArgs { + user: User, + guild: Guild +} +export interface PreGuildCreateEventResult extends EventResult { + guild: Partial<Guild> +} + +export interface OnGuildCreateEventArgs { + user: User, + guild: Guild +} diff --git a/src/util/plugin/event_types/LoginEventArgs.ts b/src/util/plugin/event_types/LoginEventArgs.ts new file mode 100644 index 00000000..8f80b69f --- /dev/null +++ b/src/util/plugin/event_types/LoginEventArgs.ts @@ -0,0 +1,15 @@ +import { User } from "util/entities"; +import { EventResult } from "."; + +export interface PreLoginEventArgs { + ip: String, + user: User +} +export interface PreLoginEventResult extends EventResult { + +} + +export interface OnLoginEventArgs { + ip: String, + user: User +} diff --git a/src/util/plugin/event_types/MessageEventArgs.ts b/src/util/plugin/event_types/MessageEventArgs.ts new file mode 100644 index 00000000..ab276429 --- /dev/null +++ b/src/util/plugin/event_types/MessageEventArgs.ts @@ -0,0 +1,15 @@ +import { Message, User } from "util/entities"; +import { EventResult } from "."; + +export interface PreMessageEventArgs { + user: User, + message: Message; +} +export interface PreMessageEventResult extends EventResult { + message: Partial<Message> +} + +export interface OnMessageEventArgs { + user: User, + message: Message +} diff --git a/src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts b/src/util/plugin/event_types/PluginLoadedEventArgs.ts index 58829f15..58829f15 100644 --- a/src/util/plugin/plugin_data_objects/PluginLoadedEventArgs.ts +++ b/src/util/plugin/event_types/PluginLoadedEventArgs.ts diff --git a/src/util/plugin/event_types/RegisterEventArgs.ts b/src/util/plugin/event_types/RegisterEventArgs.ts new file mode 100644 index 00000000..d36d7e64 --- /dev/null +++ b/src/util/plugin/event_types/RegisterEventArgs.ts @@ -0,0 +1,17 @@ +import { User } from "util/entities"; +import { EventResult } from "."; + +export interface PreRegisterEventArgs { + age: any, + user: User, + ip: String +} +export interface PreRegisterEventResult extends EventResult { + user: Partial<User> +} + +export interface OnRegisterEventArgs { + age: any, + user: User, + ip: String +} diff --git a/src/util/plugin/event_types/StatusChangeEventArgs.ts b/src/util/plugin/event_types/StatusChangeEventArgs.ts new file mode 100644 index 00000000..c1a67112 --- /dev/null +++ b/src/util/plugin/event_types/StatusChangeEventArgs.ts @@ -0,0 +1,16 @@ +import { User } from "util/entities"; +import { Presence } from "util/interfaces"; +import { EventResult } from "."; + +export interface PreStatusChangeEventArgs { + user: User, + presence: Presence +} +export interface PreStatusChangeEventResult extends EventResult { + presence: Partial<Presence> +} + +export interface OnStatusChangeEventArgs { + user: User, + presence: Presence +} diff --git a/src/util/plugin/event_types/TypingEventArgs.ts b/src/util/plugin/event_types/TypingEventArgs.ts new file mode 100644 index 00000000..3ac59b41 --- /dev/null +++ b/src/util/plugin/event_types/TypingEventArgs.ts @@ -0,0 +1,17 @@ +import { Channel, Guild, User } from "util/entities"; +import { EventResult } from "."; + +export interface PreTypingEventArgs { + channel: Channel, + guild: Guild, + user: User +} +export interface PreTypingEventResult extends EventResult { + +} + +export interface OnTypingEventArgs { + channel: Channel, + guild: Guild, + user: User +} diff --git a/src/util/plugin/event_types/_gen.sh b/src/util/plugin/event_types/_gen.sh new file mode 100755 index 00000000..9f761d1e --- /dev/null +++ b/src/util/plugin/event_types/_gen.sh @@ -0,0 +1,74 @@ +#!/bin/sh +rm -f ../plugin.eventfuncs.generated +rm -f ../plugin.imports.generated +while read event +do + echo Making event $event... + ( + echo 'import { EventResult } from ".";' + echo '' + echo "export interface Pre${event}EventArgs {" + echo ' ' + echo '}' + echo "export interface Pre${event}EventResult extends EventResult {" + echo ' ' + echo '}' + echo '' + echo "export interface On${event}EventArgs {" + echo ' ' + echo '}' + ) > ${event}EventArgs.ts.generated + ( + echo " public static async pre${event}Event(args: Pre${event}EventArgs): Promise<Pre${event}EventResult[]> {" + echo " return (await Promise.all(PluginStore.plugins.filter(x=>x.onPre${event}).map(x=>x.onPre${event} && x.onPre${event}(args)))).filter(x=>x) as Pre${event}EventResult[];" + echo ' }' + echo ' ' + echo " public static async on${event}Event(args: On${event}EventArgs): Promise<void> {" + echo " await Promise.all(PluginStore.plugins.filter(x=>x.on${event}).map(x=>x.on${event} && x.on${event}(args)));" + echo ' }' + echo ' ' + ) >> ../PluginEventHandler.ts.3 + ( + echo " /**" + echo " * ${event}Event: document me" + echo " *" + echo " * @param {On${event}EventArgs} args Info about what's going on" + echo " * @memberof Plugin" + echo " */" + echo " async on${event}?(args: On${event}EventArgs): Promise<void>;" + echo ' ' + echo " /**" + echo " * ${event}Event: Executed before changes are announced" + echo " * document me." + echo " *" + echo " * @param {Pre${event}EventArgs} args Info about what's going on" + echo " * @return {Pre${event}EventResult} How event should be handled" + echo " * @memberof Plugin" + echo " */" + echo " async onPre${event}?(args: Pre${event}EventArgs): Promise<Pre${event}EventResult>;" + ) >> ../plugin.eventfuncs.generated + + echo "import { Pre${event}EventArgs, On${event}EventArgs, Pre${event}EventResult } from './event_types';" >> ../PluginEventHandler.ts.1 + echo "import { Pre${event}EventArgs, Pre${event}EventResult, On${event}EventArgs } from '.';" >> ../plugin.imports.generated + cmp --silent "${event}EventArgs.ts" "${event}EventArgs.ts.generated" && rm -f "${event}EventArgs.ts.generated" +done < _pdo + +echo 'Building PluginEventHandler...' + +rm -f ../PluginEventHandler.ts.generated +( + echo 'import { PluginStore } from ".";' + echo '' + echo 'export class PluginEventHandler {' +) > ../PluginEventHandler.ts.2 +echo '}' > ../PluginEventHandler.ts.4 +for i in {1..4} +do + cat "../PluginEventHandler.ts.$i" >> ../PluginEventHandler.ts.generated + rm -f ../PluginEventHandler.ts.$i +done +cmp --silent ../PluginEventHandler.ts ../PluginEventHandler.ts.generated && rm -f ../PluginEventHandler.ts.generated + +echo 'Rebuilding indexes...' +node ../../../../scripts/gen_index.js .. --recursive +echo 'Done!' \ No newline at end of file diff --git a/src/util/plugin/plugin_data_objects/_pdo b/src/util/plugin/event_types/_pdo index fa207f77..f6127174 100644 --- a/src/util/plugin/plugin_data_objects/_pdo +++ b/src/util/plugin/event_types/_pdo @@ -4,4 +4,5 @@ Login GuildCreate ChannelCreate Typing -StatusChange \ No newline at end of file +StatusChange +UserProfileUpdate \ No newline at end of file diff --git a/src/util/plugin/plugin_data_objects/_todo.txt b/src/util/plugin/event_types/_todo.txt index a6a78c7e..a6a78c7e 100644 --- a/src/util/plugin/plugin_data_objects/_todo.txt +++ b/src/util/plugin/event_types/_todo.txt diff --git a/src/util/plugin/event_types/base/EventResult.ts b/src/util/plugin/event_types/base/EventResult.ts new file mode 100644 index 00000000..f18837cd --- /dev/null +++ b/src/util/plugin/event_types/base/EventResult.ts @@ -0,0 +1,4 @@ +export interface EventResult { + cancel?: boolean; + blockReason?: string; +} \ No newline at end of file diff --git a/src/util/plugin/event_types/base/index.ts b/src/util/plugin/event_types/base/index.ts new file mode 100644 index 00000000..fd0dbd03 --- /dev/null +++ b/src/util/plugin/event_types/base/index.ts @@ -0,0 +1 @@ +export * from "./EventResult"; diff --git a/src/util/plugin/plugin_data_objects/index.ts b/src/util/plugin/event_types/index.ts index c75d43f9..4a585dc0 100644 --- a/src/util/plugin/plugin_data_objects/index.ts +++ b/src/util/plugin/event_types/index.ts @@ -4,4 +4,6 @@ export * from "./LoginEventArgs"; export * from "./MessageEventArgs"; export * from "./PluginLoadedEventArgs"; export * from "./RegisterEventArgs"; +export * from "./StatusChangeEventArgs"; export * from "./TypingEventArgs"; +export * from "./base/index"; diff --git a/src/util/plugin/index.ts b/src/util/plugin/index.ts index 5974a065..7a297981 100644 --- a/src/util/plugin/index.ts +++ b/src/util/plugin/index.ts @@ -1,4 +1,7 @@ export * from "./Plugin"; +export * from "./PluginConfig"; +export * from "./PluginEventHandler"; export * from "./PluginLoader"; export * from "./PluginManifest"; -export * from "./plugin_data_objects/index"; +export * from "./PluginStore"; +export * from "./event_types/index"; diff --git a/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts b/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts deleted file mode 100644 index ce7dec87..00000000 --- a/src/util/plugin/plugin_data_objects/ChannelCreateEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreChannelCreateEventArgs { - -} - -export interface OnChannelCreateEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts b/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts deleted file mode 100644 index e10e675a..00000000 --- a/src/util/plugin/plugin_data_objects/GuildCreateEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreGuildCreateEventArgs { - -} - -export interface OnGuildCreateEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/LoginEventArgs.ts b/src/util/plugin/plugin_data_objects/LoginEventArgs.ts deleted file mode 100644 index 391b852e..00000000 --- a/src/util/plugin/plugin_data_objects/LoginEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreLoginEventArgs { - -} - -export interface OnLoginEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/MessageEventArgs.ts b/src/util/plugin/plugin_data_objects/MessageEventArgs.ts deleted file mode 100644 index 0a3498c2..00000000 --- a/src/util/plugin/plugin_data_objects/MessageEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreMessageEventArgs { - -} - -export interface OnMessageEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts b/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts deleted file mode 100644 index 7f7c0c76..00000000 --- a/src/util/plugin/plugin_data_objects/RegisterEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreRegisterEventArgs { - -} - -export interface OnRegisterEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/TypingEventArgs.ts b/src/util/plugin/plugin_data_objects/TypingEventArgs.ts deleted file mode 100644 index f6660692..00000000 --- a/src/util/plugin/plugin_data_objects/TypingEventArgs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface PreTypingEventArgs { - -} - -export interface OnTypingEventArgs { - -} diff --git a/src/util/plugin/plugin_data_objects/_gen.sh b/src/util/plugin/plugin_data_objects/_gen.sh deleted file mode 100755 index 9fbd1749..00000000 --- a/src/util/plugin/plugin_data_objects/_gen.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -while read event -do - if [ ! -f "${event}EventArgs.ts" ] - then - echo Making event $event... - ( - echo "export interface Pre${event}EventArgs {" - echo ' ' - echo '}' - echo '' - echo "export interface On${event}EventArgs {" - echo ' ' - echo '}' - ) > ${event}EventArgs.ts - fi -done < _pdo - -echo '' - -node ../../../../scripts/gen_index.js .. --recursive \ No newline at end of file diff --git a/src/util/util/Logo.ts b/src/util/util/Logo.ts new file mode 100644 index 00000000..b1627198 --- /dev/null +++ b/src/util/util/Logo.ts @@ -0,0 +1,41 @@ +import { existsSync } from "fs"; +import { execSync } from "child_process"; + +export class Logo { + public static printLogo(){ + if(existsSync("/usr/bin/chafa")) + return execSync("chafa https://raw.githubusercontent.com/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Wordmark-Orange.svg", { + env: process.env, + encoding: "utf-8", + stdio: "inherit", + + }); + else console.log(Logo.logoVersions['1'] as string) + } + private static getConsoleColors(): number { + return 1; + if(!process.env.TERM) return 1; + else { + switch (process.env.TERM) { + case "": + + break; + + default: + break; + } + } + return 1; + } + private static logoVersions: any = { + '1': + `███████╗ ██████╗ ███████╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ + ██╔════╝██╔═══██╗██╔════╝██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗ + █████╗ ██║ ██║███████╗███████╗██║ ██║ ██║██████╔╝██║ ██║ + ██╔══╝ ██║ ██║╚════██║╚════██║██║ ██║ ██║██╔══██╗██║ ██║ + ██║ ╚██████╔╝███████║███████║╚██████╗╚██████╔╝██║ ██║██████╔╝ + ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝`, + '2':`` + + } +} \ No newline at end of file diff --git a/src/util/util/imports/HTTPError.ts b/src/util/util/imports/HTTPError.ts index 70ba92a8..3439bd00 100644 --- a/src/util/util/imports/HTTPError.ts +++ b/src/util/util/imports/HTTPError.ts @@ -1,5 +1,5 @@ export class HTTPError extends Error { - constructor(message: string, public code: number = 400) { + constructor(message: string, public code: number = 400, public data: any = null) { super(message); } } |