56 lines
1.4 KiB
TypeScript
56 lines
1.4 KiB
TypeScript
import process from 'node:process';
|
|
|
|
/**
|
|
* Result from creating a prompt interface
|
|
*/
|
|
export interface IPromptInterface {
|
|
/** Function to prompt for user input */
|
|
prompt: (question: string) => Promise<string>;
|
|
/** Function to close the prompt interface */
|
|
close: () => void;
|
|
}
|
|
|
|
/**
|
|
* Create a readline prompt interface for interactive CLI input
|
|
* @returns Promise resolving to prompt function and close function
|
|
*/
|
|
export async function createPrompt(): Promise<IPromptInterface> {
|
|
const readline = await import('node:readline');
|
|
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
});
|
|
|
|
const prompt = (question: string): Promise<string> => {
|
|
return new Promise((resolve) => {
|
|
rl.question(question, (answer: string) => {
|
|
resolve(answer);
|
|
});
|
|
});
|
|
};
|
|
|
|
const close = (): void => {
|
|
rl.close();
|
|
process.stdin.destroy();
|
|
};
|
|
|
|
return { prompt, close };
|
|
}
|
|
|
|
/**
|
|
* Run an async function with a prompt interface, ensuring cleanup
|
|
* @param fn Function to run with the prompt interface
|
|
* @returns Promise resolving to the function's return value
|
|
*/
|
|
export async function withPrompt<T>(
|
|
fn: (prompt: (question: string) => Promise<string>) => Promise<T>,
|
|
): Promise<T> {
|
|
const { prompt, close } = await createPrompt();
|
|
try {
|
|
return await fn(prompt);
|
|
} finally {
|
|
close();
|
|
}
|
|
}
|