2022-09-21 12:59:22 +00:00
|
|
|
import config from "../config.js";
|
2022-11-26 07:59:07 +00:00
|
|
|
import { getRpcServer } from "./rpc/server.js";
|
2022-08-29 02:40:25 +00:00
|
|
|
import type { PluginAPI, RPCMethod, Plugin } from "@lumeweb/relay-types";
|
2022-08-27 01:52:19 +00:00
|
|
|
import slugify from "slugify";
|
2022-08-28 04:26:24 +00:00
|
|
|
import * as fs from "fs";
|
|
|
|
import path from "path";
|
2022-09-09 09:17:25 +00:00
|
|
|
import {
|
|
|
|
getSavedSsl,
|
|
|
|
getSsl,
|
|
|
|
getSslContext,
|
|
|
|
saveSSl,
|
|
|
|
setSsl,
|
2022-09-21 11:31:29 +00:00
|
|
|
setSSlCheck,
|
2022-09-09 09:17:25 +00:00
|
|
|
setSslContext,
|
|
|
|
} from "./ssl.js";
|
|
|
|
import log from "loglevel";
|
2022-09-21 12:59:22 +00:00
|
|
|
import { getSeed } from "../lib/util.js";
|
2022-09-21 12:56:24 +00:00
|
|
|
import { getRouter, resetRouter, setRouter } from "./app.js";
|
2022-09-09 09:17:25 +00:00
|
|
|
import {
|
|
|
|
createIndependentFileSmall,
|
|
|
|
openIndependentFileSmall,
|
|
|
|
overwriteIndependentFileSmall,
|
2022-09-21 12:59:22 +00:00
|
|
|
} from "../lib/file";
|
2022-09-09 09:17:25 +00:00
|
|
|
import { setDnsProvider } from "./dns";
|
2022-11-26 07:59:07 +00:00
|
|
|
import pluginRpc from "./plugins/rpc";
|
|
|
|
import pluginCore from "./plugins/core";
|
2022-08-27 01:52:19 +00:00
|
|
|
|
2022-08-27 02:14:02 +00:00
|
|
|
let pluginApi: PluginApiManager;
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-28 04:26:24 +00:00
|
|
|
const paths = [];
|
|
|
|
for (const modulePath of [`${moduleName}.js`, `${moduleName}.mjs`]) {
|
2022-09-21 20:11:02 +00:00
|
|
|
const fullPath = path.join(config.get("plugindir"), modulePath);
|
2022-08-28 04:26:24 +00:00
|
|
|
if (fs.existsSync(fullPath)) {
|
|
|
|
paths.push(fullPath);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-08-27 01:52:19 +00:00
|
|
|
|
|
|
|
if (!paths.length) {
|
|
|
|
throw new Error(`Plugin ${moduleName} does not exist`);
|
|
|
|
}
|
|
|
|
|
|
|
|
let plugin: Plugin;
|
|
|
|
try {
|
2022-12-13 12:23:18 +00:00
|
|
|
plugin = require(paths.shift() as string) as Plugin;
|
2022-08-27 01:52:19 +00:00
|
|
|
} catch (e) {
|
|
|
|
throw e;
|
|
|
|
}
|
2022-11-26 07:59:07 +00:00
|
|
|
|
|
|
|
return this.loadPluginInstance(plugin);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async loadPluginInstance(plugin: Plugin): Promise<Plugin> {
|
2022-08-28 04:27:20 +00:00
|
|
|
if ("default" in plugin) {
|
|
|
|
plugin = plugin?.default as Plugin;
|
|
|
|
}
|
2022-08-27 01:52:19 +00:00
|
|
|
|
|
|
|
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-29 02:39:51 +00:00
|
|
|
loadPlugin: getPluginAPI().loadPlugin.bind(getPluginAPI()),
|
2022-11-26 07:59:07 +00:00
|
|
|
getRpcServer,
|
2022-09-09 09:17:25 +00:00
|
|
|
ssl: {
|
|
|
|
setContext: setSslContext,
|
|
|
|
getContext: getSslContext,
|
|
|
|
getSaved: getSavedSsl,
|
|
|
|
set: setSsl,
|
|
|
|
get: getSsl,
|
|
|
|
save: saveSSl,
|
2022-09-21 11:31:29 +00:00
|
|
|
setCheck: setSSlCheck,
|
2022-09-09 09:17:25 +00:00
|
|
|
},
|
|
|
|
files: {
|
|
|
|
createIndependentFileSmall,
|
|
|
|
openIndependentFileSmall,
|
|
|
|
overwriteIndependentFileSmall,
|
|
|
|
},
|
|
|
|
dns: {
|
|
|
|
setProvider: setDnsProvider,
|
|
|
|
},
|
|
|
|
logger: log,
|
|
|
|
getSeed,
|
|
|
|
appRouter: {
|
|
|
|
get: getRouter,
|
|
|
|
set: setRouter,
|
|
|
|
reset: resetRouter,
|
|
|
|
},
|
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-11-26 07:59:07 +00:00
|
|
|
const api = await getPluginAPI();
|
|
|
|
|
|
|
|
api.loadPluginInstance(pluginCore);
|
|
|
|
api.loadPluginInstance(pluginRpc);
|
|
|
|
|
2022-09-21 20:03:12 +00:00
|
|
|
for (const plugin of [...new Set(config.array("plugins", []))] as []) {
|
2022-11-26 07:59:07 +00:00
|
|
|
api.loadPlugin(plugin);
|
2022-08-27 01:52:19 +00:00
|
|
|
}
|
|
|
|
}
|