First build

This commit is contained in:
Lucid Kobold
2025-02-19 11:11:47 -05:00
43 changed files with 4061 additions and 7177 deletions

View File

@@ -1,102 +1,98 @@
import type { Bot } from '#root/bot/index.js'
import type { Config } from '#root/config.js'
import type { Logger } from '#root/logger.js'
import type { Env } from '#root/server/environment.js'
import { setLogger } from '#root/server/middlewares/logger.js'
import { requestId } from '#root/server/middlewares/request-id.js'
import { requestLogger } from '#root/server/middlewares/request-logger.js'
import { serve } from '@hono/node-server'
import { webhookCallback } from 'grammy'
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
import { getPath } from 'hono/utils/url'
import type { Bot } from "#root/bot/index.js";
import type { Config } from "#root/config.js";
import type { Logger } from "#root/logger.js";
import type { Env } from "#root/server/environment.js";
import { setLogger } from "#root/server/middlewares/logger.js";
import { requestId } from "#root/server/middlewares/request-id.js";
import { requestLogger } from "#root/server/middlewares/request-logger.js";
import { serve } from "@hono/node-server";
import { webhookCallback } from "grammy";
import { Hono } from "hono";
import { HTTPException } from "hono/http-exception";
import { getPath } from "hono/utils/url";
interface Dependencies {
bot: Bot
config: Config
logger: Logger
bot: Bot;
config: Config;
logger: Logger;
}
export function createServer(dependencies: Dependencies) {
const {
bot,
config,
logger,
} = dependencies
const { bot, config, logger } = dependencies;
const server = new Hono<Env>()
const server = new Hono<Env>();
server.use(requestId())
server.use(setLogger(logger))
if (config.isDebug)
server.use(requestLogger())
server.use(requestId());
server.use(setLogger(logger));
if (config.isDebug) server.use(requestLogger());
server.onError(async (error, c) => {
if (error instanceof HTTPException) {
if (error.status < 500)
c.var.logger.info(error)
else
c.var.logger.error(error)
if (error.status < 500) c.var.logger.info(error);
else c.var.logger.error(error);
return error.getResponse()
return error.getResponse();
}
// unexpected error
c.var.logger.error({
err: error,
method: c.req.raw.method,
path: getPath(c.req.raw),
})
path: getPath(c.req.raw)
});
return c.json(
{
error: 'Oops! Something went wrong.',
error: "Oops! Something went wrong."
},
500,
)
})
500
);
});
server.get('/', c => c.json({ status: true }))
server.get("/", c => c.json({ status: true }));
if (config.isWebhookMode) {
server.post(
'/webhook',
webhookCallback(bot, 'hono', {
secretToken: config.botWebhookSecret,
}),
)
"/webhook",
webhookCallback(bot, "hono", {
secretToken: config.botWebhookSecret
})
);
}
return server
return server;
}
export type Server = Awaited<ReturnType<typeof createServer>>
export type Server = Awaited<ReturnType<typeof createServer>>;
export function createServerManager(server: Server, options: { host: string, port: number }) {
let handle: undefined | ReturnType<typeof serve>
export function createServerManager(
server: Server,
options: { host: string; port: number }
) {
let handle: undefined | ReturnType<typeof serve>;
return {
start() {
return new Promise<{ url: string }>((resolve) => {
return new Promise<{ url: string }>(resolve => {
handle = serve(
{
fetch: server.fetch,
hostname: options.host,
port: options.port,
port: options.port
},
info => resolve({
url: info.family === 'IPv6'
? `http://[${info.address}]:${info.port}`
: `http://${info.address}:${info.port}`,
}),
)
})
info =>
resolve({
url:
info.family === "IPv6"
? `http://[${info.address}]:${info.port}`
: `http://${info.address}:${info.port}`
})
);
});
},
stop() {
return new Promise<void>((resolve) => {
if (handle)
handle.close(() => resolve())
else
resolve()
})
},
}
return new Promise<void>(resolve => {
if (handle) handle.close(() => resolve());
else resolve();
});
}
};
}