refactor(cli): centralize Clack prompt handling

This commit is contained in:
Andrey Avtomonov 2026-05-12 11:31:43 +02:00
parent 9409d50d1d
commit 42365481ac
3 changed files with 106 additions and 12 deletions

View file

@ -1,4 +1,4 @@
import { spinner } from '@clack/prompts';
import { cancel, confirm, isCancel, log, spinner } from '@clack/prompts';
export interface KtxCliSpinner {
start(message: string): void;
@ -6,6 +6,62 @@ export interface KtxCliSpinner {
error(message: string): void;
}
export interface KtxCliPromptAdapter {
confirm(options: { message: string; initialValue?: boolean }): Promise<boolean>;
cancel(message: string): void;
log: {
info(message: string): void;
warn(message: string): void;
error(message: string): void;
success(message: string): void;
step(message: string): void;
};
spinner(): KtxCliSpinner;
}
export class KtxCliPromptCancelledError extends Error {
constructor(message = 'Operation cancelled.') {
super(message);
this.name = 'KtxCliPromptCancelledError';
}
}
export function createClackSpinner(): KtxCliSpinner {
return spinner();
}
export function createClackPromptAdapter(): KtxCliPromptAdapter {
return {
async confirm(options) {
const value = await confirm(options);
if (isCancel(value)) {
cancel('Operation cancelled.');
throw new KtxCliPromptCancelledError();
}
return value;
},
cancel(message) {
cancel(message);
},
log: {
info(message) {
log.info(message);
},
warn(message) {
log.warn(message);
},
error(message) {
log.error(message);
},
success(message) {
log.success(message);
},
step(message) {
log.step(message);
},
},
spinner() {
return createClackSpinner();
},
};
}