refactor(plugin): ♻️ Move plugin loading to PluginLoader class

This commit is contained in:
Jesse Wierzbinski 2024-11-10 13:08:26 +01:00
parent 95b8eb6e20
commit 3ec5118771
No known key found for this signature in database
3 changed files with 63 additions and 22 deletions

27
app.ts
View file

@ -11,7 +11,6 @@ import { OpenAPIHono } from "@hono/zod-openapi";
/* import { prometheus } from "@hono/prometheus"; */ /* import { prometheus } from "@hono/prometheus"; */
import { getLogger } from "@logtape/logtape"; import { getLogger } from "@logtape/logtape";
import chalk from "chalk"; import chalk from "chalk";
import type { ValidationError } from "zod-validation-error";
import pkg from "~/package.json" with { type: "application/json" }; import pkg from "~/package.json" with { type: "application/json" };
import { config } from "~/packages/config-manager/index.ts"; import { config } from "~/packages/config-manager/index.ts";
import { PluginLoader } from "./classes/plugin/loader.ts"; import { PluginLoader } from "./classes/plugin/loader.ts";
@ -117,6 +116,8 @@ export const appFactory = async (): Promise<OpenAPIHono<HonoEnv>> => {
serverLogger.info`Loading plugins`; serverLogger.info`Loading plugins`;
const time1 = performance.now();
const loader = new PluginLoader(); const loader = new PluginLoader();
const plugins = await loader.loadPlugins( const plugins = await loader.loadPlugins(
@ -126,27 +127,13 @@ export const appFactory = async (): Promise<OpenAPIHono<HonoEnv>> => {
config.plugins?.overrides.disabled, config.plugins?.overrides.disabled,
); );
for (const data of plugins) { await PluginLoader.addToApp(plugins, app, serverLogger);
serverLogger.info`Loading plugin ${chalk.blueBright(data.manifest.name)} ${chalk.blueBright(data.manifest.version)} ${chalk.gray(`[${plugins.indexOf(data) + 1}/${plugins.length}]`)}`;
try {
// biome-ignore lint/complexity/useLiteralKeys: loadConfig is a private method
await data.plugin["_loadConfig"](
config.plugins?.config?.[data.manifest.name],
);
} catch (e) {
serverLogger.fatal`Plugin configuration is invalid: ${chalk.redBright(e as ValidationError)}`;
serverLogger.fatal`Put your configuration at ${chalk.blueBright(
"plugins.config.<plugin-name>",
)}`;
await Bun.sleep(Number.POSITIVE_INFINITY); const time2 = performance.now();
}
// biome-ignore lint/complexity/useLiteralKeys: AddToApp is a private method serverLogger.info`Plugins loaded in ${`${chalk.gray(
await data.plugin["_addToApp"](app); (time2 - time1).toFixed(2),
} )}ms`}`;
serverLogger.info`Plugins loaded`;
app.doc31("/openapi.json", { app.doc31("/openapi.json", {
openapi: "3.1.0", openapi: "3.1.0",

View file

@ -1,11 +1,14 @@
import { readdir } from "node:fs/promises"; import { readdir } from "node:fs/promises";
import { getLogger } from "@logtape/logtape"; import type { OpenAPIHono } from "@hono/zod-openapi";
import { type Logger, getLogger } from "@logtape/logtape";
import chalk from "chalk"; import chalk from "chalk";
import { parseJSON5, parseJSONC } from "confbox"; import { parseJSON5, parseJSONC } from "confbox";
import type { ZodTypeAny } from "zod"; import type { ZodTypeAny } from "zod";
import { fromZodError } from "zod-validation-error"; import { type ValidationError, fromZodError } from "zod-validation-error";
import { config } from "~/packages/config-manager";
import { Plugin } from "~/packages/plugin-kit/plugin"; import { Plugin } from "~/packages/plugin-kit/plugin";
import { type Manifest, manifestSchema } from "~/packages/plugin-kit/schema"; import { type Manifest, manifestSchema } from "~/packages/plugin-kit/schema";
import type { HonoEnv } from "~/types/api";
/** /**
* Class to manage plugins. * Class to manage plugins.
@ -207,4 +210,46 @@ export class PluginLoader {
}), }),
).then((data) => data.filter((d) => d !== null)); ).then((data) => data.filter((d) => d !== null));
} }
public static async addToApp(
plugins: {
manifest: Manifest;
plugin: Plugin<ZodTypeAny>;
}[],
app: OpenAPIHono<HonoEnv>,
logger: Logger,
): Promise<void> {
for (const data of plugins) {
logger.info`Loading plugin ${chalk.blueBright(data.manifest.name)} ${chalk.blueBright(data.manifest.version)} ${chalk.gray(`[${plugins.indexOf(data) + 1}/${plugins.length}]`)}`;
const time1 = performance.now();
try {
// biome-ignore lint/complexity/useLiteralKeys: loadConfig is a private method
await data.plugin["_loadConfig"](
config.plugins?.config?.[data.manifest.name],
);
} catch (e) {
logger.fatal`Plugin configuration is invalid: ${chalk.redBright(e as ValidationError)}`;
logger.fatal`Put your configuration at ${chalk.blueBright(
"plugins.config.<plugin-name>",
)}`;
await Bun.sleep(Number.POSITIVE_INFINITY);
}
const time2 = performance.now();
// biome-ignore lint/complexity/useLiteralKeys: AddToApp is a private method
await data.plugin["_addToApp"](app);
const time3 = performance.now();
logger.info`Plugin ${chalk.blueBright(data.manifest.name)} ${chalk.blueBright(
data.manifest.version,
)} loaded in ${chalk.gray(
`${(time2 - time1).toFixed(2)}ms`,
)} and added to app in ${chalk.gray(`${(time3 - time2).toFixed(2)}ms`)}`;
}
}
} }

View file

@ -12,6 +12,15 @@ await configureLoggers();
const serverLogger = getLogger("server"); const serverLogger = getLogger("server");
console.info(`
`);
serverLogger.info`Starting Versia Server...`; serverLogger.info`Starting Versia Server...`;
await setupDatabase(); await setupDatabase();