import * as ansiEscapes from "./ansi_escapes.ts";import type { Chain } from "./chain.ts";
type Args = Array<unknown>;type Executor = (this: AnsiChain, ...args: Args) => string;type Property = string | Executor;type PropertyNames = keyof Chain<AnsiChain>;
export interface AnsiChain extends Chain<AnsiChain> { (): string;
toString(): string;
bytes(): Uint8Array;}
export type AnsiFactory = () => Ansi;
export type Ansi = AnsiFactory & AnsiChain;
export const ansi: Ansi = factory();
const encoder = new TextEncoder();
function factory(): Ansi { let result: Array<string> = []; let stack: Array<[Property, Args]> = [];
const ansi: Ansi = function ( this: AnsiChain | undefined, ...args: Args ): string | AnsiChain { if (this) { if (args.length) { update(args); return this; } return this.toString(); } return factory(); } as Ansi;
ansi.text = function (text: string): AnsiChain { stack.push([text, []]); return this; };
ansi.toArray = function (): Array<string> { update(); const ret: Array<string> = result; result = []; return ret; };
ansi.toString = function (): string { return this.toArray().join(""); };
ansi.bytes = function (): Uint8Array { return encoder.encode(this.toString()); };
const methodList: Array<[PropertyNames, Property]> = Object.entries( ansiEscapes, ) as Array<[PropertyNames, Property]>;
for (const [name, method] of methodList) { Object.defineProperty(ansi, name, { get(this: AnsiChain) { stack.push([method, []]); return this; }, }); }
return ansi;
function update(args?: Args) { if (!stack.length) { return; } if (args) { stack[stack.length - 1][1] = args; } result.push( ...stack.map(([prop, args]: [Property, Args]) => typeof prop === "string" ? prop : prop.call(ansi, ...args) ), ); stack = []; }}