From c04ad89a863f2c0e548b96e11d130ce372324719 Mon Sep 17 00:00:00 2001 From: dswbx Date: Fri, 29 Aug 2025 09:40:27 +0200 Subject: [PATCH] cli: align config aware commands options --- app/src/cli/commands/config.ts | 6 ++---- app/src/cli/commands/mcp/mcp.ts | 22 ++++++++++------------ app/src/cli/commands/run/run.ts | 14 ++++---------- app/src/cli/commands/sync.ts | 6 ++---- app/src/cli/commands/types/types.ts | 22 ++++++++++++---------- app/src/cli/commands/user.ts | 8 +++----- app/src/cli/utils/options.ts | 16 ++++++++++++++++ 7 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 app/src/cli/utils/options.ts diff --git a/app/src/cli/commands/config.ts b/app/src/cli/commands/config.ts index 24d7e49..154453f 100644 --- a/app/src/cli/commands/config.ts +++ b/app/src/cli/commands/config.ts @@ -3,16 +3,14 @@ import type { CliCommand } from "../types"; import { makeAppFromEnv } from "cli/commands/run"; import { writeFile } from "node:fs/promises"; import c from "picocolors"; +import { withConfigOptions } from "cli/utils/options"; export const config: CliCommand = (program) => { - program - .command("config") + withConfigOptions(program.command("config")) .description("get app config") .option("--pretty", "pretty print") .option("--default", "use default config") .option("--secrets", "include secrets in output") - .option("--config ", "config file") - .option("--db-url ", "database url, can be any valid sqlite url") .option("--out ", "output file") .action(async (options) => { let config: any = {}; diff --git a/app/src/cli/commands/mcp/mcp.ts b/app/src/cli/commands/mcp/mcp.ts index 23e7357..0ec0564 100644 --- a/app/src/cli/commands/mcp/mcp.ts +++ b/app/src/cli/commands/mcp/mcp.ts @@ -2,13 +2,11 @@ import type { CliCommand } from "cli/types"; import { makeAppFromEnv } from "../run"; import { getSystemMcp } from "modules/mcp/system-mcp"; import { $console, stdioTransport } from "bknd/utils"; +import { withConfigOptions, type WithConfigOptions } from "cli/utils/options"; export const mcp: CliCommand = (program) => - program - .command("mcp") + withConfigOptions(program.command("mcp")) .description("mcp server stdio transport") - .option("--config ", "config file") - .option("--db-url ", "database url, can be any valid sqlite url") .option( "--token ", "token to authenticate requests, if not provided, uses BEARER_TOKEN environment variable", @@ -18,14 +16,14 @@ export const mcp: CliCommand = (program) => .option("--force", "force enable mcp") .action(action); -async function action(options: { - verbose?: boolean; - config?: string; - dbUrl?: string; - token?: string; - logLevel?: string; - force?: boolean; -}) { +async function action( + options: WithConfigOptions<{ + verbose?: boolean; + token?: string; + logLevel?: string; + force?: boolean; + }>, +) { const verbose = !!options.verbose; const __oldConsole = { ...console }; diff --git a/app/src/cli/commands/run/run.ts b/app/src/cli/commands/run/run.ts index 23e0caf..0e4efb0 100644 --- a/app/src/cli/commands/run/run.ts +++ b/app/src/cli/commands/run/run.ts @@ -17,6 +17,7 @@ import { } from "./platform"; import { createRuntimeApp, makeConfig } from "bknd/adapter"; import { colorizeConsole, isBun } from "bknd/utils"; +import { withConfigOptions, type WithConfigOptions } from "cli/utils/options"; const env_files = [".env", ".dev.vars"]; dotenv.config({ @@ -25,8 +26,7 @@ dotenv.config({ const is_bun = isBun(); export const run: CliCommand = (program) => { - program - .command("run") + withConfigOptions(program.command("run")) .description("run an instance") .addOption( new Option("-p, --port ", "port to run on") @@ -41,12 +41,6 @@ export const run: CliCommand = (program) => { "db-token", ]), ) - .addOption(new Option("-c, --config ", "config file")) - .addOption( - new Option("--db-url ", "database url, can be any valid sqlite url").conflicts( - "config", - ), - ) .addOption( new Option("--server ", "server type") .choices(PLATFORMS) @@ -84,14 +78,14 @@ export async function makeConfigApp(_config: CliBkndConfig, platform?: Platform) }); } -type RunOptions = { +type RunOptions = WithConfigOptions<{ port: number; memory?: boolean; config?: string; dbUrl?: string; server: Platform; open?: boolean; -}; +}>; export async function makeAppFromEnv(options: Partial = {}) { const configFilePath = await getConfigPath(options.config); diff --git a/app/src/cli/commands/sync.ts b/app/src/cli/commands/sync.ts index abb16ec..d9b3ed5 100644 --- a/app/src/cli/commands/sync.ts +++ b/app/src/cli/commands/sync.ts @@ -2,13 +2,11 @@ import type { CliCommand } from "../types"; import { makeAppFromEnv } from "cli/commands/run"; import { writeFile } from "node:fs/promises"; import c from "picocolors"; +import { withConfigOptions } from "cli/utils/options"; export const sync: CliCommand = (program) => { - program - .command("sync") + withConfigOptions(program.command("sync")) .description("sync database") - .option("--config ", "config file") - .option("--db-url ", "database url, can be any valid sqlite url") .option("--dump", "dump operations to console instead of executing them") .option("--drop", "include destructive DDL operations") .option("--out ", "output file") diff --git a/app/src/cli/commands/types/types.ts b/app/src/cli/commands/types/types.ts index c2e8a78..b545d61 100644 --- a/app/src/cli/commands/types/types.ts +++ b/app/src/cli/commands/types/types.ts @@ -4,33 +4,35 @@ import { makeAppFromEnv } from "cli/commands/run"; import { EntityTypescript } from "data/entities/EntityTypescript"; import { writeFile } from "cli/utils/sys"; import c from "picocolors"; +import { withConfigOptions, type WithConfigOptions } from "cli/utils/options"; export const types: CliCommand = (program) => { - program - .command("types") + withConfigOptions(program.command("types")) .description("generate types") .addOption(new Option("-o, --outfile ", "output file").default("bknd-types.d.ts")) - .addOption(new Option("--no-write", "do not write to file").default(true)) + .addOption(new Option("--dump", "dump types to console instead of writing to file")) .action(action); }; async function action({ outfile, - write, -}: { + dump, + ...options +}: WithConfigOptions<{ outfile: string; - write: boolean; -}) { + dump: boolean; +}>) { const app = await makeAppFromEnv({ server: "node", + ...options, }); const et = new EntityTypescript(app.em); - if (write) { + if (dump) { + console.info(et.toString()); + } else { await writeFile(outfile, et.toString()); console.info(`\nTypes written to ${c.cyan(outfile)}`); - } else { - console.info(et.toString()); } } diff --git a/app/src/cli/commands/user.ts b/app/src/cli/commands/user.ts index d85dab0..fb4bd4a 100644 --- a/app/src/cli/commands/user.ts +++ b/app/src/cli/commands/user.ts @@ -11,20 +11,18 @@ import type { CliCommand } from "cli/types"; import { Argument } from "commander"; import { $console, isBun } from "bknd/utils"; import c from "picocolors"; +import { withConfigOptions, type WithConfigOptions } from "cli/utils/options"; export const user: CliCommand = (program) => { - program - .command("user") + withConfigOptions(program.command("user")) .description("create/update users, or generate a token (auth)") .addArgument( new Argument("", "action to perform").choices(["create", "update", "token"]), ) - .option("--config ", "config file") - .option("--db-url ", "database url, can be any valid sqlite url") .action(action); }; -async function action(action: "create" | "update" | "token", options: any) { +async function action(action: "create" | "update" | "token", options: WithConfigOptions) { const app = await makeAppFromEnv({ config: options.config, dbUrl: options.dbUrl, diff --git a/app/src/cli/utils/options.ts b/app/src/cli/utils/options.ts new file mode 100644 index 0000000..26a9abb --- /dev/null +++ b/app/src/cli/utils/options.ts @@ -0,0 +1,16 @@ +import { type Command, Option } from "commander"; + +export function withConfigOptions(program: Command) { + return program + .addOption(new Option("-c, --config ", "config file")) + .addOption( + new Option("--db-url ", "database url, can be any valid sqlite url").conflicts( + "config", + ), + ); +} + +export type WithConfigOptions = { + config?: string; + dbUrl?: string; +} & CustomOptions;