137 lines
3.2 KiB
TypeScript
137 lines
3.2 KiB
TypeScript
const reset = "\x1b[0m";
|
|
const boldCode = "\x1b[1m";
|
|
const dimCode = "\x1b[2m";
|
|
const redCode = "\x1b[31m";
|
|
const whiteCode = "\x1b[37m";
|
|
const cyanCode = "\x1b[36m";
|
|
const yellowCode = "\x1b[33m";
|
|
const bgRedCode = "\x1b[41m";
|
|
const dimGrayCode = "\x1b[38;5;102m";
|
|
const textGrayCode = "\x1b[38;5;145m";
|
|
const grayCode = "\x1b[38;5;245m";
|
|
const grayDarkCode = "\x1b[38;5;238m";
|
|
|
|
function wrap(text: string, ...codes: string[]) {
|
|
return `${codes.join("")}${text}${reset}`;
|
|
}
|
|
|
|
export function stripAnsi(text: string): string {
|
|
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
}
|
|
|
|
export function bold(text: string): string {
|
|
return wrap(text, boldCode);
|
|
}
|
|
|
|
export function dim(text: string): string {
|
|
return wrap(text, dimCode);
|
|
}
|
|
|
|
export function red(text: string): string {
|
|
return wrap(text, redCode);
|
|
}
|
|
|
|
export function white(text: string): string {
|
|
return wrap(text, whiteCode);
|
|
}
|
|
|
|
export function cyan(text: string): string {
|
|
return wrap(text, cyanCode);
|
|
}
|
|
|
|
export function yellow(text: string): string {
|
|
return wrap(text, yellowCode);
|
|
}
|
|
|
|
export function dimGray(text: string): string {
|
|
return wrap(text, dimGrayCode);
|
|
}
|
|
|
|
export function textGray(text: string): string {
|
|
return wrap(text, textGrayCode);
|
|
}
|
|
|
|
export function gray(text: string): string {
|
|
return wrap(text, grayCode);
|
|
}
|
|
|
|
export function grayDark(text: string): string {
|
|
return wrap(text, grayDarkCode);
|
|
}
|
|
|
|
export function errorBadge(text: string): string {
|
|
return wrap(` ${text} `, bgRedCode, whiteCode, boldCode);
|
|
}
|
|
|
|
export function helpHeading(label: string): string {
|
|
return bold(`${label}:`);
|
|
}
|
|
|
|
export function helpExample(command: string, note?: string): string {
|
|
const suffix = note ? ` ${dimGray(`# ${note}`)}` : "";
|
|
return ` ${dimGray("$")} ${command}${suffix}`;
|
|
}
|
|
|
|
export function helpFooter(text: string): string {
|
|
return `\n${gray(`Explore the open-source repo at ${text}`)}\n\n`;
|
|
}
|
|
|
|
export function page(text: string): string {
|
|
const content = text.replace(/^\n+|\n+$/g, "");
|
|
return `\n${content}\n\n`;
|
|
}
|
|
|
|
export function commandErrorPage(
|
|
message: string,
|
|
usage: string,
|
|
example: string,
|
|
): string {
|
|
return page(
|
|
[
|
|
`${errorBadge("ERROR")} ${red(message)}`,
|
|
"",
|
|
dim(" Usage:"),
|
|
` ${usage}`,
|
|
"",
|
|
dim(" Example:"),
|
|
` ${example}`,
|
|
].join("\n"),
|
|
);
|
|
}
|
|
|
|
export function infoLine(text: string): string {
|
|
return text;
|
|
}
|
|
|
|
export function progressLine(
|
|
completed: number,
|
|
total: number,
|
|
label: string = "skills",
|
|
): string {
|
|
const width = 10;
|
|
const safeTotal = Math.max(total, 1);
|
|
const safeCompleted = Math.min(Math.max(completed, 0), total);
|
|
const filled = Math.floor((safeCompleted / safeTotal) * width);
|
|
const bar = `[${"#".repeat(filled)}${"-".repeat(width - filled)}]`;
|
|
return `${grayDark("Progress:")} ${textGray(bar)} ${dimGray(`${safeCompleted}/${total} ${label}`)}`;
|
|
}
|
|
|
|
export function summaryLine(text: string): string {
|
|
return grayDark(text);
|
|
}
|
|
|
|
export function statusTag(status: "ok" | "warn" | "fail"): string {
|
|
switch (status) {
|
|
case "ok":
|
|
return grayDark("[ok]");
|
|
case "warn":
|
|
return gray("[warn]");
|
|
case "fail":
|
|
return red("[fail]");
|
|
}
|
|
}
|
|
|
|
export function errorMessage(text: string): string {
|
|
return red(text);
|
|
}
|