Socket
Socket
Sign inDemoInstall

listr2

Package Overview
Dependencies
30
Maintainers
1
Versions
231
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.8 to 5.1.0-beta.1

dist/index.mjs

627

dist/index.d.ts
import Enquirer from 'enquirer';
import { Subject, Observable } from 'rxjs';
import { Writable, Readable } from 'stream';
import { Observable } from 'rxjs';
import { Readable, Writable } from 'stream';
import { WriteStream } from 'fs';
interface BasePromptOptions {
message: string | (() => string) | (() => Promise<string>);
initial?: boolean | number | number[] | string | (() => string) | (() => Promise<string>);
required?: boolean;
stdin?: NodeJS.ReadStream;
stdout?: NodeJS.WriteStream;
header?: string;
footer?: string;
skip?: (value: any) => boolean | Promise<boolean>;
format?: (value: any) => any | Promise<any>;
result?: (value: any) => any | Promise<any>;
validate?: (value: any, state: any) => boolean | Promise<boolean> | string | Promise<string> | Promise<string | boolean>;
onSubmit?: (name: any, value: any, prompt: Enquirer.Prompt) => boolean | Promise<boolean>;
onCancel?: (name: any, value: any, prompt: Enquirer.Prompt) => boolean | Promise<boolean>;
/** Generic events that occur throughout the whole listr task set. */
declare enum ListrEventType {
SHOULD_REFRESH_RENDER = "SHOUD_REFRESH_RENDER"
}
interface BasePromptOptionsWithName extends BasePromptOptions {
name: string | (() => string);
/** Internal events that occur inside listr task. */
declare enum ListrTaskEventType {
TITLE = "TITLE",
STATE = "STATE",
ENABLED = "ENABLED",
SUBTASK = "SUBTASK",
DATA = "DATA",
MESSAGE = "MESSAGE"
}
interface ArrayPromptOptions extends BasePromptOptions {
choices: string[] | BasePromptOptionsWithName[];
maxChoices?: number;
multiple?: boolean;
initial?: number | number[];
delay?: number;
separator?: boolean;
sort?: boolean;
linebreak?: boolean;
edgeLength?: number;
align?: 'left' | 'right';
scroll?: boolean;
hint?: string;
}
interface BooleanPromptOptions extends BasePromptOptions {
initial?: boolean | (() => string) | (() => Promise<string>);
}
interface StringPromptOptions extends BasePromptOptions {
initial?: string;
multiline?: boolean;
}
interface ScalePromptOptions extends ArrayPromptOptions {
scale: StringPromptOptions[];
margin?: [number, number, number, number];
}
interface NumberPromptOptions extends BasePromptOptions {
min?: number;
max?: number;
delay?: number;
float?: boolean;
round?: boolean;
major?: number;
minor?: number;
initial?: number;
}
interface SnippetPromptOptions extends BasePromptOptions {
newline?: string;
fields: Partial<BasePromptOptionsWithName>[];
template: string;
}
interface SortPromptOptions extends BasePromptOptions {
hint?: string;
drag?: boolean;
numbered?: boolean;
}
interface SurveyPromptOptions extends ArrayPromptOptions {
scale: BasePromptOptionsWithName[];
margin: [number, number, number, number];
}
interface QuizPromptOptions extends ArrayPromptOptions {
correctChoice: number;
}
interface TogglePromptOptions extends BasePromptOptions {
enabled?: string;
disabled?: string;
}
/** Returns all the prompt options depending on the type selected. */
type PromptOptions<T extends boolean = false> = Unionize<{
[K in PromptTypes]-?: T extends true ? {
type: K;
} & PromptOptionsType<K> & {
name: string | (() => string);
} : {
type: K;
} & PromptOptionsType<K>;
}> | ({
type: string;
} & T extends true ? PromptOptionsType<string> & {
name: string | (() => string);
} : PromptOptionsType<string>);
type Unionize<T extends Record<PropertyKey, unknown>> = {
[P in keyof T]: T[P];
}[keyof T];
type PromptTypes = 'AutoComplete' | 'BasicAuth' | 'Confirm' | 'Editable' | 'Form' | 'Input' | 'Invisible' | 'List' | 'MultiSelect' | 'Numeral' | 'Password' | 'Quiz' | 'Scale' | 'Select' | 'Snippet' | 'Sort' | 'Survey' | 'Text' | 'Toggle';
type PromptOptionsType<T> = T extends keyof PromptOptionsMap ? PromptOptionsMap[T] : T extends string ? BasePromptOptions & Record<PropertyKey, unknown> : any;
declare class PromptOptionsMap implements Record<PromptTypes, Record<PropertyKey, any>> {
AutoComplete: ArrayPromptOptions;
BasicAuth: StringPromptOptions;
Confirm: BooleanPromptOptions;
Editable: ArrayPromptOptions;
Form: ArrayPromptOptions;
Input: StringPromptOptions;
Invisible: StringPromptOptions;
List: ArrayPromptOptions;
MultiSelect: ArrayPromptOptions;
Numeral: NumberPromptOptions;
Password: StringPromptOptions;
Quiz: QuizPromptOptions;
Scale: ScalePromptOptions;
Select: ArrayPromptOptions;
Snippet: SnippetPromptOptions;
Sort: SortPromptOptions;
Survey: SurveyPromptOptions;
Text: StringPromptOptions;
Toggle: TogglePromptOptions;
}
interface PromptSettings {
error?: boolean;
cancelCallback?: (settings?: PromptSettings) => string | Error | PromptError | void;
stdout?: WriteStream | Writable;
enquirer?: Enquirer;
}
interface PromptInstance extends Omit<BasePromptOptions, 'onCancel' | 'onSubmit'> {
submit: () => void;
cancel: (err?: string) => void;
}
/**
* Extend the task to have more functionality while accessing from the outside.
* Give event map a set of indexes to not make it go crazy when some events are missing from it.
* They are optional after all.
*/
declare class TaskWrapper<Ctx, Renderer extends ListrRendererFactory> {
task: Task<Ctx, ListrRendererFactory>;
errors: ListrError<Ctx>[];
private options;
constructor(task: Task<Ctx, ListrRendererFactory>, errors: ListrError<Ctx>[], options: ListrBaseClassOptions<Ctx, any, any>);
/** Get the title of the current task. */
get title(): string;
/** Change the title of the current task. */
set title(data: string);
/** Get the output from the output channel. */
get output(): string;
/** Send a output to the output channel. */
set output(data: string);
/** Create a new subtask with given renderer selection from the parent task. */
newListr<NewCtx = Ctx>(task: ListrTask<NewCtx, Renderer> | ListrTask<NewCtx, Renderer>[] | ((parent: Omit<this, 'skip' | 'enabled'>) => ListrTask<NewCtx, Renderer> | ListrTask<NewCtx, Renderer>[]), options?: ListrSubClassOptions<NewCtx, Renderer>): Listr<NewCtx, any, any>;
/** Report a error in process for error collection. */
report(error: Error, type: ListrErrorTypes): void;
/** Skip current task. */
skip(message?: string): void;
/** Get the number of retrying, else returns false */
isRetrying(): Task<Ctx, Renderer>['retry'];
/**
* Create a new Enquirer prompt using prompt options.
*
* Since process.stdout is controlled by Listr, this will passthrough all Enquirer data through internal stdout.
*/
prompt<T = any>(options: PromptOptions | PromptOptions<true>[]): Promise<T>;
/** Cancels the current prompt attach to this task. */
cancelPrompt(throwError?: boolean): void;
/**
* Pass stream of data to internal stdout.
*
* Since Listr2 takes control of process.stdout utilizing the default renderer, any data outputted to process.stdout
* will corrupt its looks.
*
* This returns a fake stream to pass any stream inside Listr as task data.
*/
stdout(): NodeJS.WriteStream & NodeJS.WritableStream;
/** Run this task. */
run(ctx: Ctx): Promise<void>;
declare class BaseEventMap {
[k: string]: any;
}
/**
* Request type of an event.
*/
type EventData<Event extends string, Map extends Record<string, unknown>> = Event extends keyof Map ? Map[Event] : never;
/**
* For fast typing the event map.
*/
type EventMap<Events extends string> = Partial<Record<Events, unknown>>;
/** Available task states. */
declare enum ListrTaskState {
UNINITIALIZED = "UNINITIALIZED",
PENDING = "PENDING",

@@ -187,91 +48,7 @@ COMPLETED = "COMPLETED",

/**
* Create a task from the given set of variables and make it runnable.
*/
declare class Task<Ctx, Renderer extends ListrRendererFactory> extends Subject<ListrEvent> {
listr: Listr<Ctx, any, any>;
tasks: ListrTask<Ctx, any>;
options: ListrOptions;
rendererOptions: ListrGetRendererOptions<Renderer>;
/** Unique id per task, randomly generated in the uuid v4 format */
id: string;
/** The current state of the task. */
state: string;
/** The task object itself, to further utilize it. */
task: (ctx: Ctx, task: TaskWrapper<Ctx, Renderer>) => void | ListrTaskResult<Ctx>;
/** Extend current task with multiple subtasks. */
subtasks: Task<Ctx, any>[];
/** Title of the task */
title?: string;
/** Untouched unchanged title of the task */
initialTitle?: string;
/** Output data from the task. */
output?: string;
/** Skip current task. */
skip: boolean | string | ((ctx: Ctx) => boolean | string | Promise<boolean | string>);
/** Current retry number of the task if retrying */
retry?: {
count: number;
withError?: any;
};
/**
* A channel for messages.
*
* This requires a separate channel for messages like error, skip or runtime messages to further utilize in the renderers.
*/
message: {
/** Run time of the task, if it has been successfully resolved. */
duration?: number;
/** Error message of the task, if it has been failed. */
error?: string;
/** Skip message of the task, if it has been skipped. */
skip?: string;
/** Rollback message of the task, if the rollback finishes */
rollback?: string;
/** Retry messages */
retry?: {
count: number;
withError?: any;
};
};
/** Per task options for the current renderer of the task. */
rendererTaskOptions: ListrGetRendererTaskOptions<Renderer>;
/** This will be triggered each time a new render should happen. */
renderHook$: Subject<void>;
prompt: undefined | PromptInstance | PromptError;
private enabled;
private enabledFn;
constructor(listr: Listr<Ctx, any, any>, tasks: ListrTask<Ctx, any>, options: ListrOptions, rendererOptions: ListrGetRendererOptions<Renderer>);
set state$(state: ListrTaskState);
set output$(data: string);
set message$(data: Task<Ctx, Renderer>['message']);
set title$(title: string);
/**
* A function to check whether this task should run at all via enable.
*/
check(ctx: Ctx): Promise<void>;
/** Returns whether this task has subtasks. */
hasSubtasks(): boolean;
/** Returns whether this task is in progress. */
isPending(): boolean;
/** Returns whether this task is skipped. */
isSkipped(): boolean;
/** Returns whether this task has been completed. */
isCompleted(): boolean;
/** Returns whether this task has been failed. */
hasFailed(): boolean;
/** Returns whether this task has an active rollback task going on. */
isRollingBack(): boolean;
/** Returns whether the rollback action was successful. */
hasRolledBack(): boolean;
/** Returns whether this task has an actively retrying task going on. */
isRetrying(): boolean;
/** Returns whether enabled function resolves to true. */
isEnabled(): boolean;
/** Returns whether this task actually has a title. */
hasTitle(): boolean;
/** Returns whether this task has a prompt inside. */
isPrompt(): boolean;
/** Run the current task. */
run(context: Ctx, wrapper: TaskWrapper<Ctx, Renderer>): Promise<void>;
declare class EventManager<Event extends string = string, Map extends Partial<Record<Event, unknown>> = Partial<Record<Event, any>>> {
private readonly emitter;
emit<E extends Event = Event>(dispatch: E, args?: EventData<E, Map>): void;
on<E extends Event = Event>(dispatch: E, handler: (data: EventData<E, Map>) => void): void;
complete(): void;
}

@@ -283,3 +60,3 @@

options: (typeof DefaultRenderer)['rendererOptions'];
renderHook$?: Task<any, any>['renderHook$'];
events: EventManager<ListrEventType, ListrEventMap>;
/** designates whether this renderer can output to a non-tty console */

@@ -415,3 +192,3 @@ static nonTTY: boolean;

private spinnerPosition;
constructor(tasks: Task<any, typeof DefaultRenderer>[], options: (typeof DefaultRenderer)['rendererOptions'], renderHook$?: Task<any, any>['renderHook$']);
constructor(tasks: Task<any, typeof DefaultRenderer>[], options: (typeof DefaultRenderer)['rendererOptions'], events: EventManager<ListrEventType, ListrEventMap>);
getTaskOptions(task: Task<any, typeof DefaultRenderer>): (typeof DefaultRenderer)['rendererTaskOptions'];

@@ -442,3 +219,3 @@ isBottomBar(task: Task<any, typeof DefaultRenderer>): boolean;

tasks: Task<any, typeof SilentRenderer>[];
options: typeof SilentRenderer['rendererOptions'];
options: (typeof SilentRenderer)['rendererOptions'];
/** designates whether this renderer can output to a non-tty console */

@@ -450,3 +227,3 @@ static nonTTY: boolean;

static rendererTaskOptions: never;
constructor(tasks: Task<any, typeof SilentRenderer>[], options: typeof SilentRenderer['rendererOptions']);
constructor(tasks: Task<any, typeof SilentRenderer>[], options: (typeof SilentRenderer)['rendererOptions']);
render(): void;

@@ -456,12 +233,2 @@ end(): void;

/** Type of listr internal events. */
declare enum ListrEventType {
TITLE = "TITLE",
STATE = "STATE",
ENABLED = "ENABLED",
SUBTASK = "SUBTASK",
DATA = "DATA",
MESSAGE = "MESSAGE"
}
/**

@@ -474,3 +241,3 @@ * This is the default renderer which is neither verbose or updating.

readonly tasks: Task<any, typeof SimpleRenderer>[];
options: typeof SimpleRenderer['rendererOptions'];
options: (typeof SimpleRenderer)['rendererOptions'];
static nonTTY: boolean;

@@ -499,9 +266,3 @@ static rendererOptions: {

static rendererTaskOptions: never;
/**
* Event type renderer map contains functions to process different task events
*/
eventTypeRendererMap: Partial<{
[P in ListrEventType]: (t: Task<any, typeof SimpleRenderer>, event: ListrEventFromType<P>) => void;
}>;
constructor(tasks: Task<any, typeof SimpleRenderer>[], options: typeof SimpleRenderer['rendererOptions']);
constructor(tasks: Task<any, typeof SimpleRenderer>[], options: (typeof SimpleRenderer)['rendererOptions']);
static now(): Date;

@@ -511,3 +272,4 @@ static formatTitle(task?: Task<any, typeof SimpleRenderer>): string;

end(): void;
render(tasks?: Task<any, typeof SimpleRenderer>[]): void;
render(): void;
private simpleRenderer;
}

@@ -559,3 +321,4 @@

tasks: Task<any, typeof VerboseRenderer>[];
options: typeof VerboseRenderer['rendererOptions'];
options: (typeof VerboseRenderer)['rendererOptions'];
events?: EventManager<ListrEventType, ListrEventMap>;
/** designates whether this renderer can output to a non-tty console */

@@ -597,3 +360,3 @@ static nonTTY: boolean;

private logger;
constructor(tasks: Task<any, typeof VerboseRenderer>[], options: typeof VerboseRenderer['rendererOptions']);
constructor(tasks: Task<any, typeof VerboseRenderer>[], options: (typeof VerboseRenderer)['rendererOptions'], events?: EventManager<ListrEventType, ListrEventMap>);
render(): void;

@@ -670,14 +433,20 @@ end(): void;

/** create a new renderer */
constructor(tasks: readonly Task<any, ListrRendererFactory>[], options: typeof ListrRenderer.rendererOptions, renderHook$?: Subject<void>);
constructor(tasks: readonly Task<any, ListrRendererFactory>[], options: typeof ListrRenderer.rendererOptions, events?: EventManager<ListrEventType, ListrEventMap>);
}
/** Exported for javascript applications to extend the base renderer */
declare class ListrBaseRenderer implements ListrRenderer {
/** designate renderer global options that is specific to the current renderer */
static rendererOptions: Record<PropertyKey, any>;
/** designate renderer per task options that is specific to the current renderer */
static rendererTaskOptions: Record<PropertyKey, any>;
/** designate whether this renderer can work in non-tty environments */
static nonTTY: boolean;
tasks: Task<any, typeof ListrBaseRenderer>[];
options: typeof ListrBaseRenderer.rendererOptions;
/** A function to what to do on render */
render: () => void;
/** A function to what to do on end of the render */
end: (err?: Error) => void;
constructor(tasks: Task<any, typeof ListrBaseRenderer>[], options: typeof ListrBaseRenderer.rendererOptions);
/** create a new renderer */
constructor(tasks: Task<any, typeof ListrBaseRenderer>[], options: typeof ListrBaseRenderer.rendererOptions, events?: EventManager<ListrEventType, ListrEventMap>);
}

@@ -850,17 +619,11 @@ /** A renderer factory from the current type */

type ListrEvent = {
type: Exclude<ListrEventType, 'MESSAGE' | 'DATA'>;
type: Exclude<ListrTaskEventType, 'MESSAGE' | 'DATA'>;
data?: string | boolean;
} | {
type: ListrEventType.DATA;
type: ListrTaskEventType.DATA;
data: string;
} | {
type: ListrEventType.MESSAGE;
type: ListrTaskEventType.MESSAGE;
data: Task<any, any>['message'];
};
/**
* Used to match event.type to ListrEvent permutations
*/
type ListrEventFromType<T extends ListrEventType, E = ListrEvent> = E extends {
type: infer U;
} ? T extends U ? E : never : never;

@@ -896,9 +659,286 @@ /** The internal error handling mechanism.. */

interface BasePromptOptions {
message: string | (() => string) | (() => Promise<string>);
initial?: boolean | number | number[] | string | (() => string) | (() => Promise<string>);
required?: boolean;
stdin?: NodeJS.ReadStream;
stdout?: NodeJS.WriteStream;
header?: string;
footer?: string;
skip?: (value: any) => boolean | Promise<boolean>;
format?: (value: any) => any | Promise<any>;
result?: (value: any) => any | Promise<any>;
validate?: (value: any, state: any) => boolean | Promise<boolean> | string | Promise<string> | Promise<string | boolean>;
onSubmit?: (name: any, value: any, prompt: Enquirer.Prompt) => boolean | Promise<boolean>;
onCancel?: (name: any, value: any, prompt: Enquirer.Prompt) => boolean | Promise<boolean>;
}
interface BasePromptOptionsWithName extends BasePromptOptions {
name: string | (() => string);
}
interface ArrayPromptOptions extends BasePromptOptions {
choices: string[] | BasePromptOptionsWithName[];
maxChoices?: number;
multiple?: boolean;
initial?: number | number[];
delay?: number;
separator?: boolean;
sort?: boolean;
linebreak?: boolean;
edgeLength?: number;
align?: 'left' | 'right';
scroll?: boolean;
hint?: string;
}
interface BooleanPromptOptions extends BasePromptOptions {
initial?: boolean | (() => string) | (() => Promise<string>);
}
interface StringPromptOptions extends BasePromptOptions {
initial?: string;
multiline?: boolean;
}
interface ScalePromptOptions extends ArrayPromptOptions {
scale: StringPromptOptions[];
margin?: [number, number, number, number];
}
interface NumberPromptOptions extends BasePromptOptions {
min?: number;
max?: number;
delay?: number;
float?: boolean;
round?: boolean;
major?: number;
minor?: number;
initial?: number;
}
interface SnippetPromptOptions extends BasePromptOptions {
newline?: string;
fields: Partial<BasePromptOptionsWithName>[];
template: string;
}
interface SortPromptOptions extends BasePromptOptions {
hint?: string;
drag?: boolean;
numbered?: boolean;
}
interface SurveyPromptOptions extends ArrayPromptOptions {
scale: BasePromptOptionsWithName[];
margin: [number, number, number, number];
}
interface QuizPromptOptions extends ArrayPromptOptions {
correctChoice: number;
}
interface TogglePromptOptions extends BasePromptOptions {
enabled?: string;
disabled?: string;
}
/** Returns all the prompt options depending on the type selected. */
type PromptOptions<T extends boolean = false> = Unionize<{
[K in PromptTypes]-?: T extends true ? {
type: K;
} & PromptOptionsType<K> & {
name: string | (() => string);
} : {
type: K;
} & PromptOptionsType<K>;
}> | ({
type: string;
} & T extends true ? PromptOptionsType<string> & {
name: string | (() => string);
} : PromptOptionsType<string>);
type Unionize<T extends Record<PropertyKey, unknown>> = {
[P in keyof T]: T[P];
}[keyof T];
type PromptTypes = 'AutoComplete' | 'BasicAuth' | 'Confirm' | 'Editable' | 'Form' | 'Input' | 'Invisible' | 'List' | 'MultiSelect' | 'Numeral' | 'Password' | 'Quiz' | 'Scale' | 'Select' | 'Snippet' | 'Sort' | 'Survey' | 'Text' | 'Toggle';
type PromptOptionsType<T> = T extends keyof PromptOptionsMap ? PromptOptionsMap[T] : T extends string ? BasePromptOptions & Record<PropertyKey, unknown> : any;
declare class PromptOptionsMap implements Record<PromptTypes, Record<PropertyKey, any>> {
AutoComplete: ArrayPromptOptions;
BasicAuth: StringPromptOptions;
Confirm: BooleanPromptOptions;
Editable: ArrayPromptOptions;
Form: ArrayPromptOptions;
Input: StringPromptOptions;
Invisible: StringPromptOptions;
List: ArrayPromptOptions;
MultiSelect: ArrayPromptOptions;
Numeral: NumberPromptOptions;
Password: StringPromptOptions;
Quiz: QuizPromptOptions;
Scale: ScalePromptOptions;
Select: ArrayPromptOptions;
Snippet: SnippetPromptOptions;
Sort: SortPromptOptions;
Survey: SurveyPromptOptions;
Text: StringPromptOptions;
Toggle: TogglePromptOptions;
}
interface PromptSettings {
error?: boolean;
cancelCallback?: (settings?: PromptSettings) => string | Error | PromptError | void;
stdout?: WriteStream | Writable;
enquirer?: Enquirer;
}
interface PromptInstance extends Omit<BasePromptOptions, 'onCancel' | 'onSubmit'> {
submit: () => void;
cancel: (err?: string) => void;
}
/**
* Extend the task to have more functionality while accessing from the outside.
*/
declare class TaskWrapper<Ctx, Renderer extends ListrRendererFactory> {
task: Task<Ctx, ListrRendererFactory>;
errors: ListrError<Ctx>[];
private options;
constructor(task: Task<Ctx, ListrRendererFactory>, errors: ListrError<Ctx>[], options: ListrBaseClassOptions<Ctx, any, any>);
/** Get the title of the current task. */
get title(): string;
/** Change the title of the current task. */
set title(data: string);
/** Get the output from the output channel. */
get output(): string;
/** Send a output to the output channel. */
set output(data: string);
/** Create a new subtask with given renderer selection from the parent task. */
newListr<NewCtx = Ctx>(task: ListrTask<NewCtx, Renderer> | ListrTask<NewCtx, Renderer>[] | ((parent: Omit<this, 'skip' | 'enabled'>) => ListrTask<NewCtx, Renderer> | ListrTask<NewCtx, Renderer>[]), options?: ListrSubClassOptions<NewCtx, Renderer>): Listr<NewCtx, any, any>;
/** Report a error in process for error collection. */
report(error: Error, type: ListrErrorTypes): void;
/** Skip current task. */
skip(message?: string): void;
/** Get the number of retrying, else returns false */
isRetrying(): Task<Ctx, Renderer>['retry'];
/**
* Create a new Enquirer prompt using prompt options.
*
* Since process.stdout is controlled by Listr, this will passthrough all Enquirer data through internal stdout.
*/
prompt<T = any>(options: PromptOptions | PromptOptions<true>[]): Promise<T>;
/** Cancels the current prompt attach to this task. */
cancelPrompt(throwError?: boolean): void;
/**
* Pass stream of data to internal stdout.
*
* Since Listr2 takes control of process.stdout utilizing the default renderer, any data outputted to process.stdout
* will corrupt its looks.
*
* This returns a fake stream to pass any stream inside Listr as task data.
*/
stdout(): NodeJS.WriteStream & NodeJS.WritableStream;
/** Run this task. */
run(ctx: Ctx): Promise<void>;
}
type TaskPrompt = undefined | PromptInstance | PromptError;
interface TaskRetry {
count: number;
withError?: Error;
}
interface TaskMessage {
/** Run time of the task, if it has been successfully resolved. */
duration?: number;
/** Error message of the task, if it has been failed. */
error?: string;
/** Skip message of the task, if it has been skipped. */
skip?: string;
/** Rollback message of the task, if the rollback finishes */
rollback?: string;
/** Retry messages */
retry?: TaskRetry;
}
type TaskFn<Ctx, Renderer extends ListrRendererFactory> = (ctx: Ctx, task: TaskWrapper<Ctx, Renderer>) => void | ListrTaskResult<Ctx>;
/**
* Create a task from the given set of variables and make it runnable.
*/
declare class Task<Ctx, Renderer extends ListrRendererFactory> extends EventManager<ListrTaskEventType, ListrTaskEventMap> {
listr: Listr<Ctx, any, any>;
tasks: ListrTask<Ctx, any>;
options: ListrOptions;
rendererOptions: ListrGetRendererOptions<Renderer>;
/** Unique id per task, randomly generated in the uuid v4 format */
id: string;
/** The current state of the task. */
state: ListrTaskState;
/** The task object itself, to further utilize it. */
task: TaskFn<Ctx, Renderer>;
/** Extend current task with multiple subtasks. */
subtasks: Task<Ctx, Renderer>[];
/** Title of the task */
title?: string;
/** Untouched unchanged title of the task */
initialTitle?: string;
/** Output data from the task. */
output?: string;
/** Current retry number of the task if retrying */
retry?: TaskRetry;
/**
* A channel for messages.
*
* This requires a separate channel for messages like error, skip or runtime messages to further utilize in the renderers.
*/
message: TaskMessage;
/** Per task options for the current renderer of the task. */
rendererTaskOptions: ListrGetRendererTaskOptions<Renderer>;
/** This will be triggered each time a new render should happen. */
prompt: TaskPrompt;
private enabled;
constructor(listr: Listr<Ctx, any, any>, tasks: ListrTask<Ctx, any>, options: ListrOptions, rendererOptions: ListrGetRendererOptions<Renderer>);
set state$(state: ListrTaskState);
set output$(data: string);
set message$(data: Task<Ctx, Renderer>['message']);
set title$(title: string);
/**
* A function to check whether this task should run at all via enable.
*/
check(ctx: Ctx): Promise<void>;
/** Returns whether this task has subtasks. */
hasSubtasks(): boolean;
/** Returns whether this task is finalized in someform. */
hasFinalized(): boolean;
/** Returns whether this task is in progress. */
isPending(): boolean;
/** Returns whether this task is skipped. */
isSkipped(): boolean;
/** Returns whether this task has been completed. */
isCompleted(): boolean;
/** Returns whether this task has been failed. */
hasFailed(): boolean;
/** Returns whether this task has an active rollback task going on. */
isRollingBack(): boolean;
/** Returns whether the rollback action was successful. */
hasRolledBack(): boolean;
/** Returns whether this task has an actively retrying task going on. */
isRetrying(): boolean;
/** Returns whether enabled function resolves to true. */
isEnabled(): boolean;
/** Returns whether this task actually has a title. */
hasTitle(): boolean;
/** Returns whether this task has a prompt inside. */
isPrompt(): boolean;
/** Run the current task. */
run(context: Ctx, wrapper: TaskWrapper<Ctx, Renderer>): Promise<void>;
private emitShouldRefreshRender;
}
/** Event map for generic listr events. */
declare class ListrEventMap extends BaseEventMap implements EventMap<ListrEventType> {
[ListrEventType.SHOULD_REFRESH_RENDER]: never;
}
/** Event map for internal listr events. */
declare class ListrTaskEventMap extends BaseEventMap implements EventMap<ListrTaskEventType> {
[ListrTaskEventType.STATE]: ListrTaskState;
[ListrTaskEventType.ENABLED]: boolean;
[ListrTaskEventType.SUBTASK]: Task<any, any>[];
[ListrTaskEventType.TITLE]: string;
[ListrTaskEventType.DATA]: string;
[ListrTaskEventType.MESSAGE]: Task<any, any>['message'];
}
/**
* Creates a new set of Listr2 task list.
*/
declare class Listr<Ctx extends ListrContext = ListrContext, Renderer extends ListrRendererValue = ListrDefaultRendererValue, FallbackRenderer extends ListrRendererValue = ListrFallbackRendererValue> {
declare class Listr<Ctx = ListrContext, Renderer extends ListrRendererValue = ListrDefaultRendererValue, FallbackRenderer extends ListrRendererValue = ListrFallbackRendererValue> {
task: ListrTask<Ctx, ListrGetRendererClassFromValue<Renderer>> | ListrTask<Ctx, ListrGetRendererClassFromValue<Renderer>>[];
options?: ListrBaseClassOptions<Ctx, Renderer, FallbackRenderer>;
parentTask?: Task<any, any>;
events: EventManager<ListrEventType, ListrEventMap>;
tasks: Task<Ctx, ListrGetRendererClassFromValue<Renderer>>[];

@@ -909,3 +949,2 @@ err: ListrError<Ctx>[];

rendererClassOptions: ListrGetRendererOptions<ListrRendererFactory>;
renderHook$: Task<any, any>['renderHook$'];
path: string[];

@@ -917,3 +956,2 @@ private concurrency;

run(context?: Ctx): Promise<Ctx>;
private checkAll;
private runTask;

@@ -938,3 +976,2 @@ }

run<InjectCtx = Ctx>(tasks: ListrTask<InjectCtx, ListrGetRendererClassFromValue<Renderer>>[], options?: ListrBaseClassOptions<InjectCtx, Renderer, FallbackRenderer>): Promise<InjectCtx>;
getRuntime(pipetime: number): string;
}

@@ -966,2 +1003,2 @@

export { Listr, ListrBaseClassOptions, ListrBaseRenderer, ListrContext, ListrDefaultNonTTYRendererOptions, ListrDefaultRenderer, ListrDefaultRendererOptions, ListrDefaultRendererValue, ListrError, ListrErrorTypes, ListrEvent, ListrEventFromType, ListrEventType, ListrFallbackRenderer, ListrFallbackRendererValue, ListrGetRendererClassFromValue, ListrGetRendererOptions, ListrGetRendererTaskOptions, ListrGetRendererValueFromClass, ListrOptions, ListrRenderer, ListrRendererFactory, ListrRendererOptions, ListrRendererValue, ListrSilentRenderer, ListrSilentRendererValue, ListrSimpleRenderer, ListrSimpleRendererValue, ListrSubClassOptions, ListrTask, Task as ListrTaskObject, ListrTaskResult, ListrTaskState, TaskWrapper as ListrTaskWrapper, LogLevels, Logger, Manager, PromptError, PromptInstance, PromptOptions, PromptOptionsMap, PromptOptionsType, PromptSettings, PromptTypes, SupportedRenderer, Unionize, createPrompt, destroyPrompt, figures };
export { Listr, ListrBaseClassOptions, ListrBaseRenderer, ListrContext, ListrDefaultNonTTYRendererOptions, ListrDefaultRenderer, ListrDefaultRendererOptions, ListrDefaultRendererValue, ListrError, ListrErrorTypes, ListrEvent, ListrEventType, ListrFallbackRenderer, ListrFallbackRendererValue, ListrGetRendererClassFromValue, ListrGetRendererOptions, ListrGetRendererTaskOptions, ListrGetRendererValueFromClass, ListrOptions, ListrRenderer, ListrRendererFactory, ListrRendererOptions, ListrRendererValue, ListrSilentRenderer, ListrSilentRendererValue, ListrSimpleRenderer, ListrSimpleRendererValue, ListrSubClassOptions, ListrTask, ListrTaskEventType, Task as ListrTaskObject, ListrTaskResult, ListrTaskState, TaskWrapper as ListrTaskWrapper, LogLevels, Logger, Manager, PromptError, PromptInstance, PromptOptions, PromptOptionsMap, PromptOptionsType, PromptSettings, PromptTypes, SupportedRenderer, Unionize, createPrompt, destroyPrompt, figures };

@@ -0,7 +1,55 @@

"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
Listr: () => Listr,
ListrError: () => ListrError,
ListrErrorTypes: () => ListrErrorTypes,
ListrEventType: () => ListrEventType,
ListrTaskEventType: () => ListrTaskEventType,
ListrTaskState: () => ListrTaskState,
LogLevels: () => LogLevels,
Logger: () => Logger,
Manager: () => Manager,
PromptError: () => PromptError,
createPrompt: () => createPrompt,
destroyPrompt: () => destroyPrompt,
figures: () => figures
});
module.exports = __toCommonJS(src_exports);
// src/listr.ts
import pMap from "p-map";
import { Subject as Subject2 } from "rxjs";
var import_p_map = __toESM(require("p-map"));
// src/constants/state.constants.ts
var ListrTaskState = /* @__PURE__ */ ((ListrTaskState2) => {
ListrTaskState2["UNINITIALIZED"] = "UNINITIALIZED";
ListrTaskState2["PENDING"] = "PENDING";

@@ -17,20 +65,40 @@ ListrTaskState2["COMPLETED"] = "COMPLETED";

// src/lib/event-manager.ts
var import_eventemitter3 = __toESM(require("eventemitter3"));
var EventManager = class {
constructor() {
this.emitter = new import_eventemitter3.default();
}
emit(dispatch, args) {
this.emitter.emit(dispatch, args);
}
on(dispatch, handler) {
this.emitter.addListener(dispatch, handler);
}
complete() {
this.emitter.removeAllListeners();
}
};
// src/lib/task.ts
import { isObservable, Subject } from "rxjs";
import { Readable } from "stream";
var import_stream = require("stream");
// src/constants/event.constants.ts
var ListrEventType = /* @__PURE__ */ ((ListrEventType2) => {
ListrEventType2["TITLE"] = "TITLE";
ListrEventType2["STATE"] = "STATE";
ListrEventType2["ENABLED"] = "ENABLED";
ListrEventType2["SUBTASK"] = "SUBTASK";
ListrEventType2["DATA"] = "DATA";
ListrEventType2["MESSAGE"] = "MESSAGE";
ListrEventType2["SHOULD_REFRESH_RENDER"] = "SHOUD_REFRESH_RENDER";
return ListrEventType2;
})(ListrEventType || {});
var ListrTaskEventType = /* @__PURE__ */ ((ListrTaskEventType2) => {
ListrTaskEventType2["TITLE"] = "TITLE";
ListrTaskEventType2["STATE"] = "STATE";
ListrTaskEventType2["ENABLED"] = "ENABLED";
ListrTaskEventType2["SUBTASK"] = "SUBTASK";
ListrTaskEventType2["DATA"] = "DATA";
ListrTaskEventType2["MESSAGE"] = "MESSAGE";
return ListrTaskEventType2;
})(ListrTaskEventType || {});
// src/utils/general.ts
import rfdc from "rfdc";
var clone = rfdc({ circles: true });
var import_rfdc = __toESM(require("rfdc"));
var clone = (0, import_rfdc.default)({ circles: true });
function cloneObject(obj) {

@@ -80,12 +148,17 @@ return clone(obj);

// src/utils/is-observable.ts
function isObservable(obj) {
return !!obj && typeof obj.lift === "function" && typeof obj.subscribe === "function";
}
// src/renderer/default.renderer.ts
import cliTruncate from "cli-truncate";
import logUpdate from "log-update";
import { EOL } from "os";
import cliWrap from "wrap-ansi";
var import_cli_truncate = __toESM(require("cli-truncate"));
var import_log_update = __toESM(require("log-update"));
var import_os = require("os");
var import_wrap_ansi = __toESM(require("wrap-ansi"));
// src/utils/colorette.ts
import { createColors } from "colorette";
var import_colorette = require("colorette");
var _a;
var colorette_default = createColors({ useColor: ((_a = process.env) == null ? void 0 : _a.LISTR_DISABLE_COLOR) !== "1" });
var colorette_default = (0, import_colorette.createColors)({ useColor: ((_a = process.env) == null ? void 0 : _a.LISTR_DISABLE_COLOR) !== "1" });

@@ -148,6 +221,6 @@ // src/utils/is-unicode-supported.ts

var _DefaultRenderer = class {
constructor(tasks, options, renderHook$) {
constructor(tasks, options, events) {
this.tasks = tasks;
this.options = options;
this.renderHook$ = renderHook$;
this.events = events;
this.bottomBar = {};

@@ -175,2 +248,3 @@ this.spinner = !isUnicodeSupported() ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];

}
/* istanbul ignore next */
getTaskTime(task) {

@@ -196,8 +270,8 @@ return colorette_default.dim(`[${parseTaskTime(task.message.duration)}]`);

if (options.bottomBar && (renderBottomBar == null ? void 0 : renderBottomBar.trim().length) > 0) {
render.push((render.length > 0 ? EOL : "") + renderBottomBar);
render.push((render.length > 0 ? import_os.EOL : "") + renderBottomBar);
}
if (options.prompt && (renderPrompt == null ? void 0 : renderPrompt.trim().length) > 0) {
render.push((render.length > 0 ? EOL : "") + renderPrompt);
render.push((render.length > 0 ? import_os.EOL : "") + renderPrompt);
}
return render.length > 0 ? render.join(EOL) : "";
return render.length > 0 ? render.join(import_os.EOL) : "";
}

@@ -209,3 +283,3 @@ render() {

}
const updateRender = () => logUpdate(this.createRender());
const updateRender = () => (0, import_log_update.default)(this.createRender());
if (!((_a2 = this.options) == null ? void 0 : _a2.lazy)) {

@@ -217,3 +291,3 @@ this.id = setInterval(() => {

}
this.renderHook$.subscribe(() => {
this.events.on("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */, () => {
updateRender();

@@ -227,8 +301,9 @@ });

}
logUpdate.clear();
logUpdate.done();
import_log_update.default.clear();
import_log_update.default.done();
if (!this.options.clearOutput) {
process.stdout.write(this.createRender({ prompt: false }) + EOL);
process.stdout.write(this.createRender({ prompt: false }) + import_os.EOL);
}
}
// eslint-disable-next-line complexity
multiLineRenderer(tasks, level = 0) {

@@ -303,3 +378,11 @@ var _a2, _b;

}
if (this.getSelfOrParentOption(task, "showSubtasks") !== false && task.hasSubtasks() && (task.isPending() || task.hasFailed() || task.isCompleted() && !task.hasTitle() || task.isCompleted() && this.getSelfOrParentOption(task, "collapse") === false && !task.subtasks.some((subtask) => subtask.rendererOptions.collapse === true) || task.subtasks.some((subtask) => subtask.rendererOptions.collapse === false) || task.subtasks.some((subtask) => subtask.hasFailed()) || task.subtasks.some((subtask) => subtask.hasRolledBack()))) {
if (
// check if renderer option is on first
this.getSelfOrParentOption(task, "showSubtasks") !== false && // if it doesnt have subtasks no need to check
task.hasSubtasks() && (task.isPending() || task.hasFailed() || task.isCompleted() && !task.hasTitle() || // have to be completed and have subtasks
task.isCompleted() && this.getSelfOrParentOption(task, "collapse") === false && !task.subtasks.some((subtask) => subtask.rendererOptions.collapse === true) || // if any of the subtasks have the collapse option of
task.subtasks.some((subtask) => subtask.rendererOptions.collapse === false) || // if any of the subtasks has failed
task.subtasks.some((subtask) => subtask.hasFailed()) || // if any of the subtasks rolled back
task.subtasks.some((subtask) => subtask.hasRolledBack()))
) {
const subtaskLevel = !task.hasTitle() ? level : level + 1;

@@ -311,3 +394,3 @@ const subtaskRender = this.multiLineRenderer(task.subtasks, subtaskLevel);

}
if (task.isCompleted() || task.hasFailed() || task.isSkipped() || task.hasRolledBack()) {
if (task.hasFinalized()) {
this.promptBar = null;

@@ -322,3 +405,3 @@ if (!this.hasPersistentOutput(task)) {

if (output.length > 0) {
return output.join(EOL);
return output.join(import_os.EOL);
} else {

@@ -339,3 +422,3 @@ return;

}, {});
return Object.values(this.bottomBar).reduce((o, value) => o = [...o, ...value.data], []).filter(Boolean).join(EOL);
return Object.values(this.bottomBar).reduce((o, value) => o = [...o, ...value.data], []).filter(Boolean).join(import_os.EOL);
}

@@ -378,8 +461,8 @@ }

case "truncate":
parsedStr = str.split(EOL).map((s, i) => {
return cliTruncate(this.indentMultilineOutput(s, i), columns);
parsedStr = str.split(import_os.EOL).map((s, i) => {
return (0, import_cli_truncate.default)(this.indentMultilineOutput(s, i), columns);
});
break;
case "wrap":
parsedStr = cliWrap(str, columns, { hard: true }).split(EOL).map((s, i) => this.indentMultilineOutput(s, i));
parsedStr = (0, import_wrap_ansi.default)(str, columns, { hard: true }).split(import_os.EOL).map((s, i) => this.indentMultilineOutput(s, i));
break;

@@ -392,3 +475,3 @@ default:

}
return indentString(parsedStr.join(EOL), level * this.options.indentation);
return indentString(parsedStr.join(import_os.EOL), level * this.options.indentation);
}

@@ -398,2 +481,3 @@ indentMultilineOutput(str, i) {

}
// eslint-disable-next-line complexity
getSymbol(task, data = false) {

@@ -425,3 +509,5 @@ var _a2, _b, _c;

var DefaultRenderer = _DefaultRenderer;
/** designates whether this renderer can output to a non-tty console */
DefaultRenderer.nonTTY = false;
/** renderer options for the defauult renderer */
DefaultRenderer.rendererOptions = {

@@ -455,7 +541,8 @@ indentation: 2,

};
/** designates whether this renderer can output to a non-tty console */
SilentRenderer.nonTTY = true;
// src/renderer/simple.renderer.ts
import { stderr as logUpdate2 } from "log-update";
import { EOL as EOL2 } from "os";
var import_log_update2 = require("log-update");
var import_os2 = require("os");
var _SimpleRenderer = class {

@@ -465,51 +552,16 @@ constructor(tasks, options) {

this.options = options;
this.eventTypeRendererMap = {
["SUBTASK" /* SUBTASK */]: (task) => {
if (task.hasTitle()) {
this.log(`${colorette_default.blue(figures.pointer)} ${task.title}`);
}
if (task.hasSubtasks()) {
this.render(task.subtasks);
}
},
["STATE" /* STATE */]: (task) => {
if (task.isCompleted() && task.hasTitle()) {
this.log(`${colorette_default.green(figures.tick)} ${task.title}`);
}
},
["DATA" /* DATA */]: (task, event) => {
if (task.isPrompt() && !String(event.data).match(/^\n$/)) {
logUpdate2(`${event.data}`);
} else {
this.log(`${figures.pointerSmall} ${event.data}`);
}
},
["MESSAGE" /* MESSAGE */]: (task, event) => {
if (event.data.error) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`${colorette_default.red(figures.cross)}${title}: ${event.data.error}`);
} else if (event.data.skip) {
const title = _SimpleRenderer.formatTitle(task);
const skip = task.title !== event.data.skip ? `: ${event.data.skip}` : "";
this.log(`${colorette_default.yellow(figures.arrowDown)}${title} [${colorette_default.yellow(`skipped${skip}`)}]`);
} else if (event.data.rollback) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`${colorette_default.red(figures.arrowLeft)}${title}: ${event.data.rollback}`);
} else if (event.data.retry) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`[${colorette_default.yellow(`${event.data.retry.count}`)}]${title}`);
}
}
};
this.options = { ..._SimpleRenderer.rendererOptions, ...options };
}
// This is used for mocks, since mocking Date is cumbesome
static now() {
return new Date();
return /* @__PURE__ */ new Date();
}
// Used to sanitize title output
static formatTitle(task) {
return (task == null ? void 0 : task.title) ? ` ${task.title}` : "";
}
// Writes sanitized output
log(output) {
const logOut = (msg) => {
process[this.options.output].write(msg.endsWith(EOL2) ? msg : `${msg}${EOL2}`);
process[this.options.output].write(msg.endsWith(import_os2.EOL) ? msg : `${msg}${import_os2.EOL}`);
};

@@ -524,21 +576,56 @@ if (!this.options.prefixWithTimestamp) {

}
// eslint-disable-next-line
end() {
}
render(tasks) {
if (tasks == null ? void 0 : tasks.length) {
tasks.forEach((task) => {
task.subscribe((event) => {
var _a2, _b;
(_b = (_a2 = this.eventTypeRendererMap)[event.type]) == null ? void 0 : _b.call(_a2, task, event);
}, this.log);
render() {
this.simpleRenderer(this.tasks);
}
simpleRenderer(tasks) {
tasks.forEach((task) => {
task.on("SUBTASK" /* SUBTASK */, (subtasks) => {
if (task.hasTitle()) {
this.log(`${colorette_default.blue(figures.pointer)} ${task.title}`);
}
this.simpleRenderer(subtasks);
});
} else {
this.render(this.tasks);
}
task.on("STATE" /* STATE */, (state) => {
if (state === "COMPLETED" /* COMPLETED */ && task.hasTitle()) {
this.log(`${colorette_default.green(figures.tick)} ${task.title}`);
}
});
task.on("DATA" /* DATA */, (data) => {
if (task.isPrompt() && !String(data).match(/^\n$/)) {
(0, import_log_update2.stderr)(data);
} else {
this.log(`${figures.pointerSmall} ${data}`);
}
});
task.on("MESSAGE" /* MESSAGE */, (message) => {
if (message.error) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`${colorette_default.red(figures.cross)}${title}: ${message.error}`);
} else if (message.skip) {
const title = _SimpleRenderer.formatTitle(task);
const skip = task.title !== message.skip ? `: ${message.skip}` : "";
this.log(`${colorette_default.yellow(figures.arrowDown)}${title} [${colorette_default.yellow(`skipped${skip}`)}]`);
} else if (message.rollback) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`${colorette_default.red(figures.arrowLeft)}${title}: ${message.rollback}`);
} else if (message.retry) {
const title = _SimpleRenderer.formatTitle(task);
this.log(`[${colorette_default.yellow(`${message.retry.count}`)}]${title}`);
}
});
});
}
};
var SimpleRenderer = _SimpleRenderer;
// Designate this renderer as tty or nonTTY
SimpleRenderer.nonTTY = true;
// designate your renderer options that will be showed inside the `ListrOptions` as rendererOptions
SimpleRenderer.rendererOptions = { prefixWithTimestamp: false, output: "stdout" };
// src/constants/listr.constants.ts
var TASK_WITHOUT_TITLE = "Task without title.";
// src/utils/logger.constants.ts

@@ -689,12 +776,11 @@ var LogLevels = /* @__PURE__ */ ((LogLevels2) => {

var _VerboseRenderer = class {
constructor(tasks, options) {
constructor(tasks, options, events) {
this.tasks = tasks;
this.options = options;
var _a2, _b, _c, _d;
if (((_a2 = this.options) == null ? void 0 : _a2.logger) && ((_b = this.options) == null ? void 0 : _b.options)) {
this.logger = new this.options.logger(this.options.options);
} else if ((_c = this.options) == null ? void 0 : _c.logger) {
this.logger = new this.options.logger();
this.events = events;
var _a2, _b;
if ((_a2 = this.options) == null ? void 0 : _a2.logger) {
this.logger = new this.options.logger(options == null ? void 0 : options.options);
} else {
this.logger = new Logger({ useIcons: (_d = this.options) == null ? void 0 : _d.useIcons });
this.logger = new Logger({ useIcons: (_b = this.options) == null ? void 0 : _b.useIcons });
}

@@ -706,44 +792,46 @@ this.options = { ..._VerboseRenderer.rendererOptions, ...this.options };

}
// eslint-disable-next-line @typescript-eslint/no-empty-function
end() {
}
// verbose renderer multi-level
verboseRenderer(tasks) {
return tasks == null ? void 0 : tasks.forEach((task) => {
task.subscribe(
(event) => {
var _a2, _b, _c, _d, _e, _f, _g, _h;
if (task.isEnabled()) {
const taskTitle = task.hasTitle() ? task.title : "Task without title.";
if (event.type === "SUBTASK" /* SUBTASK */ && task.hasSubtasks()) {
this.verboseRenderer(task.subtasks);
} else if (event.type === "STATE" /* STATE */) {
if (((_a2 = this.options) == null ? void 0 : _a2.logEmptyTitle) !== false || task.hasTitle()) {
if (task.isPending()) {
this.logger.start(taskTitle);
} else if (task.isCompleted()) {
this.logger.success(taskTitle + (((_b = this.options) == null ? void 0 : _b.showTimer) && ((_c = task.message) == null ? void 0 : _c.duration) ? ` [${parseTaskTime(task.message.duration)}]` : ""));
}
}
} else if (event.type === "DATA" /* DATA */ && !!event.data) {
this.logger.data(String(event.data));
} else if (event.type === "TITLE" /* TITLE */) {
if (((_d = this.options) == null ? void 0 : _d.logTitleChange) !== false) {
this.logger.title(String(event.data));
}
} else if (event.type === "MESSAGE" /* MESSAGE */) {
if ((_e = event.data) == null ? void 0 : _e.error) {
this.logger.fail(String(event.data.error));
} else if ((_f = event.data) == null ? void 0 : _f.skip) {
this.logger.skip(String(event.data.skip));
} else if ((_g = event.data) == null ? void 0 : _g.rollback) {
this.logger.rollback(String(event.data.rollback));
} else if ((_h = event.data) == null ? void 0 : _h.retry) {
this.logger.retry(`[${event.data.retry.count}] ` + String(taskTitle));
}
}
var _a2;
task.on("SUBTASK" /* SUBTASK */, (subtasks) => {
this.verboseRenderer(subtasks);
});
task.on("STATE" /* STATE */, (state) => {
var _a3, _b, _c;
if (task.hasTitle() || ((_a3 = this.options) == null ? void 0 : _a3.logEmptyTitle) !== false) {
const title = task.hasTitle() ? task.title : TASK_WITHOUT_TITLE;
switch (state) {
case "PENDING" /* PENDING */:
this.logger.start(title);
break;
case "COMPLETED" /* COMPLETED */:
this.logger.success(title + (((_b = this.options) == null ? void 0 : _b.showTimer) && ((_c = task.message) == null ? void 0 : _c.duration) ? ` [${parseTaskTime(task.message.duration)}]` : ""));
break;
}
},
(err) => {
this.logger.fail(err);
}
);
});
task.on("DATA" /* DATA */, (data) => {
this.logger.data(data);
});
if (((_a2 = this.options) == null ? void 0 : _a2.logTitleChange) !== false) {
task.on("TITLE" /* TITLE */, (title) => {
this.logger.title(title);
});
}
task.on("MESSAGE" /* MESSAGE */, (message) => {
if (message == null ? void 0 : message.error) {
this.logger.fail(message.error);
} else if (message == null ? void 0 : message.skip) {
this.logger.skip(message.skip);
} else if (message == null ? void 0 : message.rollback) {
this.logger.rollback(message.rollback);
} else if (message == null ? void 0 : message.retry) {
const title = task.hasTitle() ? task.title : TASK_WITHOUT_TITLE;
this.logger.retry(`[${message.retry.count}] ` + title);
}
});
});

@@ -753,3 +841,5 @@ }

var VerboseRenderer = _VerboseRenderer;
/** designates whether this renderer can output to a non-tty console */
VerboseRenderer.nonTTY = true;
/** renderer options for the verbose renderer */
VerboseRenderer.rendererOptions = {

@@ -803,5 +893,5 @@ useIcons: false,

// src/lib/task.ts
var Task = class extends Subject {
var Task = class extends EventManager {
constructor(listr, tasks, options, rendererOptions) {
var _a2, _b, _c, _d;
var _a2, _b;
super();

@@ -812,21 +902,20 @@ this.listr = listr;

this.rendererOptions = rendererOptions;
/** Unique id per task, randomly generated in the uuid v4 format */
this.id = generateUUID();
/** The current state of the task. */
this.state = "UNINITIALIZED" /* UNINITIALIZED */;
/**
* A channel for messages.
*
* This requires a separate channel for messages like error, skip or runtime messages to further utilize in the renderers.
*/
this.message = {};
this.id = generateUUID();
this.title = (_a2 = this.tasks) == null ? void 0 : _a2.title;
this.initialTitle = (_b = this.tasks) == null ? void 0 : _b.title;
this.task = this.tasks.task;
this.skip = ((_c = this.tasks) == null ? void 0 : _c.skip) ?? false;
this.enabledFn = ((_d = this.tasks) == null ? void 0 : _d.enabled) ?? true;
this.rendererTaskOptions = this.tasks.options;
this.renderHook$ = this.listr.renderHook$;
this.subscribe(() => {
this.renderHook$.next();
});
}
set state$(state) {
this.state = state;
this.next({
type: "STATE" /* STATE */,
data: state
});
this.emit("STATE" /* STATE */, state);
if (this.hasSubtasks() && this.hasFailed()) {

@@ -839,33 +928,31 @@ for (const subtask of this.subtasks) {

}
this.emitShouldRefreshRender();
}
set output$(data) {
this.output = data;
this.next({
type: "DATA" /* DATA */,
data
});
this.emit("DATA" /* DATA */, data);
this.emitShouldRefreshRender();
}
set message$(data) {
this.message = { ...this.message, ...data };
this.next({
type: "MESSAGE" /* MESSAGE */,
data
});
this.emit("MESSAGE" /* MESSAGE */, data);
this.emitShouldRefreshRender();
}
set title$(title) {
this.title = title;
this.next({
type: "TITLE" /* TITLE */,
data: title
});
this.emit("TITLE" /* TITLE */, title);
this.emitShouldRefreshRender();
}
/**
* A function to check whether this task should run at all via enable.
*/
async check(ctx) {
if (this.state === void 0) {
this.enabled = await assertFunctionOrSelf(this.enabledFn, ctx);
this.next({
type: "ENABLED" /* ENABLED */,
data: this.enabled
});
var _a2;
if (this.state === "UNINITIALIZED" /* UNINITIALIZED */) {
this.enabled = await assertFunctionOrSelf(((_a2 = this.tasks) == null ? void 0 : _a2.enabled) ?? true, ctx);
this.emit("ENABLED" /* ENABLED */, this.enabled);
this.emitShouldRefreshRender();
}
}
/** Returns whether this task has subtasks. */
hasSubtasks() {

@@ -875,34 +962,49 @@ var _a2;

}
/** Returns whether this task is finalized in someform. */
hasFinalized() {
return this.isCompleted() || this.hasFailed() || this.isSkipped() || this.hasRolledBack();
}
/** Returns whether this task is in progress. */
isPending() {
return this.state === "PENDING" /* PENDING */;
}
/** Returns whether this task is skipped. */
isSkipped() {
return this.state === "SKIPPED" /* SKIPPED */;
}
/** Returns whether this task has been completed. */
isCompleted() {
return this.state === "COMPLETED" /* COMPLETED */;
}
/** Returns whether this task has been failed. */
hasFailed() {
return this.state === "FAILED" /* FAILED */;
}
/** Returns whether this task has an active rollback task going on. */
isRollingBack() {
return this.state === "ROLLING_BACK" /* ROLLING_BACK */;
}
/** Returns whether the rollback action was successful. */
hasRolledBack() {
return this.state === "ROLLED_BACK" /* ROLLED_BACK */;
}
/** Returns whether this task has an actively retrying task going on. */
isRetrying() {
return this.state === "RETRY" /* RETRY */;
}
/** Returns whether enabled function resolves to true. */
isEnabled() {
return this.enabled;
}
/** Returns whether this task actually has a title. */
hasTitle() {
return typeof (this == null ? void 0 : this.title) === "string";
}
/** Returns whether this task has a prompt inside. */
isPrompt() {
return !!this.prompt;
}
/** Run the current task. */
async run(context, wrapper) {
var _a2, _b, _c, _d, _e;
var _a2, _b, _c, _d, _e, _f;
const handleResult = (result) => {

@@ -912,8 +1014,5 @@ if (result instanceof Listr) {

result.rendererClass = getRenderer("silent").renderer;
result.renderHook$.subscribe(() => {
this.renderHook$.next();
});
this.subtasks = result.tasks;
result.err = this.listr.err;
this.next({ type: "SUBTASK" /* SUBTASK */ });
this.emit("SUBTASK" /* SUBTASK */, this.subtasks);
result = result.run(context);

@@ -923,3 +1022,3 @@ } else if (this.isPrompt()) {

result = result.then(handleResult);
} else if (result instanceof Readable) {
} else if (result instanceof import_stream.Readable) {
result = new Promise((resolve, reject) => {

@@ -947,3 +1046,3 @@ result.on("data", (data) => {

this.state$ = "PENDING" /* PENDING */;
const skipped = await assertFunctionOrSelf(this.skip, context);
const skipped = await assertFunctionOrSelf(((_a2 = this.tasks) == null ? void 0 : _a2.skip) ?? false, context);
if (skipped) {

@@ -961,3 +1060,3 @@ if (typeof skipped === "string") {

try {
const retryCount = ((_a2 = this.tasks) == null ? void 0 : _a2.retry) && ((_b = this.tasks) == null ? void 0 : _b.retry) > 0 ? this.tasks.retry + 1 : 1;
const retryCount = ((_b = this.tasks) == null ? void 0 : _b.retry) && ((_c = this.tasks) == null ? void 0 : _c.retry) > 0 ? this.tasks.retry + 1 : 1;
for (let retries = 1; retries <= retryCount; retries++) {

@@ -988,3 +1087,3 @@ try {

}
if ((_c = this.tasks) == null ? void 0 : _c.rollback) {
if ((_d = this.tasks) == null ? void 0 : _d.rollback) {
wrapper.report(error, "WILL_ROLLBACK" /* WILL_ROLLBACK */);

@@ -1001,3 +1100,3 @@ try {

}
if (((_d = this.listr.options) == null ? void 0 : _d.exitAfterRollback) !== false) {
if (((_e = this.listr.options) == null ? void 0 : _e.exitAfterRollback) !== false) {
throw new Error(this.title);

@@ -1007,3 +1106,3 @@ }

this.state$ = "FAILED" /* FAILED */;
if (this.listr.options.exitOnError !== false && await assertFunctionOrSelf((_e = this.tasks) == null ? void 0 : _e.exitOnError, context) !== false) {
if (this.listr.options.exitOnError !== false && await assertFunctionOrSelf((_f = this.tasks) == null ? void 0 : _f.exitOnError, context) !== false) {
wrapper.report(error, "HAS_FAILED" /* HAS_FAILED */);

@@ -1019,6 +1118,9 @@ throw error;

}
emitShouldRefreshRender() {
this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
}
};
// src/lib/task-wrapper.ts
import through from "through";
var import_through = __toESM(require("through"));

@@ -1058,2 +1160,3 @@ // src/constants/clearline-regex.constants.ts

Object.assign(option, {
// this is for outside calls, if it is not called from taskwrapper with bind
stdout: this instanceof TaskWrapper ? (settings == null ? void 0 : settings.stdout) ?? this.stdout() : process.stdout,

@@ -1079,4 +1182,4 @@ onCancel: cancelCallback.bind(this, settings)

enquirer.on("submit", () => this.task.prompt = void 0);
this.task.subscribe((event) => {
if (event.type === "STATE" /* STATE */ && event.data === "SKIPPED" /* SKIPPED */) {
this.task.on("STATE" /* STATE */, (event) => {
if (event === "SKIPPED" /* SKIPPED */) {
if (this.task.prompt && !(this.task.prompt instanceof PromptError)) {

@@ -1113,14 +1216,19 @@ this.task.prompt.submit();

}
/** Get the title of the current task. */
get title() {
return this.task.title;
}
/** Change the title of the current task. */
set title(data) {
this.task.title$ = data;
}
/** Get the output from the output channel. */
get output() {
return this.task.output;
}
/** Send a output to the output channel. */
set output(data) {
this.task.output$ = data;
}
/** Create a new subtask with given renderer selection from the parent task. */
newListr(task, options) {

@@ -1135,2 +1243,3 @@ let tasks;

}
/** Report a error in process for error collection. */
report(error, type) {

@@ -1143,2 +1252,3 @@ var _a2;

}
/** Skip current task. */
skip(message) {

@@ -1151,5 +1261,11 @@ var _a2;

}
/** Get the number of retrying, else returns false */
isRetrying() {
return this.task.isRetrying() ? this.task.retry : { count: 0 };
}
/**
* Create a new Enquirer prompt using prompt options.
*
* Since process.stdout is controlled by Listr, this will passthrough all Enquirer data through internal stdout.
*/
async prompt(options) {

@@ -1159,7 +1275,16 @@ var _a2;

}
/** Cancels the current prompt attach to this task. */
cancelPrompt(throwError = false) {
return destroyPrompt.bind(this)(throwError);
}
/**
* Pass stream of data to internal stdout.
*
* Since Listr2 takes control of process.stdout utilizing the default renderer, any data outputted to process.stdout
* will corrupt its looks.
*
* This returns a fake stream to pass any stream inside Listr as task data.
*/
stdout() {
return through((chunk) => {
return (0, import_through.default)((chunk) => {
chunk = chunk.toString();

@@ -1173,2 +1298,3 @@ chunk = chunk.replace(new RegExp(CLEAR_LINE_REGEX, "gmi"), "");

}
/** Run this task. */
run(ctx) {

@@ -1187,15 +1313,12 @@ return this.task.run(ctx, this);

this.err = [];
this.renderHook$ = new Subject2();
this.path = [];
var _a2, _b, _c;
var _a2, _b, _c, _d;
this.options = {
...{
concurrent: false,
renderer: "default",
nonTTYRenderer: "verbose",
exitOnError: true,
exitAfterRollback: true,
collectErrors: "minimal",
registerSignalListeners: true
},
concurrent: false,
renderer: "default",
nonTTYRenderer: "verbose",
exitOnError: true,
exitAfterRollback: true,
collectErrors: "minimal",
registerSignalListeners: true,
...options

@@ -1210,3 +1333,8 @@ };

}
const renderer = getRenderer(this.options.renderer, this.options.nonTTYRenderer, (_a2 = this.options) == null ? void 0 : _a2.rendererFallback, (_b = this.options) == null ? void 0 : _b.rendererSilent);
if (((_a2 = this.parentTask) == null ? void 0 : _a2.listr.events) instanceof EventManager) {
this.events = this.parentTask.listr.events;
} else {
this.events = new EventManager();
}
const renderer = getRenderer(this.options.renderer, this.options.nonTTYRenderer, (_b = this.options) == null ? void 0 : _b.rendererFallback, (_c = this.options) == null ? void 0 : _c.rendererSilent);
this.rendererClass = renderer.renderer;

@@ -1233,3 +1361,3 @@ if (!renderer.nonTTY) {

}
if ((_c = this.options) == null ? void 0 : _c.disableColor) {
if ((_d = this.options) == null ? void 0 : _d.disableColor) {
process.env.LISTR_DISABLE_COLOR = "1";

@@ -1247,9 +1375,9 @@ }

if (!this.renderer) {
this.renderer = new this.rendererClass(this.tasks, this.rendererClassOptions, this.renderHook$);
this.renderer = new this.rendererClass(this.tasks, this.rendererClassOptions, this.events);
}
this.renderer.render();
this.ctx = ((_a2 = this.options) == null ? void 0 : _a2.ctx) ?? context ?? {};
await this.checkAll(this.ctx);
await Promise.all(this.tasks.map((task) => task.check(this.ctx)));
try {
await pMap(
await (0, import_p_map.default)(
this.tasks,

@@ -1271,5 +1399,2 @@ async (task) => {

}
checkAll(context) {
return Promise.all(this.tasks.map((task) => task.check(context)));
}
runTask(task, context, errors) {

@@ -1329,7 +1454,5 @@ if (!task.isEnabled()) {

}
getRuntime(pipetime) {
return `${Math.round(Date.now() - pipetime) / 1e3}s`;
}
};
export {
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Listr,

@@ -1339,2 +1462,3 @@ ListrError,

ListrEventType,
ListrTaskEventType,
ListrTaskState,

@@ -1348,2 +1472,2 @@ LogLevels,

figures
};
});
{
"name": "listr2",
"version": "5.0.8",
"version": "5.1.0-beta.1",
"description": "Terminal task list reborn! Create beautiful CLI interfaces via easy and logical to implement task lists that feel alive and interactive.",
"license": "MIT",
"repository": "https://github.com/cenk1cenk2/listr2",
"type": "module",
"main": "./dist/index.cjs",

@@ -74,6 +73,6 @@ "module": "./dist/index.js",

"colorette": "^2.0.19",
"eventemitter3": "^5.0.0",
"log-update": "^4.0.0",
"p-map": "^4.0.0",
"rfdc": "^1.3.0",
"rxjs": "^7.8.0",
"through": "^2.3.8",

@@ -83,4 +82,4 @@ "wrap-ansi": "^7.0.0"

"devDependencies": {
"@cenk1cenk2/cz-cc": "^1.5.3",
"@cenk1cenk2/eslint-config": "2.5.26",
"@cenk1cenk2/cz-cc": "^1.5.9",
"@cenk1cenk2/eslint-config": "2.5.52",
"@types/clone": "^2.1.1",

@@ -99,7 +98,8 @@ "@types/jest": "^29.0.0",

"rimraf": "^4.0.5",
"rxjs": "^7.8.0",
"simple-git-hooks": "^2.8.0",
"ts-jest": "^28.0.8",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.1.0",
"tsup": "6.2.3",
"tsup": "6.6.3",
"typedoc": "^0.23.14",

@@ -106,0 +106,0 @@ "typedoc-plugin-markdown": "^3.13.6",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc