UNPKG

@kubb/ui

Version:

User interface components and web dashboard for Kubb, providing a visual interface for managing and monitoring code generation.

121 lines (117 loc) 3.26 kB
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; import { serve } from "@hono/node-server"; import { cors } from "hono/cors"; import fs from "node:fs"; import { Hono } from "hono"; import { createServer } from "node:http2"; import path from "node:path"; import { fileURLToPath } from "node:url"; //#region src/models/StatusSchema.ts const statusSchema = z.object({ name: z.string().optional(), percentages: z.record(z.string(), z.number()), executed: z.array(z.any()) }).openapi("Status"); //#endregion //#region package.json var version = "4.0.0"; //#endregion //#region src/server.ts const __dirname = path.dirname(fileURLToPath(import.meta.url)); const distPath = path.join(__dirname, "../static"); const statusRoute = createRoute({ method: "get", path: "/status", response: {}, responses: { 200: { content: { "application/json": { schema: statusSchema } }, description: "Retrieve the status" } } }); const restartRoute = createRoute({ method: "post", path: "/restart", response: {}, responses: { 200: { content: { "application/json": { schema: z.object({}) } }, description: "Restart creation" } } }); const stopRoute = createRoute({ method: "post", path: "/stop", response: {}, responses: { 200: { content: { "application/json": { schema: z.object({}) } }, description: "Stop creation" } } }); function findOpenPort(preferredPort) { return new Promise((resolve, reject) => { const server = createServer(); server.listen(preferredPort, () => { server.close(() => resolve(preferredPort)); }); server.on("error", async (err) => { if (err.code === "EADDRINUSE") resolve(findOpenPort(preferredPort + 1)); else reject(err); }); }); } async function startServer(options, listeningListener) { const { stop, restart, getMeta } = options; const app = new Hono(); const api = new OpenAPIHono(); api.use("*", cors()); api.openapi(statusRoute, (c) => { const meta = getMeta(); return c.json({ name: meta.name, percentages: meta.percentages, executed: [] }, 200); }); api.openapi(stopRoute, (c) => { stop(); return c.json({}, 200); }); api.openapi(restartRoute, (c) => { restart(); return c.json({}, 200); }); api.doc("/doc", { openapi: "3.0.0", info: { version, title: "Kubb ui" } }); app.route("/api", api); app.get("/*", async (c) => { const filePath = path.join(distPath, c.req.path); if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) return new Response(fs.readFileSync(filePath), { headers: { "Content-Type": getMimeType(filePath) } }); return new Response(fs.readFileSync(path.join(distPath, "index.html")), { headers: { "Content-Type": "text/html" } }); }); const getMimeType = (filePath) => { const ext = path.extname(filePath).toLowerCase(); return { ".html": "text/html", ".js": "text/javascript", ".css": "text/css", ".json": "application/json", ".png": "image/png", ".jpg": "image/jpeg", ".gif": "image/gif", ".svg": "image/svg+xml", ".ico": "image/x-icon" }[ext] || "application/octet-stream"; }; const port = await findOpenPort(5822); return serve({ fetch: app.fetch, port }, listeningListener); } //#endregion export { startServer }; //# sourceMappingURL=index.js.map