@oxog/termstyle
Version:
A powerful, feature-rich CLI text formatting library with zero dependencies. Supports colors, gradients, animations, progress bars, and more.
590 lines (572 loc) • 20.8 kB
text/typescript
type ColorInput = string | number | [number, number, number];
interface StyleOptions {
force?: boolean;
level?: 0 | 1 | 2 | 3;
}
declare class Style {
private codes;
private resetCodes;
private options;
constructor(codes?: string[], resetCodes?: string[], options?: StyleOptions);
private shouldApplyStyle;
private addStyle;
apply(text: string): string;
get bold(): Style;
get dim(): Style;
get italic(): Style;
get underline(): Style;
get inverse(): Style;
get hidden(): Style;
get strikethrough(): Style;
get black(): Style;
get red(): Style;
get green(): Style;
get yellow(): Style;
get blue(): Style;
get magenta(): Style;
get cyan(): Style;
get white(): Style;
get gray(): Style;
get grey(): Style;
get bgBlack(): Style;
get bgRed(): Style;
get bgGreen(): Style;
get bgYellow(): Style;
get bgBlue(): Style;
get bgMagenta(): Style;
get bgCyan(): Style;
get bgWhite(): Style;
get bgGray(): Style;
get bgGrey(): Style;
color(color: ColorInput): Style;
bgColor(color: ColorInput): Style;
rgb(r: number, g: number, b: number): Style;
bgRgb(r: number, g: number, b: number): Style;
hex(hex: string): Style;
bgHex(hex: string): Style;
}
type FormatterFunction = {
(text: string): string;
(...args: any[]): string;
};
type FormatterProxy = FormatterFunction & Record<string, any>;
declare class Formatter {
private style;
constructor(options?: StyleOptions);
private createProxy;
private template;
get proxy(): FormatterProxy;
strip(text: string): string;
static create(options?: StyleOptions): FormatterProxy;
}
interface FormatterInstance extends FormatterProxy {
(text: string): string;
(...args: any[]): string;
(strings: TemplateStringsArray, ...values: any[]): string;
strip: (text: string) => string;
color: (color: string | number | [number, number, number]) => FormatterProxy;
bgColor: (color: string | number | [number, number, number]) => FormatterProxy;
rgb: (r: number, g: number, b: number) => FormatterProxy;
bgRgb: (r: number, g: number, b: number) => FormatterProxy;
hex: (hex: string) => FormatterProxy;
bgHex: (hex: string) => FormatterProxy;
}
interface FormatterAPI extends FormatterInstance {
black: FormatterInstance;
red: FormatterInstance;
green: FormatterInstance;
yellow: FormatterInstance;
blue: FormatterInstance;
magenta: FormatterInstance;
cyan: FormatterInstance;
white: FormatterInstance;
gray: FormatterInstance;
grey: FormatterInstance;
bgBlack: FormatterInstance;
bgRed: FormatterInstance;
bgGreen: FormatterInstance;
bgYellow: FormatterInstance;
bgBlue: FormatterInstance;
bgMagenta: FormatterInstance;
bgCyan: FormatterInstance;
bgWhite: FormatterInstance;
bgGray: FormatterInstance;
bgGrey: FormatterInstance;
bold: FormatterInstance;
dim: FormatterInstance;
italic: FormatterInstance;
underline: FormatterInstance;
inverse: FormatterInstance;
hidden: FormatterInstance;
strikethrough: FormatterInstance;
}
interface TerminalInfo {
supportsColor: boolean;
colorLevel: 0 | 1 | 2 | 3;
isTTY: boolean;
isCI: boolean;
width: number;
height: number;
columns: number;
rows: number;
}
declare const getTerminalInfo: () => TerminalInfo;
declare const terminal: () => TerminalInfo;
interface GradientOptions {
interpolation?: 'linear' | 'bezier';
hsvSpin?: 'short' | 'long';
}
interface GradientAPI {
(text: string, colors: (string | number | [number, number, number])[], options?: GradientOptions): string;
(colors: (string | number | [number, number, number])[]): (text: string, options?: GradientOptions) => string;
linear: (text: string, options: {
from: string | number | [number, number, number];
to: string | number | [number, number, number];
}) => string;
}
declare const gradientWithLinear: GradientAPI;
declare function rainbow(...args: any[]): string | ((text: string) => string);
/**
* Global Resource Manager for tracking and disposing resources
* Prevents memory leaks by ensuring all resources are properly cleaned up
*/
interface Disposable {
dispose(): void;
}
type AnimationType = 'blink' | 'pulse' | 'slide' | 'typewriter' | 'fade';
interface AnimationOptions {
duration?: number;
interval?: number;
iterations?: number;
onComplete?: () => void;
}
declare class Animation implements Disposable {
private text;
private type;
private options;
private intervalId?;
private running;
private isDisposed;
private componentId;
private frameCount;
private startTime;
private pausedFrame;
private pausedIteration;
constructor(text: string, type: AnimationType, options?: AnimationOptions);
start(): void;
stop(): void;
pause(frame?: number, iteration?: number): void;
resume(): void;
dispose(): void;
private renderBlink;
private renderPulse;
private renderSlide;
private renderTypewriter;
private renderFade;
}
declare function animate(text: string, type: AnimationType, options?: AnimationOptions): Animation;
declare const spinners: {
readonly dots: {
readonly frames: readonly ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
readonly interval: 80;
};
readonly dots2: {
readonly frames: readonly ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
readonly interval: 80;
};
readonly dots3: {
readonly frames: readonly ["⠋", "⠙", "⠚", "⠞", "⠖", "⠦", "⠴", "⠲", "⠳", "⠓"];
readonly interval: 80;
};
readonly line: {
readonly frames: readonly ["-", "\\", "|", "/"];
readonly interval: 130;
};
readonly line2: {
readonly frames: readonly ["⠂", "-", "–", "—", "–", "-"];
readonly interval: 100;
};
readonly pipe: {
readonly frames: readonly ["┤", "┘", "┴", "└", "├", "┌", "┬", "┐"];
readonly interval: 100;
};
readonly star: {
readonly frames: readonly ["✶", "✸", "✹", "✺", "✹", "✷"];
readonly interval: 70;
};
readonly toggle: {
readonly frames: readonly ["⊶", "⊷"];
readonly interval: 250;
};
readonly box: {
readonly frames: readonly ["◰", "◳", "◲", "◱"];
readonly interval: 120;
};
readonly circle: {
readonly frames: readonly ["◐", "◓", "◑", "◒"];
readonly interval: 120;
};
readonly arrow: {
readonly frames: readonly ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"];
readonly interval: 100;
};
readonly bounce: {
readonly frames: readonly ["⠁", "⠂", "⠄", "⠂"];
readonly interval: 120;
};
readonly bar: {
readonly frames: readonly ["▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃"];
readonly interval: 80;
};
readonly earth: {
readonly frames: readonly ["🌍", "🌎", "🌏"];
readonly interval: 180;
};
readonly moon: {
readonly frames: readonly ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"];
readonly interval: 80;
};
readonly clock: {
readonly frames: readonly ["🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛"];
readonly interval: 100;
};
readonly balloon: {
readonly frames: readonly [" ", ".", "o", "O", "@", "*", " "];
readonly interval: 140;
};
readonly noise: {
readonly frames: readonly ["▓", "▒", "░"];
readonly interval: 100;
};
readonly boxBounce: {
readonly frames: readonly ["▖", "▘", "▝", "▗"];
readonly interval: 120;
};
readonly triangle: {
readonly frames: readonly ["◢", "◣", "◤", "◥"];
readonly interval: 50;
};
readonly binary: {
readonly frames: readonly ["010010", "101101", "010010", "101010"];
readonly interval: 120;
};
readonly runner: {
readonly frames: readonly ["🚶", "🏃"];
readonly interval: 140;
};
readonly pong: {
readonly frames: readonly ["▐⠂ ▌", "▐⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂▌", "▐ ⠠▌", "▐ ⡀▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐⠠ ▌"];
readonly interval: 80;
};
readonly shark: {
readonly frames: readonly ["▐|\\____________▌", "▐_|\\___________▌", "▐__|\\__________▌", "▐___|\\_________▌", "▐____|\\________▌", "▐_____|\\_______▌", "▐______|\\______▌", "▐_______|\\_____▌", "▐________|\\____▌", "▐_________|\\___▌", "▐__________|\\__▌", "▐___________|\\_▌", "▐____________|\\▌", "▐____________/|▌", "▐___________/|_▌", "▐__________/|__▌", "▐_________/|___▌", "▐________/|____▌", "▐_______/|_____▌", "▐______/|______▌", "▐_____/|_______▌", "▐____/|________▌", "▐___/|_________▌", "▐__/|__________▌", "▐_/|___________▌", "▐/|____________▌"];
readonly interval: 120;
};
readonly dqpb: {
readonly frames: readonly ["d", "q", "p", "b"];
readonly interval: 100;
};
readonly weather: {
readonly frames: readonly ["☀️ ", "⛅ ", "🌤 ", "⛈ ", "🌧 ", "🌦 ", "☀️ "];
readonly interval: 100;
};
readonly christmas: {
readonly frames: readonly ["🌲", "🎄"];
readonly interval: 400;
};
};
type SpinnerName = keyof typeof spinners;
declare class Spinner implements Disposable {
private text;
private frames;
private currentFrame;
private intervalId?;
private running;
private interval;
private isDisposed;
private componentId;
constructor(text: string, spinnerOrOptions?: SpinnerName | {
spinner?: SpinnerName | string;
color?: string;
interval?: number;
}, interval?: number);
start(): void;
stop(finalText?: string): void;
update(text: string): void;
updateColor(_color: string): void;
succeed(text?: string): void;
fail(text?: string): void;
warn(text?: string): void;
info(text?: string): void;
clear(): void;
dispose(): void;
}
declare function spinner(text: string, options?: SpinnerName | {
spinner?: SpinnerName;
color?: string;
interval?: number;
}): Spinner;
type BoxStyle = 'single' | 'double' | 'round' | 'bold' | 'ascii';
interface BoxOptions {
padding?: number | {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
margin?: number | {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
borderStyle?: BoxStyle;
borderColor?: string | [number, number, number];
backgroundColor?: string | [number, number, number];
align?: 'left' | 'center' | 'right';
title?: string;
titleAlignment?: 'left' | 'center' | 'right';
width?: number;
wrap?: boolean;
}
declare function box(content: string, options?: BoxOptions): string;
interface ProgressBarOptions {
total?: number;
width?: number;
complete?: string;
incomplete?: string;
head?: string;
clear?: boolean;
renderThrottle?: number;
format?: string;
stream?: NodeJS.WriteStream;
barColor?: string | [number, number, number];
completeColor?: string | [number, number, number];
}
declare class ProgressBar implements Disposable {
private current;
private startTime;
private lastRender;
private options;
private isDisposed;
private componentId;
constructor(options?: ProgressBarOptions);
tick(delta?: number, tokens?: Record<string, string>): void;
update(current: number, tokens?: Record<string, string>): void;
private render;
private formatTime;
complete(): void;
getRenderString(): string;
dispose(): void;
}
interface MultiProgressOptions {
total?: number;
width?: number;
complete?: string;
incomplete?: string;
stream?: NodeJS.WriteStream;
}
declare class MultiProgress implements Disposable {
private bars;
private options;
private isDisposed;
constructor(options?: MultiProgressOptions);
newBar(format: string, options?: ProgressBarOptions): ProgressBar;
render(): void;
update(): void;
dispose(): void;
}
declare function progressBar(options?: ProgressBarOptions): ProgressBar;
declare function multiProgress(options?: MultiProgressOptions): MultiProgress;
declare function bar(current: number, total: number, options?: ProgressBarOptions): string;
type TemplateFunction = (strings: TemplateStringsArray, ...values: any[]) => string;
interface TemplateHelpers {
[key: string]: Style | TemplateFunction;
}
declare function createTemplateTag(options?: {
formatter?: FormatterProxy;
helpers?: TemplateHelpers;
}): TemplateFunction;
declare function parse(template: string, variables?: Record<string, any>): string;
interface ThemeColors {
primary?: string | [number, number, number];
secondary?: string | [number, number, number];
success?: string | [number, number, number];
error?: string | [number, number, number];
warning?: string | [number, number, number];
info?: string | [number, number, number];
debug?: string | [number, number, number];
muted?: string | [number, number, number];
accent?: string | [number, number, number];
highlight?: string | [number, number, number];
[key: string]: string | [number, number, number] | undefined;
}
interface ThemeStyles {
heading1?: Style;
heading2?: Style;
heading3?: Style;
text?: Style;
bold?: Style;
italic?: Style;
underline?: Style;
code?: Style;
link?: Style;
quote?: Style;
list?: Style;
[key: string]: Style | undefined;
}
interface Theme {
name: string;
colors: ThemeColors;
styles: ThemeStyles;
}
declare const defaultTheme: Theme;
declare const themes: Record<string, Theme>;
declare function create(colors: ThemeColors): any;
declare class ThemeManager {
private currentTheme;
private customThemes;
constructor(themeName?: string);
setTheme(themeName: string): void;
getTheme(): Theme;
registerTheme(theme: Theme): void;
registerTheme(name: string, theme: Omit<Theme, 'name'>): void;
getColor(colorName: string): string | [number, number, number] | undefined;
getStyle(styleName: string): Style | undefined;
applyTheme(): Record<string, (...args: any[]) => any>;
getCurrentTheme(): string;
}
type Condition = boolean | (() => boolean);
interface ConditionalOptions {
defaultStyle?: Style;
fallback?: string;
}
declare class ConditionalFormatter {
private conditions;
private options;
format: any;
constructor(condition: boolean, options?: ConditionalOptions);
constructor(options?: ConditionalOptions);
when(condition: Condition, style: Style | string): this;
elsif(condition: Condition, style: Style | string): this;
else(style: Style | string): this;
formatText(text: string): string;
}
declare function conditional(): ConditionalFormatter;
declare function conditional(condition: any, options?: ConditionalOptions): any;
declare namespace conditional {
var when: (condition: Condition | (() => Promise<boolean>), text: string, style?: Style | string) => string | Promise<string>;
}
interface LogLevel {
name: string;
value: number;
style: Style;
prefix?: string;
}
declare const logLevels: Record<string, LogLevel>;
declare class LogFormatter {
private minLevel;
private usePrefix;
private timestamp;
constructor(options?: {
minLevel?: string;
usePrefix?: boolean;
timestamp?: boolean;
});
format(level: string, message: string): string | null;
trace(message: string): string | null;
debug(message: string): string | null;
info(message: string): string | null;
warn(message: string): string | null;
error(message: string): string | null;
fatal(message: string): string | null;
}
declare function createLogFormatter(options?: ConstructorParameters<typeof LogFormatter>[0]): LogFormatter;
interface StatusFormatter {
success(text: string): string;
error(text: string): string;
warning(text: string): string;
info(text: string): string;
pending(text: string): string;
skipped(text: string): string;
}
declare function createStatusFormatter(): StatusFormatter;
declare function color(input: string, fallback?: string | Style): string;
declare const stripAnsi: (str: string) => string;
type RGBTuple = readonly [number, number, number];
/**
* Cache Manager for Performance Optimization
* Provides centralized caching for expensive operations
*/
interface CacheStats {
hits: number;
misses: number;
size: number;
maxSize: number;
}
declare class CacheManager {
private static instance;
private colorCache;
private hexCache;
private hslCache;
private gradientCache;
private styleCache;
private stats;
private constructor();
static getInstance(): CacheManager;
getColor(key: string): RGBTuple | undefined;
setColor(key: string, value: RGBTuple): void;
getHexColor(hex: string): RGBTuple | undefined;
setHexColor(hex: string, value: RGBTuple): void;
getHslColor(key: string): RGBTuple | undefined;
setHslColor(key: string, value: RGBTuple): void;
getGradient(key: string): string | undefined;
setGradient(key: string, value: string): void;
getStyle(key: string): Style | undefined;
setStyle(key: string, value: Style): void;
clear(): void;
clearColors(): void;
clearGradients(): void;
clearStyles(): void;
getStats(): Record<string, CacheStats>;
resetStats(): void;
getHitRate(type: 'color' | 'gradient' | 'style'): number;
}
declare const cacheManager: CacheManager;
declare const termstyle: FormatterAPI & {
Style: typeof Style;
Formatter: typeof Formatter;
gradient: typeof gradientWithLinear;
rainbow: typeof rainbow;
animate: typeof animate;
Animation: typeof Animation;
spinner: typeof spinner;
Spinner: typeof Spinner;
spinners: typeof spinners;
box: typeof box;
progressBar: typeof progressBar;
ProgressBar: typeof ProgressBar;
multiProgress: typeof multiProgress;
MultiProgress: typeof MultiProgress;
template: TemplateFunction;
createTemplate: typeof createTemplateTag;
templateParse: typeof parse;
ThemeManager: typeof ThemeManager;
themes: typeof themes;
conditional: typeof conditional;
ConditionalFormatter: typeof ConditionalFormatter;
createLogFormatter: typeof createLogFormatter;
LogFormatter: typeof LogFormatter;
createStatusFormatter: typeof createStatusFormatter;
logLevels: typeof logLevels;
conditionalColor: typeof color;
terminal: typeof terminal;
getTerminalInfo: typeof getTerminalInfo;
strip: typeof stripAnsi;
stripAnsi: typeof stripAnsi;
create: typeof Formatter.create;
supportsColor: boolean;
level: 0 | 1 | 2 | 3;
};
declare const style: Style;
export { Animation, type AnimationOptions, type AnimationType, type BoxOptions, type BoxStyle, ConditionalFormatter, type ConditionalOptions, Formatter, type FormatterAPI, type GradientOptions, LogFormatter, MultiProgress, type MultiProgressOptions, ProgressBar, type ProgressBarOptions, Spinner, type SpinnerName, type StatusFormatter, Style, type StyleOptions, type TemplateFunction, type TemplateHelpers, type TerminalInfo, type Theme, type ThemeColors, ThemeManager, type ThemeStyles, animate, bar, box, cacheManager, conditional, color as conditionalColor, createLogFormatter, createStatusFormatter, createTemplateTag, termstyle as default, defaultTheme, getTerminalInfo, gradientWithLinear as gradient, logLevels, multiProgress, progressBar, rainbow, spinner, spinners, stripAnsi, style, parse as templateParse, terminal, create as themeCreate, themes };