public commit

This commit is contained in:
dswbx
2024-11-16 12:01:47 +01:00
commit 90f80c4280
582 changed files with 49291 additions and 0 deletions

View File

@@ -0,0 +1 @@
export * from "./run";

View File

@@ -0,0 +1,96 @@
import { readFile } from "node:fs/promises";
import path from "node:path";
import type { ServeStaticOptions } from "@hono/node-server/serve-static";
import { type Config, createClient } from "@libsql/client/node";
import { Connection, LibsqlConnection, SqliteLocalConnection } from "data";
import type { MiddlewareHandler } from "hono";
import { fileExists, getDistPath, getRelativeDistPath } from "../../utils/sys";
export const PLATFORMS = ["node", "bun"] as const;
export type Platform = (typeof PLATFORMS)[number];
export async function serveStatic(server: Platform): Promise<MiddlewareHandler> {
switch (server) {
case "node": {
const m = await import("@hono/node-server/serve-static");
return m.serveStatic({
// somehow different for node
root: getRelativeDistPath() + "/static"
});
}
case "bun": {
const m = await import("hono/bun");
return m.serveStatic({
root: path.resolve(getRelativeDistPath(), "static")
});
}
}
}
export async function attachServeStatic(app: any, platform: Platform) {
app.module.server.client.get("/assets/*", await serveStatic(platform));
}
export async function startServer(server: Platform, app: any, options: { port: number }) {
const port = options.port;
console.log("running on", server, port);
switch (server) {
case "node": {
// https://github.com/honojs/node-server/blob/main/src/response.ts#L88
const serve = await import("@hono/node-server").then((m) => m.serve);
serve({
fetch: (req) => app.fetch(req),
port
});
break;
}
case "bun": {
Bun.serve({
fetch: (req) => app.fetch(req),
port
});
break;
}
}
console.log("Server listening on", "http://localhost:" + port);
}
export async function getHtml() {
return await readFile(path.resolve(getDistPath(), "static/index.html"), "utf-8");
}
export function getConnection(connectionOrConfig?: Connection | Config): Connection {
if (connectionOrConfig) {
if (connectionOrConfig instanceof Connection) {
return connectionOrConfig;
}
if ("url" in connectionOrConfig) {
return new LibsqlConnection(createClient(connectionOrConfig));
}
}
console.log("Using in-memory database");
return new LibsqlConnection(createClient({ url: ":memory:" }));
//return new SqliteLocalConnection(new Database(":memory:"));
}
export async function getConfigPath(filePath?: string) {
if (filePath) {
const config_path = path.resolve(process.cwd(), filePath);
if (await fileExists(config_path)) {
return config_path;
}
}
const paths = ["./bknd.config", "./bknd.config.ts", "./bknd.config.js"];
for (const p of paths) {
const _p = path.resolve(process.cwd(), p);
if (await fileExists(_p)) {
return _p;
}
}
return;
}

View File

@@ -0,0 +1,115 @@
import type { Config } from "@libsql/client/node";
import { App } from "App";
import type { BkndConfig } from "adapter";
import { Option } from "commander";
import type { Connection } from "data";
import type { CliCommand } from "../../types";
import {
PLATFORMS,
type Platform,
attachServeStatic,
getConfigPath,
getConnection,
getHtml,
startServer
} from "./platform";
const isBun = typeof Bun !== "undefined";
export const run: CliCommand = (program) => {
program
.command("run")
.addOption(
new Option("-p, --port <port>", "port to run on")
.env("PORT")
.default(1337)
.argParser((v) => Number.parseInt(v))
)
.addOption(new Option("-c, --config <config>", "config file"))
.addOption(
new Option("--db-url <db>", "database url, can be any valid libsql url").conflicts(
"config"
)
)
.addOption(new Option("--db-token <db>", "database token").conflicts("config"))
.addOption(
new Option("--server <server>", "server type")
.choices(PLATFORMS)
.default(isBun ? "bun" : "node")
)
.action(action);
};
type MakeAppConfig = {
connection: Connection;
server?: { platform?: Platform };
setAdminHtml?: boolean;
onBuilt?: (app: App) => Promise<void>;
};
async function makeApp(config: MakeAppConfig) {
const html = await getHtml();
const app = new App(config.connection);
app.emgr.on(
"app-built",
async () => {
await attachServeStatic(app, config.server?.platform ?? "node");
app.module.server.setAdminHtml(html);
if (config.onBuilt) {
await config.onBuilt(app);
}
},
"sync"
);
await app.build();
return app;
}
export async function makeConfigApp(config: BkndConfig, platform?: Platform) {
const appConfig = typeof config.app === "function" ? config.app(process.env) : config.app;
const html = await getHtml();
const app = App.create(appConfig);
app.emgr.on(
"app-built",
async () => {
await attachServeStatic(app, platform ?? "node");
app.module.server.setAdminHtml(html);
if (config.onBuilt) {
await config.onBuilt(app);
}
},
"sync"
);
await app.build();
return app;
}
async function action(options: {
port: number;
config?: string;
dbUrl?: string;
dbToken?: string;
server: Platform;
}) {
const configFilePath = await getConfigPath(options.config);
let app: App;
if (options.dbUrl || !configFilePath) {
const connection = getConnection(
options.dbUrl ? { url: options.dbUrl, authToken: options.dbToken } : undefined
);
app = await makeApp({ connection, server: { platform: options.server } });
} else {
console.log("Using config from:", configFilePath);
const config = (await import(configFilePath).then((m) => m.default)) as BkndConfig;
app = await makeConfigApp(config, options.server);
}
await startServer(options.server, app, { port: options.port });
}