diff --git a/src/util/plugin/Plugin.ts b/src/util/plugin/Plugin.ts
index 246e9931..96e05843 100644
--- a/src/util/plugin/Plugin.ts
+++ b/src/util/plugin/Plugin.ts
@@ -1,5 +1,13 @@
-export class Plugin {
- onPluginLoaded() {
- console.log('no onpluginloaded!')
- }
-}
\ No newline at end of file
+import EventEmitter from "events";
+import { TypedEventEmitter } from "@fosscord/util";
+
+type PluginEvents = {
+ error: (error: Error | unknown) => void;
+ loaded: () => void;
+};
+
+export class Plugin extends (EventEmitter as new () => TypedEventEmitter<PluginEvents>) {
+ async init() {
+ // insert default config into database?
+ }
+}
diff --git a/src/util/plugin/PluginLoader.ts b/src/util/plugin/PluginLoader.ts
index eadfb912..b46ef269 100644
--- a/src/util/plugin/PluginLoader.ts
+++ b/src/util/plugin/PluginLoader.ts
@@ -6,27 +6,34 @@ const root = process.env.PLUGIN_LOCATION || "../plugins";
let pluginsLoaded = false;
export class PluginLoader {
- public static loadPlugins() {
+ public static loadPlugins() {
+ console.log(`Plugin root directory: ${path.resolve(root)}`);
+ const dirs = fs.readdirSync(root).filter((x) => {
+ try {
+ fs.readdirSync(path.join(root, x));
+ return true;
+ } catch (e) {
+ return false;
+ }
+ });
+ console.log(dirs);
+ dirs.forEach(async (x) => {
+ let modPath = path.resolve(path.join(root, x));
+ 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_ = require(path.join(modPath, "dist", "index.js")) as Plugin;
+ try {
+ await module_.init();
+ module_.emit("loaded");
+ } catch (error) {
+ module_.emit("error", error);
+ }
+ });
- console.log(`Plugin root directory: ${path.resolve(root)}`);
- const dirs = fs.readdirSync(root).filter(x => {
- try {
- fs.readdirSync(path.join(root, x));
- return true;
- } catch (e) {
- return false;
- }
- });
- console.log(dirs)
- dirs.forEach(x=>{
- let modPath = path.resolve(path.join(root, x));
- 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_ = require(path.join(modPath, "dist", "index.js")) as Plugin;
- module_.onPluginLoaded();
- })
- //
- //module_.pluginPath =
- }
-}
\ No newline at end of file
+ //
+ //module_.pluginPath =
+ }
+}
diff --git a/src/util/util/imports/TypedEmitter.ts b/src/util/util/imports/TypedEmitter.ts
new file mode 100644
index 00000000..7a0fffe2
--- /dev/null
+++ b/src/util/util/imports/TypedEmitter.ts
@@ -0,0 +1,41 @@
+export type EventMap = {
+ [key: string]: (...args: any[]) => void;
+};
+
+/**
+ * Type-safe event emitter.
+ *
+ * Use it like this:
+ *
+ * ```typescript
+ * type MyEvents = {
+ * error: (error: Error) => void;
+ * message: (from: string, content: string) => void;
+ * }
+ *
+ * const myEmitter = new EventEmitter() as TypedEmitter<MyEvents>;
+ *
+ * myEmitter.emit("error", "x") // <- Will catch this type error;
+ * ```
+ */
+export interface TypedEventEmitter<Events extends EventMap> {
+ addListener<E extends keyof Events>(event: E, listener: Events[E]): this;
+ on<E extends keyof Events>(event: E, listener: Events[E]): this;
+ once<E extends keyof Events>(event: E, listener: Events[E]): this;
+ prependListener<E extends keyof Events>(event: E, listener: Events[E]): this;
+ prependOnceListener<E extends keyof Events>(event: E, listener: Events[E]): this;
+
+ off<E extends keyof Events>(event: E, listener: Events[E]): this;
+ removeAllListeners<E extends keyof Events>(event?: E): this;
+ removeListener<E extends keyof Events>(event: E, listener: Events[E]): this;
+
+ emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): boolean;
+ // The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5
+ eventNames(): (keyof Events | string | symbol)[];
+ rawListeners<E extends keyof Events>(event: E): Events[E][];
+ listeners<E extends keyof Events>(event: E): Events[E][];
+ listenerCount<E extends keyof Events>(event: E): number;
+
+ getMaxListeners(): number;
+ setMaxListeners(maxListeners: number): this;
+}
diff --git a/src/util/util/imports/index.ts b/src/util/util/imports/index.ts
index 120cff11..844aee4f 100644
--- a/src/util/util/imports/index.ts
+++ b/src/util/util/imports/index.ts
@@ -1,3 +1,4 @@
export * from "./Checks";
export * from "./HTTPError";
export * from "./OrmUtils";
+export * from "./TypedEmitter";
|