You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1344 lines
45 KiB
1344 lines
45 KiB
"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(
|
|
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,
|
|
ListrTaskState: () => ListrTaskState,
|
|
LogLevels: () => LogLevels,
|
|
Logger: () => Logger,
|
|
Manager: () => Manager,
|
|
PromptError: () => PromptError,
|
|
createPrompt: () => createPrompt,
|
|
destroyPrompt: () => destroyPrompt,
|
|
figures: () => figures
|
|
});
|
|
module.exports = __toCommonJS(src_exports);
|
|
|
|
// src/listr.ts
|
|
var import_p_map = __toESM(require("p-map"), 1);
|
|
var import_rxjs2 = require("rxjs");
|
|
|
|
// src/constants/state.constants.ts
|
|
var ListrTaskState = /* @__PURE__ */ ((ListrTaskState2) => {
|
|
ListrTaskState2["PENDING"] = "PENDING";
|
|
ListrTaskState2["COMPLETED"] = "COMPLETED";
|
|
ListrTaskState2["FAILED"] = "FAILED";
|
|
ListrTaskState2["SKIPPED"] = "SKIPPED";
|
|
ListrTaskState2["ROLLING_BACK"] = "ROLLING_BACK";
|
|
ListrTaskState2["ROLLED_BACK"] = "ROLLED_BACK";
|
|
ListrTaskState2["RETRY"] = "RETRY";
|
|
return ListrTaskState2;
|
|
})(ListrTaskState || {});
|
|
|
|
// src/lib/task.ts
|
|
var import_rxjs = require("rxjs");
|
|
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";
|
|
return ListrEventType2;
|
|
})(ListrEventType || {});
|
|
|
|
// src/utils/general.ts
|
|
var import_rfdc = __toESM(require("rfdc"), 1);
|
|
var clone = (0, import_rfdc.default)({ circles: true });
|
|
function cloneObject(obj) {
|
|
return clone(obj);
|
|
}
|
|
|
|
// src/interfaces/listr-error.interface.ts
|
|
var ListrError = class extends Error {
|
|
constructor(error, type, task) {
|
|
super(error.message);
|
|
this.error = error;
|
|
this.type = type;
|
|
this.task = task;
|
|
this.name = "ListrError";
|
|
this.path = [...task.listr.path ?? [], task.title].join(" > ");
|
|
if ((task == null ? void 0 : task.options.collectErrors) === "full") {
|
|
this.task = cloneObject(task);
|
|
this.ctx = cloneObject(task.listr.ctx);
|
|
}
|
|
this.stack = error == null ? void 0 : error.stack;
|
|
}
|
|
};
|
|
var ListrErrorTypes = /* @__PURE__ */ ((ListrErrorTypes2) => {
|
|
ListrErrorTypes2["WILL_RETRY"] = "WILL_RETRY";
|
|
ListrErrorTypes2["WILL_ROLLBACK"] = "WILL_ROLLBACK";
|
|
ListrErrorTypes2["HAS_FAILED_TO_ROLLBACK"] = "HAS_FAILED_TO_ROLLBACK";
|
|
ListrErrorTypes2["HAS_FAILED"] = "HAS_FAILED";
|
|
ListrErrorTypes2["HAS_FAILED_WITHOUT_ERROR"] = "HAS_FAILED_WITHOUT_ERROR";
|
|
return ListrErrorTypes2;
|
|
})(ListrErrorTypes || {});
|
|
var PromptError = class extends Error {
|
|
constructor(message) {
|
|
super(message);
|
|
this.name = "PromptError";
|
|
}
|
|
};
|
|
|
|
// src/utils/assert.ts
|
|
function assertFunctionOrSelf(functionOrSelf, ...args) {
|
|
if (typeof functionOrSelf === "function") {
|
|
return functionOrSelf(...args);
|
|
} else {
|
|
return functionOrSelf;
|
|
}
|
|
}
|
|
|
|
// src/renderer/default.renderer.ts
|
|
var import_cli_truncate = __toESM(require("cli-truncate"), 1);
|
|
var import_log_update = __toESM(require("log-update"), 1);
|
|
var import_os = require("os");
|
|
var import_wrap_ansi = __toESM(require("wrap-ansi"), 1);
|
|
|
|
// src/utils/colorette.ts
|
|
var import_colorette = require("colorette");
|
|
var _a;
|
|
var colorette_default = (0, import_colorette.createColors)({ useColor: ((_a = process.env) == null ? void 0 : _a.LISTR_DISABLE_COLOR) !== "1" });
|
|
|
|
// src/utils/is-unicode-supported.ts
|
|
function isUnicodeSupported() {
|
|
if (process.platform !== "win32") {
|
|
return true;
|
|
}
|
|
return Boolean(process.env.CI) || Boolean(process.env.WT_SESSION) || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty";
|
|
}
|
|
|
|
// src/utils/figures.ts
|
|
var FIGURES_MAIN = {
|
|
warning: "\u26A0",
|
|
cross: "\u2716",
|
|
arrowDown: "\u2193",
|
|
tick: "\u2714",
|
|
arrowRight: "\u2192",
|
|
pointer: "\u276F",
|
|
checkboxOn: "\u2612",
|
|
arrowLeft: "\u2190",
|
|
squareSmallFilled: "\u25FC",
|
|
pointerSmall: "\u203A"
|
|
};
|
|
var FIGURES_FALLBACK = {
|
|
...FIGURES_MAIN,
|
|
warning: "\u203C",
|
|
cross: "\xD7",
|
|
tick: "\u221A",
|
|
pointer: ">",
|
|
checkboxOn: "[\xD7]",
|
|
squareSmallFilled: "\u25A0"
|
|
};
|
|
var figures = isUnicodeSupported() ? FIGURES_MAIN : FIGURES_FALLBACK;
|
|
|
|
// src/utils/indent-string.ts
|
|
function indentString(string, count) {
|
|
return string.replace(/^(?!\s*$)/gm, " ".repeat(count));
|
|
}
|
|
|
|
// src/utils/parse-time.ts
|
|
function parseTaskTime(duration) {
|
|
const seconds = Math.floor(duration / 1e3);
|
|
const minutes = Math.floor(seconds / 60);
|
|
let parsedTime;
|
|
if (seconds === 0 && minutes === 0) {
|
|
parsedTime = `0.${Math.floor(duration / 100)}s`;
|
|
}
|
|
if (seconds > 0) {
|
|
parsedTime = `${seconds % 60}s`;
|
|
}
|
|
if (minutes > 0) {
|
|
parsedTime = `${minutes}m${parsedTime}`;
|
|
}
|
|
return parsedTime;
|
|
}
|
|
|
|
// src/renderer/default.renderer.ts
|
|
var _DefaultRenderer = class {
|
|
constructor(tasks, options, renderHook$) {
|
|
this.tasks = tasks;
|
|
this.options = options;
|
|
this.renderHook$ = renderHook$;
|
|
this.bottomBar = {};
|
|
this.spinner = !isUnicodeSupported() ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
this.spinnerPosition = 0;
|
|
this.options = { ..._DefaultRenderer.rendererOptions, ...this.options };
|
|
}
|
|
getTaskOptions(task) {
|
|
return { ..._DefaultRenderer.rendererTaskOptions, ...task.rendererTaskOptions };
|
|
}
|
|
isBottomBar(task) {
|
|
const bottomBar = this.getTaskOptions(task).bottomBar;
|
|
return typeof bottomBar === "number" && bottomBar !== 0 || typeof bottomBar === "boolean" && bottomBar !== false;
|
|
}
|
|
hasPersistentOutput(task) {
|
|
return this.getTaskOptions(task).persistentOutput === true;
|
|
}
|
|
hasTimer(task) {
|
|
return this.getTaskOptions(task).showTimer === true;
|
|
}
|
|
getSelfOrParentOption(task, key) {
|
|
var _a2, _b;
|
|
return ((_a2 = task == null ? void 0 : task.rendererOptions) == null ? void 0 : _a2[key]) ?? ((_b = this.options) == null ? void 0 : _b[key]);
|
|
}
|
|
getTaskTime(task) {
|
|
return colorette_default.dim(`[${parseTaskTime(task.message.duration)}]`);
|
|
}
|
|
createRender(options) {
|
|
options = {
|
|
...{
|
|
tasks: true,
|
|
bottomBar: true,
|
|
prompt: true
|
|
},
|
|
...options
|
|
};
|
|
const render = [];
|
|
const renderTasks = this.multiLineRenderer(this.tasks);
|
|
const renderBottomBar = this.renderBottomBar();
|
|
const renderPrompt = this.renderPrompt();
|
|
if (options.tasks && (renderTasks == null ? void 0 : renderTasks.trim().length) > 0) {
|
|
render.push(renderTasks);
|
|
}
|
|
if (options.bottomBar && (renderBottomBar == null ? void 0 : renderBottomBar.trim().length) > 0) {
|
|
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 ? import_os.EOL : "") + renderPrompt);
|
|
}
|
|
return render.length > 0 ? render.join(import_os.EOL) : "";
|
|
}
|
|
render() {
|
|
var _a2;
|
|
if (this.id) {
|
|
return;
|
|
}
|
|
const updateRender = () => (0, import_log_update.default)(this.createRender());
|
|
if (!((_a2 = this.options) == null ? void 0 : _a2.lazy)) {
|
|
this.id = setInterval(() => {
|
|
this.spinnerPosition = ++this.spinnerPosition % this.spinner.length;
|
|
updateRender();
|
|
}, 100);
|
|
}
|
|
this.renderHook$.subscribe(() => {
|
|
updateRender();
|
|
});
|
|
}
|
|
end() {
|
|
clearInterval(this.id);
|
|
if (this.id) {
|
|
this.id = void 0;
|
|
}
|
|
import_log_update.default.clear();
|
|
import_log_update.default.done();
|
|
if (!this.options.clearOutput) {
|
|
process.stdout.write(this.createRender({ prompt: false }) + import_os.EOL);
|
|
}
|
|
}
|
|
multiLineRenderer(tasks, level = 0) {
|
|
var _a2, _b;
|
|
let output = [];
|
|
for (const task of tasks) {
|
|
if (task.isEnabled()) {
|
|
if (task.hasTitle()) {
|
|
if (!(tasks.some((task2) => task2.hasFailed()) && !task.hasFailed() && task.options.exitOnError !== false && !(task.isCompleted() || task.isSkipped()))) {
|
|
if (task.hasFailed() && this.getSelfOrParentOption(task, "collapseErrors")) {
|
|
output = [
|
|
...output,
|
|
this.formatString(
|
|
!task.hasSubtasks() && task.message.error && this.getSelfOrParentOption(task, "showErrorMessage") ? task.message.error : task.title,
|
|
this.getSymbol(task),
|
|
level
|
|
)
|
|
];
|
|
} else if (task.isSkipped() && this.getSelfOrParentOption(task, "collapseSkips")) {
|
|
output = [
|
|
...output,
|
|
this.formatString(
|
|
this.addSuffixToMessage(
|
|
task.message.skip && this.getSelfOrParentOption(task, "showSkipMessage") ? task.message.skip : task.title,
|
|
"SKIPPED",
|
|
this.getSelfOrParentOption(task, "suffixSkips")
|
|
),
|
|
this.getSymbol(task),
|
|
level
|
|
)
|
|
];
|
|
} else if (task.isRetrying() && this.getSelfOrParentOption(task, "suffixRetries")) {
|
|
output = [...output, this.formatString(this.addSuffixToMessage(task.title, `RETRYING-${task.message.retry.count}`), this.getSymbol(task), level)];
|
|
} else if (task.isCompleted() && task.hasTitle() && (this.getSelfOrParentOption(task, "showTimer") || this.hasTimer(task))) {
|
|
output = [...output, this.formatString(`${task == null ? void 0 : task.title} ${this.getTaskTime(task)}`, this.getSymbol(task), level)];
|
|
} else {
|
|
output = [...output, this.formatString(task.title, this.getSymbol(task), level)];
|
|
}
|
|
} else {
|
|
output = [...output, this.formatString(task.title, colorette_default.red(figures.squareSmallFilled), level)];
|
|
}
|
|
}
|
|
if (!task.hasSubtasks() || !this.getSelfOrParentOption(task, "showSubtasks")) {
|
|
if (task.hasFailed() && this.getSelfOrParentOption(task, "collapseErrors") === false && (this.getSelfOrParentOption(task, "showErrorMessage") || !this.getSelfOrParentOption(task, "showSubtasks"))) {
|
|
output = [...output, this.dumpData(task, level, "error")];
|
|
} else if (task.isSkipped() && this.getSelfOrParentOption(task, "collapseSkips") === false && (this.getSelfOrParentOption(task, "showSkipMessage") || !this.getSelfOrParentOption(task, "showSubtasks"))) {
|
|
output = [...output, this.dumpData(task, level, "skip")];
|
|
}
|
|
}
|
|
if (task == null ? void 0 : task.output) {
|
|
if ((task.isPending() || task.isRetrying() || task.isRollingBack()) && task.isPrompt()) {
|
|
this.promptBar = task.output;
|
|
} else if (this.isBottomBar(task) || !task.hasTitle()) {
|
|
const data = [this.dumpData(task, -1)];
|
|
if (!this.bottomBar[task.id]) {
|
|
this.bottomBar[task.id] = {};
|
|
this.bottomBar[task.id].data = [];
|
|
const bottomBar = this.getTaskOptions(task).bottomBar;
|
|
if (typeof bottomBar === "boolean") {
|
|
this.bottomBar[task.id].items = 1;
|
|
} else {
|
|
this.bottomBar[task.id].items = bottomBar;
|
|
}
|
|
}
|
|
if (!((_b = (_a2 = this.bottomBar[task.id]) == null ? void 0 : _a2.data) == null ? void 0 : _b.some((element) => data.includes(element))) && !task.isSkipped()) {
|
|
this.bottomBar[task.id].data = [...this.bottomBar[task.id].data, ...data];
|
|
}
|
|
} else if (task.isPending() || task.isRetrying() || task.isRollingBack() || this.hasPersistentOutput(task)) {
|
|
output = [...output, this.dumpData(task, level)];
|
|
}
|
|
}
|
|
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()))) {
|
|
const subtaskLevel = !task.hasTitle() ? level : level + 1;
|
|
const subtaskRender = this.multiLineRenderer(task.subtasks, subtaskLevel);
|
|
if ((subtaskRender == null ? void 0 : subtaskRender.trim()) !== "") {
|
|
output = [...output, subtaskRender];
|
|
}
|
|
}
|
|
if (task.isCompleted() || task.hasFailed() || task.isSkipped() || task.hasRolledBack()) {
|
|
this.promptBar = null;
|
|
if (!this.hasPersistentOutput(task)) {
|
|
delete this.bottomBar[task.id];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
output = output.filter(Boolean);
|
|
if (output.length > 0) {
|
|
return output.join(import_os.EOL);
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
renderBottomBar() {
|
|
if (Object.keys(this.bottomBar).length > 0) {
|
|
this.bottomBar = Object.keys(this.bottomBar).reduce((o, key) => {
|
|
if (!(o == null ? void 0 : o[key])) {
|
|
o[key] = {};
|
|
}
|
|
o[key] = this.bottomBar[key];
|
|
this.bottomBar[key].data = this.bottomBar[key].data.slice(-this.bottomBar[key].items);
|
|
o[key].data = this.bottomBar[key].data;
|
|
return o;
|
|
}, {});
|
|
return Object.values(this.bottomBar).reduce((o, value) => o = [...o, ...value.data], []).filter(Boolean).join(import_os.EOL);
|
|
}
|
|
}
|
|
renderPrompt() {
|
|
if (this.promptBar) {
|
|
return this.promptBar;
|
|
}
|
|
}
|
|
dumpData(task, level, source = "output") {
|
|
let data;
|
|
switch (source) {
|
|
case "output":
|
|
data = task.output;
|
|
break;
|
|
case "skip":
|
|
data = task.message.skip;
|
|
break;
|
|
case "error":
|
|
data = task.message.error;
|
|
break;
|
|
}
|
|
if (task.hasTitle() && source === "error" && data === task.title) {
|
|
return;
|
|
}
|
|
if (typeof data === "string") {
|
|
return this.formatString(data, this.getSymbol(task, true), level + 1);
|
|
}
|
|
}
|
|
formatString(str, icon, level) {
|
|
if (str.trim() === "") {
|
|
return;
|
|
}
|
|
str = `${icon} ${str}`;
|
|
let parsedStr;
|
|
let columns = process.stdout.columns ? process.stdout.columns : 80;
|
|
columns = columns - level * this.options.indentation - 2;
|
|
switch (this.options.formatOutput) {
|
|
case "truncate":
|
|
parsedStr = str.split(import_os.EOL).map((s, i) => {
|
|
return (0, import_cli_truncate.default)(this.indentMultilineOutput(s, i), columns);
|
|
});
|
|
break;
|
|
case "wrap":
|
|
parsedStr = (0, import_wrap_ansi.default)(str, columns, { hard: true }).split(import_os.EOL).map((s, i) => this.indentMultilineOutput(s, i));
|
|
break;
|
|
default:
|
|
throw new Error("Format option for the renderer is wrong.");
|
|
}
|
|
if (this.options.removeEmptyLines) {
|
|
parsedStr = parsedStr.filter(Boolean);
|
|
}
|
|
return indentString(parsedStr.join(import_os.EOL), level * this.options.indentation);
|
|
}
|
|
indentMultilineOutput(str, i) {
|
|
return i > 0 ? indentString(str.trim(), 2) : str.trim();
|
|
}
|
|
getSymbol(task, data = false) {
|
|
var _a2, _b, _c;
|
|
if (task.isPending() && !data) {
|
|
return ((_a2 = this.options) == null ? void 0 : _a2.lazy) || this.getSelfOrParentOption(task, "showSubtasks") !== false && task.hasSubtasks() && !task.subtasks.every((subtask) => !subtask.hasTitle()) ? colorette_default.yellow(figures.pointer) : colorette_default.yellowBright(this.spinner[this.spinnerPosition]);
|
|
} else if (task.isCompleted() && !data) {
|
|
return task.hasSubtasks() && task.subtasks.some((subtask) => subtask.hasFailed()) ? colorette_default.yellow(figures.warning) : colorette_default.green(figures.tick);
|
|
} else if (task.isRetrying() && !data) {
|
|
return ((_b = this.options) == null ? void 0 : _b.lazy) ? colorette_default.yellow(figures.warning) : colorette_default.yellow(this.spinner[this.spinnerPosition]);
|
|
} else if (task.isRollingBack() && !data) {
|
|
return ((_c = this.options) == null ? void 0 : _c.lazy) ? colorette_default.red(figures.warning) : colorette_default.red(this.spinner[this.spinnerPosition]);
|
|
} else if (task.hasRolledBack() && !data) {
|
|
return colorette_default.red(figures.arrowLeft);
|
|
} else if (task.hasFailed() && !data) {
|
|
return task.hasSubtasks() ? colorette_default.red(figures.pointer) : colorette_default.red(figures.cross);
|
|
} else if (task.isSkipped() && !data && this.getSelfOrParentOption(task, "collapseSkips") === false) {
|
|
return colorette_default.yellow(figures.warning);
|
|
} else if (task.isSkipped() && (data || this.getSelfOrParentOption(task, "collapseSkips"))) {
|
|
return colorette_default.yellow(figures.arrowDown);
|
|
}
|
|
return !data ? colorette_default.dim(figures.squareSmallFilled) : figures.pointerSmall;
|
|
}
|
|
addSuffixToMessage(message, suffix, condition) {
|
|
return condition ?? true ? message + colorette_default.dim(` [${suffix}]`) : message;
|
|
}
|
|
};
|
|
var DefaultRenderer = _DefaultRenderer;
|
|
DefaultRenderer.nonTTY = false;
|
|
DefaultRenderer.rendererOptions = {
|
|
indentation: 2,
|
|
clearOutput: false,
|
|
showSubtasks: true,
|
|
collapse: true,
|
|
collapseSkips: true,
|
|
showSkipMessage: true,
|
|
suffixSkips: true,
|
|
collapseErrors: true,
|
|
showErrorMessage: true,
|
|
suffixRetries: true,
|
|
lazy: false,
|
|
showTimer: false,
|
|
removeEmptyLines: true,
|
|
formatOutput: "truncate"
|
|
};
|
|
|
|
// src/renderer/silent.renderer.ts
|
|
var SilentRenderer = class {
|
|
constructor(tasks, options) {
|
|
this.tasks = tasks;
|
|
this.options = options;
|
|
}
|
|
render() {
|
|
}
|
|
end() {
|
|
}
|
|
};
|
|
SilentRenderer.nonTTY = true;
|
|
|
|
// src/renderer/simple.renderer.ts
|
|
var import_log_update2 = require("log-update");
|
|
var import_os2 = require("os");
|
|
var _SimpleRenderer = class {
|
|
constructor(tasks, options) {
|
|
this.tasks = tasks;
|
|
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$/)) {
|
|
(0, import_log_update2.stderr)(`${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 };
|
|
}
|
|
static now() {
|
|
return new Date();
|
|
}
|
|
static formatTitle(task) {
|
|
return (task == null ? void 0 : task.title) ? ` ${task.title}` : "";
|
|
}
|
|
log(output) {
|
|
const logOut = (msg) => {
|
|
process[this.options.output].write(msg.endsWith(import_os2.EOL) ? msg : `${msg}${import_os2.EOL}`);
|
|
};
|
|
if (!this.options.prefixWithTimestamp) {
|
|
logOut(`${output}`);
|
|
return;
|
|
}
|
|
const now = _SimpleRenderer.now();
|
|
const timestamp = String(now.getHours()).padStart(2, "0") + ":" + String(now.getMinutes()).padStart(2, "0") + ":" + String(now.getSeconds()).padStart(2, "0");
|
|
logOut(`${colorette_default.dim(`[${timestamp}]`)} ${output}`);
|
|
}
|
|
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);
|
|
});
|
|
} else {
|
|
this.render(this.tasks);
|
|
}
|
|
}
|
|
};
|
|
var SimpleRenderer = _SimpleRenderer;
|
|
SimpleRenderer.nonTTY = true;
|
|
SimpleRenderer.rendererOptions = { prefixWithTimestamp: false, output: "stdout" };
|
|
|
|
// src/utils/logger.constants.ts
|
|
var LogLevels = /* @__PURE__ */ ((LogLevels2) => {
|
|
LogLevels2["SILENT"] = "SILENT";
|
|
LogLevels2["FAILED"] = "FAILED";
|
|
LogLevels2["SKIPPED"] = "SKIPPED";
|
|
LogLevels2["SUCCESS"] = "SUCCESS";
|
|
LogLevels2["DATA"] = "DATA";
|
|
LogLevels2["STARTED"] = "STARTED";
|
|
LogLevels2["TITLE"] = "TITLE";
|
|
LogLevels2["RETRY"] = "RETRY";
|
|
LogLevels2["ROLLBACK"] = "ROLLBACK";
|
|
return LogLevels2;
|
|
})(LogLevels || {});
|
|
|
|
// src/utils/logger.ts
|
|
var Logger = class {
|
|
constructor(options) {
|
|
this.options = options;
|
|
}
|
|
fail(message) {
|
|
message = this.parseMessage("FAILED" /* FAILED */, message);
|
|
console.error(message);
|
|
}
|
|
skip(message) {
|
|
message = this.parseMessage("SKIPPED" /* SKIPPED */, message);
|
|
console.info(message);
|
|
}
|
|
success(message) {
|
|
message = this.parseMessage("SUCCESS" /* SUCCESS */, message);
|
|
console.log(message);
|
|
}
|
|
data(message) {
|
|
message = this.parseMessage("DATA" /* DATA */, message);
|
|
console.info(message);
|
|
}
|
|
start(message) {
|
|
message = this.parseMessage("STARTED" /* STARTED */, message);
|
|
console.log(message);
|
|
}
|
|
title(message) {
|
|
message = this.parseMessage("TITLE" /* TITLE */, message);
|
|
console.info(message);
|
|
}
|
|
retry(message) {
|
|
message = this.parseMessage("RETRY" /* RETRY */, message);
|
|
console.warn(message);
|
|
}
|
|
rollback(message) {
|
|
message = this.parseMessage("ROLLBACK" /* ROLLBACK */, message);
|
|
console.warn(message);
|
|
}
|
|
parseMessage(level, message) {
|
|
let multiLineMessage;
|
|
try {
|
|
multiLineMessage = message.split("\n");
|
|
} catch {
|
|
multiLineMessage = [message];
|
|
}
|
|
multiLineMessage = multiLineMessage.map((msg) => {
|
|
return this.logColoring({
|
|
level,
|
|
message: msg
|
|
});
|
|
});
|
|
message = multiLineMessage.join("\n");
|
|
return message;
|
|
}
|
|
logColoring({ level, message }) {
|
|
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
let icon;
|
|
let coloring = (input) => {
|
|
return input;
|
|
};
|
|
switch (level) {
|
|
case "FAILED" /* FAILED */:
|
|
if ((_a2 = this.options) == null ? void 0 : _a2.useIcons) {
|
|
coloring = colorette_default.red;
|
|
icon = figures.cross;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "SKIPPED" /* SKIPPED */:
|
|
if ((_b = this.options) == null ? void 0 : _b.useIcons) {
|
|
coloring = colorette_default.yellow;
|
|
icon = figures.arrowDown;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "SUCCESS" /* SUCCESS */:
|
|
if ((_c = this.options) == null ? void 0 : _c.useIcons) {
|
|
coloring = colorette_default.green;
|
|
icon = figures.tick;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "DATA" /* DATA */:
|
|
if ((_d = this.options) == null ? void 0 : _d.useIcons) {
|
|
icon = figures.arrowRight;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "STARTED" /* STARTED */:
|
|
if ((_e = this.options) == null ? void 0 : _e.useIcons) {
|
|
icon = figures.pointer;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "TITLE" /* TITLE */:
|
|
if ((_f = this.options) == null ? void 0 : _f.useIcons) {
|
|
icon = figures.checkboxOn;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "RETRY" /* RETRY */:
|
|
if ((_g = this.options) == null ? void 0 : _g.useIcons) {
|
|
coloring = colorette_default.yellow;
|
|
icon = figures.pointer;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
case "ROLLBACK" /* ROLLBACK */:
|
|
if ((_h = this.options) == null ? void 0 : _h.useIcons) {
|
|
coloring = colorette_default.red;
|
|
icon = figures.arrowLeft;
|
|
} else {
|
|
icon = this.wrapInBrackets(level);
|
|
}
|
|
break;
|
|
}
|
|
return coloring(`${icon} ${message}`);
|
|
}
|
|
wrapInBrackets(level) {
|
|
return `[${level}]`;
|
|
}
|
|
};
|
|
|
|
// src/renderer/verbose.renderer.ts
|
|
var _VerboseRenderer = class {
|
|
constructor(tasks, options) {
|
|
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();
|
|
} else {
|
|
this.logger = new Logger({ useIcons: (_d = this.options) == null ? void 0 : _d.useIcons });
|
|
}
|
|
this.options = { ..._VerboseRenderer.rendererOptions, ...this.options };
|
|
}
|
|
render() {
|
|
this.verboseRenderer(this.tasks);
|
|
}
|
|
end() {
|
|
}
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
},
|
|
(err) => {
|
|
this.logger.fail(err);
|
|
}
|
|
);
|
|
});
|
|
}
|
|
};
|
|
var VerboseRenderer = _VerboseRenderer;
|
|
VerboseRenderer.nonTTY = true;
|
|
VerboseRenderer.rendererOptions = {
|
|
useIcons: false,
|
|
logEmptyTitle: true,
|
|
logTitleChange: true
|
|
};
|
|
|
|
// src/utils/renderer.ts
|
|
var renderers = {
|
|
default: DefaultRenderer,
|
|
simple: SimpleRenderer,
|
|
verbose: VerboseRenderer,
|
|
silent: SilentRenderer
|
|
};
|
|
function isRendererSupported(renderer) {
|
|
return process.stdout.isTTY === true || renderer.nonTTY === true;
|
|
}
|
|
function getRendererClass(renderer) {
|
|
if (typeof renderer === "string") {
|
|
return renderers[renderer] || renderers.default;
|
|
}
|
|
return typeof renderer === "function" ? renderer : renderers.default;
|
|
}
|
|
function getRenderer(renderer, fallbackRenderer, fallbackCondition, silentCondition) {
|
|
let returnValue;
|
|
let ret = getRendererClass(renderer);
|
|
returnValue = { renderer: ret, nonTTY: false };
|
|
const evaluateSilent = assertFunctionOrSelf(silentCondition);
|
|
const evaluateFallback = assertFunctionOrSelf(fallbackCondition);
|
|
if (evaluateSilent) {
|
|
ret = getRendererClass("silent");
|
|
returnValue = { renderer: ret, nonTTY: true };
|
|
} else if (!isRendererSupported(ret) || evaluateFallback) {
|
|
ret = getRendererClass(fallbackRenderer);
|
|
returnValue = { renderer: ret, nonTTY: true };
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
// src/utils/uuid.ts
|
|
function generateUUID() {
|
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
const r = Math.random() * 16 || 0;
|
|
const v = c === "x" ? r : r && 3 || 8;
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
|
|
// src/lib/task.ts
|
|
var Task = class extends import_rxjs.Subject {
|
|
constructor(listr, tasks, options, rendererOptions) {
|
|
var _a2, _b, _c, _d;
|
|
super();
|
|
this.listr = listr;
|
|
this.tasks = tasks;
|
|
this.options = options;
|
|
this.rendererOptions = rendererOptions;
|
|
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
|
|
});
|
|
if (this.hasSubtasks() && this.hasFailed()) {
|
|
for (const subtask of this.subtasks) {
|
|
if (subtask.state === "PENDING" /* PENDING */) {
|
|
subtask.state$ = "FAILED" /* FAILED */;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
set output$(data) {
|
|
this.output = data;
|
|
this.next({
|
|
type: "DATA" /* DATA */,
|
|
data
|
|
});
|
|
}
|
|
set message$(data) {
|
|
this.message = { ...this.message, ...data };
|
|
this.next({
|
|
type: "MESSAGE" /* MESSAGE */,
|
|
data
|
|
});
|
|
}
|
|
set title$(title) {
|
|
this.title = title;
|
|
this.next({
|
|
type: "TITLE" /* TITLE */,
|
|
data: title
|
|
});
|
|
}
|
|
async check(ctx) {
|
|
if (this.state === void 0) {
|
|
this.enabled = await assertFunctionOrSelf(this.enabledFn, ctx);
|
|
this.next({
|
|
type: "ENABLED" /* ENABLED */,
|
|
data: this.enabled
|
|
});
|
|
}
|
|
}
|
|
hasSubtasks() {
|
|
var _a2;
|
|
return ((_a2 = this.subtasks) == null ? void 0 : _a2.length) > 0;
|
|
}
|
|
isPending() {
|
|
return this.state === "PENDING" /* PENDING */;
|
|
}
|
|
isSkipped() {
|
|
return this.state === "SKIPPED" /* SKIPPED */;
|
|
}
|
|
isCompleted() {
|
|
return this.state === "COMPLETED" /* COMPLETED */;
|
|
}
|
|
hasFailed() {
|
|
return this.state === "FAILED" /* FAILED */;
|
|
}
|
|
isRollingBack() {
|
|
return this.state === "ROLLING_BACK" /* ROLLING_BACK */;
|
|
}
|
|
hasRolledBack() {
|
|
return this.state === "ROLLED_BACK" /* ROLLED_BACK */;
|
|
}
|
|
isRetrying() {
|
|
return this.state === "RETRY" /* RETRY */;
|
|
}
|
|
isEnabled() {
|
|
return this.enabled;
|
|
}
|
|
hasTitle() {
|
|
return typeof (this == null ? void 0 : this.title) === "string";
|
|
}
|
|
isPrompt() {
|
|
return !!this.prompt;
|
|
}
|
|
async run(context, wrapper) {
|
|
var _a2, _b, _c, _d, _e;
|
|
const handleResult = (result) => {
|
|
if (result instanceof Listr) {
|
|
result.options = { ...this.options, ...result.options };
|
|
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 */ });
|
|
result = result.run(context);
|
|
} else if (this.isPrompt()) {
|
|
} else if (result instanceof Promise) {
|
|
result = result.then(handleResult);
|
|
} else if (result instanceof import_stream.Readable) {
|
|
result = new Promise((resolve, reject) => {
|
|
result.on("data", (data) => {
|
|
this.output$ = data.toString();
|
|
});
|
|
result.on("error", (error) => reject(error));
|
|
result.on("end", () => resolve(null));
|
|
});
|
|
} else if ((0, import_rxjs.isObservable)(result)) {
|
|
result = new Promise((resolve, reject) => {
|
|
result.subscribe({
|
|
next: (data) => {
|
|
this.output$ = data;
|
|
},
|
|
error: reject,
|
|
complete: resolve
|
|
});
|
|
});
|
|
}
|
|
return result;
|
|
};
|
|
const startTime = Date.now();
|
|
this.state$ = "PENDING" /* PENDING */;
|
|
const skipped = await assertFunctionOrSelf(this.skip, context);
|
|
if (skipped) {
|
|
if (typeof skipped === "string") {
|
|
this.message$ = { skip: skipped };
|
|
} else if (this.hasTitle()) {
|
|
this.message$ = { skip: this.title };
|
|
} else {
|
|
this.message$ = { skip: "Skipped task without a title." };
|
|
}
|
|
this.state$ = "SKIPPED" /* SKIPPED */;
|
|
return;
|
|
}
|
|
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;
|
|
for (let retries = 1; retries <= retryCount; retries++) {
|
|
try {
|
|
await handleResult(this.task(context, wrapper));
|
|
break;
|
|
} catch (err) {
|
|
if (retries !== retryCount) {
|
|
this.retry = { count: retries, withError: err };
|
|
this.message$ = { retry: this.retry };
|
|
this.title$ = this.initialTitle;
|
|
this.output = void 0;
|
|
wrapper.report(err, "WILL_RETRY" /* WILL_RETRY */);
|
|
this.state$ = "RETRY" /* RETRY */;
|
|
} else {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
if (this.isPending() || this.isRetrying()) {
|
|
this.message$ = { duration: Date.now() - startTime };
|
|
this.state$ = "COMPLETED" /* COMPLETED */;
|
|
}
|
|
} catch (error) {
|
|
if (this.prompt instanceof PromptError) {
|
|
error = new Error(this.prompt.message);
|
|
}
|
|
if ((_c = this.tasks) == null ? void 0 : _c.rollback) {
|
|
wrapper.report(error, "WILL_ROLLBACK" /* WILL_ROLLBACK */);
|
|
try {
|
|
this.state$ = "ROLLING_BACK" /* ROLLING_BACK */;
|
|
await this.tasks.rollback(context, wrapper);
|
|
this.state$ = "ROLLED_BACK" /* ROLLED_BACK */;
|
|
this.message$ = { rollback: this.title };
|
|
} catch (err) {
|
|
this.state$ = "FAILED" /* FAILED */;
|
|
wrapper.report(err, "HAS_FAILED_TO_ROLLBACK" /* HAS_FAILED_TO_ROLLBACK */);
|
|
throw err;
|
|
}
|
|
if (((_d = this.listr.options) == null ? void 0 : _d.exitAfterRollback) !== false) {
|
|
throw new Error(this.title);
|
|
}
|
|
} else {
|
|
this.state$ = "FAILED" /* FAILED */;
|
|
if (this.listr.options.exitOnError !== false && await assertFunctionOrSelf((_e = this.tasks) == null ? void 0 : _e.exitOnError, context) !== false) {
|
|
wrapper.report(error, "HAS_FAILED" /* HAS_FAILED */);
|
|
throw error;
|
|
} else if (!this.hasSubtasks()) {
|
|
wrapper.report(error, "HAS_FAILED_WITHOUT_ERROR" /* HAS_FAILED_WITHOUT_ERROR */);
|
|
}
|
|
}
|
|
} finally {
|
|
this.complete();
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/lib/task-wrapper.ts
|
|
var import_through = __toESM(require("through"), 1);
|
|
|
|
// src/constants/clearline-regex.constants.ts
|
|
var CLEAR_LINE_REGEX = "(?:\\u001b|\\u009b)\\[[\\=><~/#&.:=?%@~_-]*[0-9]*[\\a-ln-tqyz=><~/#&.:=?%@~_-]+";
|
|
var BELL_REGEX = /\u0007/;
|
|
|
|
// src/utils/prompt.ts
|
|
function defaultCancelCallback(settings) {
|
|
const errorMsg = "Cancelled prompt.";
|
|
if (this instanceof TaskWrapper) {
|
|
this.task.prompt = new PromptError(errorMsg);
|
|
} else if ((settings == null ? void 0 : settings.error) !== false) {
|
|
throw new Error(errorMsg);
|
|
} else {
|
|
return errorMsg;
|
|
}
|
|
}
|
|
async function createPrompt(options, settings) {
|
|
let cancelCallback;
|
|
if (settings == null ? void 0 : settings.cancelCallback) {
|
|
cancelCallback = settings.cancelCallback;
|
|
} else {
|
|
cancelCallback = defaultCancelCallback;
|
|
}
|
|
if (!Array.isArray(options)) {
|
|
options = [{ ...options, name: "default" }];
|
|
} else if (options.length === 1) {
|
|
options = options.reduce((o, option) => {
|
|
return [...o, Object.assign(option, { name: "default" })];
|
|
}, []);
|
|
}
|
|
options = options.reduce((o, option) => {
|
|
return [
|
|
...o,
|
|
Object.assign(option, {
|
|
stdout: this instanceof TaskWrapper ? (settings == null ? void 0 : settings.stdout) ?? this.stdout() : process.stdout,
|
|
onCancel: cancelCallback.bind(this, settings)
|
|
})
|
|
];
|
|
}, []);
|
|
let enquirer;
|
|
if (settings == null ? void 0 : settings.enquirer) {
|
|
enquirer = settings.enquirer;
|
|
} else {
|
|
try {
|
|
const imported = await import("enquirer");
|
|
enquirer = imported.default ? new imported.default() : new imported();
|
|
} catch (e) {
|
|
this.task.prompt = new PromptError("Enquirer is a peer dependency that must be installed separately.");
|
|
throw new Error(e);
|
|
}
|
|
}
|
|
if (this instanceof TaskWrapper) {
|
|
enquirer.on("prompt", (prompt) => this.task.prompt = prompt);
|
|
enquirer.on("submit", () => this.task.prompt = void 0);
|
|
this.task.subscribe((event) => {
|
|
if (event.type === "STATE" /* STATE */ && event.data === "SKIPPED" /* SKIPPED */) {
|
|
if (this.task.prompt && !(this.task.prompt instanceof PromptError)) {
|
|
this.task.prompt.submit();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
const response = await enquirer.prompt(options);
|
|
if (options.length === 1) {
|
|
return response.default;
|
|
} else {
|
|
return response;
|
|
}
|
|
}
|
|
function destroyPrompt(throwError = false) {
|
|
if (!this.task.prompt || this.task.prompt instanceof PromptError) {
|
|
return;
|
|
}
|
|
if (throwError) {
|
|
this.task.prompt.cancel();
|
|
} else {
|
|
this.task.prompt.submit();
|
|
}
|
|
}
|
|
|
|
// src/lib/task-wrapper.ts
|
|
var TaskWrapper = class {
|
|
constructor(task, errors, options) {
|
|
this.task = task;
|
|
this.errors = errors;
|
|
this.options = options;
|
|
}
|
|
get title() {
|
|
return this.task.title;
|
|
}
|
|
set title(data) {
|
|
this.task.title$ = data;
|
|
}
|
|
get output() {
|
|
return this.task.output;
|
|
}
|
|
set output(data) {
|
|
this.task.output$ = data;
|
|
}
|
|
newListr(task, options) {
|
|
let tasks;
|
|
if (typeof task === "function") {
|
|
tasks = task(this);
|
|
} else {
|
|
tasks = task;
|
|
}
|
|
return new Listr(tasks, options, this.task);
|
|
}
|
|
report(error, type) {
|
|
var _a2;
|
|
if (this.task.options.collectErrors !== false) {
|
|
this.errors.push(new ListrError(error, type, this.task));
|
|
}
|
|
this.task.message$ = { error: error.message ?? ((_a2 = this.task) == null ? void 0 : _a2.title) ?? "Task with no title." };
|
|
}
|
|
skip(message) {
|
|
var _a2;
|
|
this.task.state$ = "SKIPPED" /* SKIPPED */;
|
|
if (message) {
|
|
this.task.message$ = { skip: message ?? ((_a2 = this.task) == null ? void 0 : _a2.title) ?? "Task with no title." };
|
|
}
|
|
}
|
|
isRetrying() {
|
|
return this.task.isRetrying() ? this.task.retry : { count: 0 };
|
|
}
|
|
async prompt(options) {
|
|
var _a2;
|
|
return createPrompt.bind(this)(options, { ...(_a2 = this.options) == null ? void 0 : _a2.injectWrapper });
|
|
}
|
|
cancelPrompt(throwError = false) {
|
|
return destroyPrompt.bind(this)(throwError);
|
|
}
|
|
stdout() {
|
|
return (0, import_through.default)((chunk) => {
|
|
chunk = chunk.toString();
|
|
chunk = chunk.replace(new RegExp(CLEAR_LINE_REGEX, "gmi"), "");
|
|
chunk = chunk.replace(new RegExp(BELL_REGEX, "gmi"), "");
|
|
if (chunk !== "") {
|
|
this.output = chunk;
|
|
}
|
|
});
|
|
}
|
|
run(ctx) {
|
|
return this.task.run(ctx, this);
|
|
}
|
|
};
|
|
|
|
// src/listr.ts
|
|
var Listr = class {
|
|
constructor(task, options, parentTask) {
|
|
this.task = task;
|
|
this.options = options;
|
|
this.parentTask = parentTask;
|
|
this.tasks = [];
|
|
this.err = [];
|
|
this.renderHook$ = new import_rxjs2.Subject();
|
|
this.path = [];
|
|
var _a2, _b, _c;
|
|
this.options = {
|
|
...{
|
|
concurrent: false,
|
|
renderer: "default",
|
|
nonTTYRenderer: "verbose",
|
|
exitOnError: true,
|
|
exitAfterRollback: true,
|
|
collectErrors: "minimal",
|
|
registerSignalListeners: true
|
|
},
|
|
...options
|
|
};
|
|
if (this.options.concurrent === true) {
|
|
this.concurrency = Infinity;
|
|
} else if (typeof this.options.concurrent === "number") {
|
|
this.concurrency = this.options.concurrent;
|
|
} else {
|
|
this.concurrency = 1;
|
|
}
|
|
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);
|
|
this.rendererClass = renderer.renderer;
|
|
if (!renderer.nonTTY) {
|
|
this.rendererClassOptions = this.options.rendererOptions;
|
|
} else {
|
|
this.rendererClassOptions = this.options.nonTTYRendererOptions;
|
|
}
|
|
this.add(task ?? []);
|
|
if (parentTask) {
|
|
this.path = [...parentTask.listr.path, parentTask.title];
|
|
}
|
|
if (this.options.registerSignalListeners) {
|
|
process.once("SIGINT", () => {
|
|
this.tasks.forEach(async (task2) => {
|
|
if (task2.isPending()) {
|
|
task2.state$ = "FAILED" /* FAILED */;
|
|
}
|
|
});
|
|
this.renderer.end(new Error("Interrupted."));
|
|
process.exit(127);
|
|
}).setMaxListeners(0);
|
|
}
|
|
if ((_c = this.options) == null ? void 0 : _c.disableColor) {
|
|
process.env.LISTR_DISABLE_COLOR = "1";
|
|
}
|
|
}
|
|
add(task) {
|
|
const tasks = Array.isArray(task) ? task : [task];
|
|
tasks.forEach((task2) => {
|
|
this.tasks.push(new Task(this, task2, this.options, { ...this.rendererClassOptions, ...task2.options }));
|
|
});
|
|
}
|
|
async run(context) {
|
|
var _a2;
|
|
if (!this.renderer) {
|
|
this.renderer = new this.rendererClass(this.tasks, this.rendererClassOptions, this.renderHook$);
|
|
}
|
|
this.renderer.render();
|
|
this.ctx = ((_a2 = this.options) == null ? void 0 : _a2.ctx) ?? context ?? {};
|
|
await this.checkAll(this.ctx);
|
|
try {
|
|
await (0, import_p_map.default)(
|
|
this.tasks,
|
|
async (task) => {
|
|
await task.check(this.ctx);
|
|
return this.runTask(task, this.ctx, this.err);
|
|
},
|
|
{ concurrency: this.concurrency }
|
|
);
|
|
this.renderer.end();
|
|
} catch (err) {
|
|
if (this.options.exitOnError !== false) {
|
|
this.renderer.end(err);
|
|
throw err;
|
|
}
|
|
}
|
|
return this.ctx;
|
|
}
|
|
checkAll(context) {
|
|
return Promise.all(this.tasks.map((task) => task.check(context)));
|
|
}
|
|
runTask(task, context, errors) {
|
|
if (!task.isEnabled()) {
|
|
return Promise.resolve();
|
|
}
|
|
return new TaskWrapper(task, errors, this.options).run(context);
|
|
}
|
|
};
|
|
|
|
// src/manager.ts
|
|
var Manager = class {
|
|
constructor(options) {
|
|
this.options = options;
|
|
this.err = [];
|
|
this.tasks = [];
|
|
}
|
|
set ctx(ctx) {
|
|
this.options.ctx = ctx;
|
|
}
|
|
add(tasks, options) {
|
|
options = { ...this.options, ...options };
|
|
this.tasks = [...this.tasks, this.indent(tasks, options)];
|
|
}
|
|
async runAll(options) {
|
|
options = { ...this.options, ...options };
|
|
const ctx = await this.run(this.tasks, options);
|
|
this.tasks = [];
|
|
return ctx;
|
|
}
|
|
newListr(tasks, options) {
|
|
return new Listr(tasks, options);
|
|
}
|
|
indent(tasks, options, taskOptions) {
|
|
options = { ...this.options, ...options };
|
|
let newTask;
|
|
if (typeof tasks === "function") {
|
|
newTask = {
|
|
...taskOptions,
|
|
task: (ctx) => this.newListr(tasks(ctx), options)
|
|
};
|
|
} else {
|
|
newTask = {
|
|
...taskOptions,
|
|
task: () => this.newListr(tasks, options)
|
|
};
|
|
}
|
|
return newTask;
|
|
}
|
|
async run(tasks, options) {
|
|
options = { ...this.options, ...options };
|
|
const task = this.newListr(tasks, options);
|
|
const ctx = await task.run();
|
|
this.err = task.err;
|
|
return ctx;
|
|
}
|
|
getRuntime(pipetime) {
|
|
return `${Math.round(Date.now() - pipetime) / 1e3}s`;
|
|
}
|
|
};
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
Listr,
|
|
ListrError,
|
|
ListrErrorTypes,
|
|
ListrEventType,
|
|
ListrTaskState,
|
|
LogLevels,
|
|
Logger,
|
|
Manager,
|
|
PromptError,
|
|
createPrompt,
|
|
destroyPrompt,
|
|
figures
|
|
});
|