2022-08-27 01:52:19 +00:00
|
|
|
import config from "./config.js";
|
|
|
|
import { getRpcServer } from "./rpc/server.js";
|
2022-08-27 02:14:02 +00:00
|
|
|
import { PluginAPI, RPCMethod, Plugin } from "./types.js";
|
2022-08-27 01:52:19 +00:00
|
|
|
import slugify from "slugify";
|
2022-08-28 02:24:43 +00:00
|
|
|
import { dynImport } from "./util";
|
2022-08-27 01:52:19 +00:00
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
let pluginApi: PluginApiManager;
|
2022-08-28 02:24:43 +00:00
|
|
|
let globby: typeof import("globby").globby;
|
2022-08-27 01:52:19 +00:00
|
|
|
|
|
|
|
const sanitizeName = (name: string) =>
|
|
|
|
slugify(name, { lower: true, strict: true });
|
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
export class PluginApiManager {
|
2022-08-27 01:52:19 +00:00
|
|
|
private registeredPlugins: Map<string, Plugin> = new Map<string, Plugin>();
|
|
|
|
|
|
|
|
public async loadPlugin(moduleName: string): Promise<Plugin> {
|
|
|
|
moduleName = sanitizeName(moduleName);
|
|
|
|
|
|
|
|
if (this.registeredPlugins.has(moduleName)) {
|
|
|
|
return this.registeredPlugins.get(moduleName) as Plugin;
|
|
|
|
}
|
|
|
|
|
|
|
|
const paths = await globby([`${moduleName}.js`, "${moduleName}.mjs"], {
|
|
|
|
cwd: config.get("plugin-folder"),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!paths.length) {
|
|
|
|
throw new Error(`Plugin ${moduleName} does not exist`);
|
|
|
|
}
|
|
|
|
|
|
|
|
let plugin: Plugin;
|
|
|
|
try {
|
|
|
|
plugin = (await import(paths.shift() as string)) as Plugin;
|
|
|
|
} catch (e) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
|
|
|
|
plugin.name = sanitizeName(plugin.name);
|
|
|
|
|
|
|
|
this.registeredPlugins.set(plugin.name, plugin);
|
|
|
|
|
|
|
|
try {
|
|
|
|
plugin.plugin(this.getPluginAPI(plugin.name));
|
|
|
|
} catch (e) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
|
|
|
|
return plugin;
|
|
|
|
}
|
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
private getPluginAPI(pluginName: string): PluginAPI {
|
2022-08-27 01:52:19 +00:00
|
|
|
return {
|
|
|
|
config,
|
2022-08-27 02:12:13 +00:00
|
|
|
registerMethod: (methodName: string, method: RPCMethod): void => {
|
|
|
|
getRpcServer().registerMethod(pluginName, methodName, method);
|
2022-08-27 01:52:19 +00:00
|
|
|
},
|
2022-08-27 02:12:13 +00:00
|
|
|
loadPlugin: getPluginAPI().loadPlugin,
|
2022-08-27 02:38:32 +00:00
|
|
|
getMethods: getRpcServer().getMethods,
|
2022-08-27 01:52:19 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
export function getPluginAPI(): PluginApiManager {
|
2022-08-27 01:52:19 +00:00
|
|
|
if (!pluginApi) {
|
2022-08-27 02:14:02 +00:00
|
|
|
pluginApi = new PluginApiManager();
|
2022-08-27 01:52:19 +00:00
|
|
|
}
|
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
return pluginApi as PluginApiManager;
|
2022-08-27 01:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function loadPlugins() {
|
2022-08-28 02:24:43 +00:00
|
|
|
globby = ((await dynImport("globby")) as typeof import("globby")).globby;
|
2022-08-27 01:52:19 +00:00
|
|
|
for (const plugin of config.array("plugins")) {
|
|
|
|
await getPluginAPI().loadPlugin(plugin);
|
|
|
|
}
|
|
|
|
}
|