@api-buddy/plugin-utils
Version:
Shared utilities for API Buddy plugins
148 lines (132 loc) • 3 kB
text/typescript
import type { Color, Ora, SpinnerName } from 'ora';
import chalk from 'chalk';
import inquirer from 'inquirer';
// Import ora dynamically to handle ESM
let ora: typeof import('ora').default;
// Lazy load ora to avoid loading it when not needed
async function getOra() {
if (!ora) {
ora = (await import('ora')).default;
}
return ora;
}
type SpinnerOptions = {
text: string;
color?: Color;
spinner?: SpinnerName;
};
export class Spinner {
private spinner: Ora | null = null;
private isActive = false;
async start({ text, color = 'blue', spinner = 'dots' }: SpinnerOptions): Promise<void> {
const oraInstance = await getOra();
if (this.isActive) {
this.stop();
}
this.spinner = oraInstance({
text,
spinner,
color,
} as any).start();
this.isActive = true;
}
updateText(text: string): void {
if (this.spinner && this.isActive) {
this.spinner.text = text;
}
}
succeed(text?: string): void {
if (this.spinner && this.isActive) {
this.spinner.succeed(text);
this.isActive = false;
}
}
fail(text?: string): void {
if (this.spinner && this.isActive) {
this.spinner.fail(text);
this.isActive = false;
}
}
warn(text: string): void {
if (this.spinner && this.isActive) {
this.spinner.warn(text);
this.isActive = false;
}
}
stop(): void {
if (this.spinner && this.isActive) {
this.spinner.stop();
this.isActive = false;
}
}
}
export async function confirm(
message: string,
defaultValue = false
): Promise<boolean> {
const { confirmed } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirmed',
message,
default: defaultValue,
},
]);
return confirmed;
}
export async function select<T = string>(
message: string,
choices: Array<{ name: string; value: T; description?: string }>,
pageSize = 10
): Promise<T> {
const { result } = await inquirer.prompt([
{
type: 'list',
name: 'result',
message,
choices: choices.map((choice) => ({
name: choice.name,
value: choice.value,
short: choice.name,
})),
pageSize,
},
]);
return result;
}
export async function input(
message: string,
defaultValue?: string,
validate?: (input: string) => boolean | string
): Promise<string> {
const { result } = await inquirer.prompt([
{
type: 'input',
name: 'result',
message,
default: defaultValue,
validate: validate ? (input) => {
const result = validate(input);
if (typeof result === 'string') {
return result;
}
return result || 'Invalid input';
} : undefined,
},
]);
return result;
}
export const ui = {
Spinner,
confirm,
select,
input,
colors: {
success: chalk.green,
error: chalk.red,
warning: chalk.yellow,
info: chalk.blue,
highlight: chalk.cyan,
},
};
export default ui;