diff options
-rw-r--r-- | src/util/plugin/Plugin.ts | 18 | ||||
-rw-r--r-- | src/util/plugin/PluginLoader.ts | 53 | ||||
-rw-r--r-- | src/util/util/imports/TypedEmitter.ts | 41 | ||||
-rw-r--r-- | src/util/util/imports/index.ts | 1 |
4 files changed, 85 insertions, 28 deletions
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"; |