diff --git a/app.ts b/app.ts index 389226ce..242726de 100644 --- a/app.ts +++ b/app.ts @@ -11,7 +11,6 @@ import { OpenAPIHono } from "@hono/zod-openapi"; /* import { prometheus } from "@hono/prometheus"; */ import { getLogger } from "@logtape/logtape"; import chalk from "chalk"; -import type { ValidationError } from "zod-validation-error"; import pkg from "~/package.json" with { type: "application/json" }; import { config } from "~/packages/config-manager/index.ts"; import { PluginLoader } from "./classes/plugin/loader.ts"; @@ -117,6 +116,8 @@ export const appFactory = async (): Promise> => { serverLogger.info`Loading plugins`; + const time1 = performance.now(); + const loader = new PluginLoader(); const plugins = await loader.loadPlugins( @@ -126,27 +127,13 @@ export const appFactory = async (): Promise> => { config.plugins?.overrides.disabled, ); - for (const data of plugins) { - 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.", - )}`; + await PluginLoader.addToApp(plugins, app, serverLogger); - 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); - } - - serverLogger.info`Plugins loaded`; + serverLogger.info`Plugins loaded in ${`${chalk.gray( + (time2 - time1).toFixed(2), + )}ms`}`; app.doc31("/openapi.json", { openapi: "3.1.0", diff --git a/classes/plugin/loader.ts b/classes/plugin/loader.ts index 201195e8..ced3f0a4 100644 --- a/classes/plugin/loader.ts +++ b/classes/plugin/loader.ts @@ -1,11 +1,14 @@ 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 { parseJSON5, parseJSONC } from "confbox"; 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 { type Manifest, manifestSchema } from "~/packages/plugin-kit/schema"; +import type { HonoEnv } from "~/types/api"; /** * Class to manage plugins. @@ -207,4 +210,46 @@ export class PluginLoader { }), ).then((data) => data.filter((d) => d !== null)); } + + public static async addToApp( + plugins: { + manifest: Manifest; + plugin: Plugin; + }[], + app: OpenAPIHono, + logger: Logger, + ): Promise { + 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.", + )}`; + + 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`)}`; + } + } } diff --git a/setup.ts b/setup.ts index 415353a6..065790b0 100644 --- a/setup.ts +++ b/setup.ts @@ -12,6 +12,15 @@ await configureLoggers(); const serverLogger = getLogger("server"); +console.info(` +██╗ ██╗███████╗██████╗ ███████╗██╗ █████╗ +██║ ██║██╔════╝██╔══██╗██╔════╝██║██╔══██╗ +██║ ██║█████╗ ██████╔╝███████╗██║███████║ +╚██╗ ██╔╝██╔══╝ ██╔══██╗╚════██║██║██╔══██║ + ╚████╔╝ ███████╗██║ ██║███████║██║██║ ██║ + ╚═══╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═╝ +`); + serverLogger.info`Starting Versia Server...`; await setupDatabase();