mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
153 lines
4.6 KiB
TypeScript
153 lines
4.6 KiB
TypeScript
import type { Config } from "@libsql/client/node";
|
|
import { App, type CreateAppConfig } from "App";
|
|
import { StorageLocalAdapter } from "adapter/node";
|
|
import type { CliBkndConfig, CliCommand } from "cli/types";
|
|
import { Option } from "commander";
|
|
import { colorizeConsole, config } from "core";
|
|
import dotenv from "dotenv";
|
|
import { registries } from "modules/registries";
|
|
import c from "picocolors";
|
|
import {
|
|
PLATFORMS,
|
|
type Platform,
|
|
attachServeStatic,
|
|
getConfigPath,
|
|
getConnectionCredentialsFromEnv,
|
|
startServer,
|
|
} from "./platform";
|
|
|
|
dotenv.config();
|
|
const isBun = typeof Bun !== "undefined";
|
|
|
|
export const run: CliCommand = (program) => {
|
|
program
|
|
.command("run")
|
|
.description("run an instance")
|
|
.addOption(
|
|
new Option("-p, --port <port>", "port to run on")
|
|
.env("PORT")
|
|
.default(config.server.default_port)
|
|
.argParser((v) => Number.parseInt(v)),
|
|
)
|
|
.addOption(
|
|
new Option("-m, --memory", "use in-memory database").conflicts([
|
|
"config",
|
|
"db-url",
|
|
"db-token",
|
|
]),
|
|
)
|
|
.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"),
|
|
)
|
|
.addOption(new Option("--no-open", "don't open browser window on start"))
|
|
.action(action);
|
|
};
|
|
|
|
// automatically register local adapter
|
|
const local = StorageLocalAdapter.prototype.getName();
|
|
if (!registries.media.has(local)) {
|
|
registries.media.register(local, StorageLocalAdapter);
|
|
}
|
|
|
|
type MakeAppConfig = {
|
|
connection?: CreateAppConfig["connection"];
|
|
server?: { platform?: Platform };
|
|
setAdminHtml?: boolean;
|
|
onBuilt?: (app: App) => Promise<void>;
|
|
};
|
|
|
|
async function makeApp(config: MakeAppConfig) {
|
|
const app = App.create({ connection: config.connection });
|
|
|
|
app.emgr.onEvent(
|
|
App.Events.AppBuiltEvent,
|
|
async () => {
|
|
await attachServeStatic(app, config.server?.platform ?? "node");
|
|
app.registerAdminController();
|
|
|
|
if (config.onBuilt) {
|
|
await config.onBuilt(app);
|
|
}
|
|
},
|
|
"sync",
|
|
);
|
|
|
|
await app.build();
|
|
return app;
|
|
}
|
|
|
|
export async function makeConfigApp(config: CliBkndConfig, platform?: Platform) {
|
|
const appConfig = typeof config.app === "function" ? config.app(process.env) : config.app;
|
|
const app = App.create(appConfig);
|
|
|
|
app.emgr.onEvent(
|
|
App.Events.AppBuiltEvent,
|
|
async () => {
|
|
await attachServeStatic(app, platform ?? "node");
|
|
app.registerAdminController();
|
|
|
|
await config.onBuilt?.(app);
|
|
},
|
|
"sync",
|
|
);
|
|
|
|
await config.beforeBuild?.(app);
|
|
await app.build(config.buildConfig);
|
|
return app;
|
|
}
|
|
|
|
async function action(options: {
|
|
port: number;
|
|
memory?: boolean;
|
|
config?: string;
|
|
dbUrl?: string;
|
|
dbToken?: string;
|
|
server: Platform;
|
|
open?: boolean;
|
|
}) {
|
|
colorizeConsole(console);
|
|
const configFilePath = await getConfigPath(options.config);
|
|
|
|
let app: App | undefined = undefined;
|
|
if (options.dbUrl) {
|
|
console.info("Using connection from", c.cyan("--db-url"));
|
|
const connection = options.dbUrl
|
|
? { url: options.dbUrl, authToken: options.dbToken }
|
|
: undefined;
|
|
app = await makeApp({ connection, server: { platform: options.server } });
|
|
} else if (configFilePath) {
|
|
console.info("Using config from", c.cyan(configFilePath));
|
|
const config = (await import(configFilePath).then((m) => m.default)) as CliBkndConfig;
|
|
app = await makeConfigApp(config, options.server);
|
|
} else if (options.memory) {
|
|
console.info("Using", c.cyan("in-memory"), "connection");
|
|
app = await makeApp({ server: { platform: options.server } });
|
|
} else {
|
|
const credentials = getConnectionCredentialsFromEnv();
|
|
if (credentials) {
|
|
console.info("Using connection from env", c.cyan(credentials.url));
|
|
app = await makeConfigApp({ app: { connection: credentials } }, options.server);
|
|
}
|
|
}
|
|
|
|
if (!app) {
|
|
const connection = { url: "file:data.db" } as Config;
|
|
console.info("Using connection", c.cyan(connection.url));
|
|
app = await makeApp({
|
|
connection,
|
|
server: { platform: options.server },
|
|
});
|
|
}
|
|
|
|
await startServer(options.server, app, { port: options.port, open: options.open });
|
|
}
|