UNPKG

@catladder/cli

Version:

Panter cli tool for cloud CI/CD and DevOps

89 lines (79 loc) 2.53 kB
import type { CommandDef, IO, InputDef, InputResultType, InputsSchema, } from "../core/types"; import { MissingInputError } from "../core/types"; import { BaseContext } from "./baseContext"; export interface ProgrammaticOptions { /** Pre-supplied values keyed by input name */ inputs?: Record<string, unknown>; /** Called on every log message. Defaults to no-op. */ onLog?: (message: string) => void; } class ProgrammaticContext< TInputs extends InputsSchema, > extends BaseContext<TInputs> { private inputs: Record<string, unknown>; private onLog?: (message: string) => void; constructor(command: CommandDef<TInputs>, options: ProgrammaticOptions) { super(command); this.inputs = options.inputs ?? {}; this.onLog = options.onLog; } log(message: string): void { this.onLog?.(message); } async confirm(): Promise<boolean> { return true; // programmatic mode always confirms } protected async resolveInput<P extends InputDef>( name: string, spec: P, ): Promise<InputResultType<P>> { if (name in this.inputs && this.inputs[name] !== undefined) { return this.inputs[name] as InputResultType<P>; } if ("default" in spec && spec.default !== undefined) { return spec.default as InputResultType<P>; } throw new MissingInputError(name, spec.message); } } /** * Create a CommandContext that resolves inputs from pre-supplied values. * Used for non-interactive CLI mode and programmatic invocation. */ export function createProgrammaticContext<TInputs extends InputsSchema>( command: CommandDef<TInputs>, options: ProgrammaticOptions = {}, ): ProgrammaticContext<TInputs> { return new ProgrammaticContext(command, options); } /** * Create a bare IO instance for helper functions that only need log + promptDirect. */ export function createProgrammaticIO(options: ProgrammaticOptions = {}): IO { const { inputs = {}, onLog } = options; return { log(message: string): void { onLog?.(message); }, async confirm(): Promise<boolean> { return true; }, async promptDirect<P extends InputDef>( spec: P & { name: string }, ): Promise<InputResultType<P>> { if (spec.name in inputs && inputs[spec.name] !== undefined) { return inputs[spec.name] as InputResultType<P>; } if ("default" in spec && spec.default !== undefined) { return spec.default as InputResultType<P>; } throw new MissingInputError(spec.name, spec.message); }, }; }