Files
moltbot/src/cli/program/route-specs.ts
2026-04-06 14:24:18 +01:00

57 lines
1.8 KiB
TypeScript

import { hasFlag } from "../argv.js";
import { cliCommandCatalog, type CliCommandCatalogEntry } from "../command-catalog.js";
import { matchesCommandPath } from "../command-path-matches.js";
import { resolveCliCommandPathPolicy } from "../command-path-policy.js";
import {
routedCommandDefinitions,
type RoutedCommandDefinition,
} from "./routed-command-definitions.js";
export type RouteSpec = {
match: (path: string[]) => boolean;
loadPlugins?: boolean | ((argv: string[]) => boolean);
run: (argv: string[]) => Promise<boolean>;
};
function createCommandLoadPlugins(commandPath: readonly string[]): (argv: string[]) => boolean {
return (argv) => {
const loadPlugins = resolveCliCommandPathPolicy([...commandPath]).loadPlugins;
return loadPlugins === "always" || (loadPlugins === "text-only" && !hasFlag(argv, "--json"));
};
}
function createParsedRoute(params: {
entry: CliCommandCatalogEntry;
definition: RoutedCommandDefinition;
}): RouteSpec {
return {
match: (path) =>
matchesCommandPath(path, params.entry.commandPath, { exact: params.entry.exact }),
loadPlugins: params.entry.route?.preloadPlugins
? createCommandLoadPlugins(params.entry.commandPath)
: undefined,
run: async (argv) => {
const args = params.definition.parseArgs(argv);
if (!args) {
return false;
}
await params.definition.runParsedArgs(args);
return true;
},
};
}
export const routedCommands: RouteSpec[] = cliCommandCatalog
.filter(
(
entry,
): entry is CliCommandCatalogEntry & { route: { id: keyof typeof routedCommandDefinitions } } =>
Boolean(entry.route),
)
.map((entry) =>
createParsedRoute({
entry,
definition: routedCommandDefinitions[entry.route.id] as RoutedCommandDefinition,
}),
);