index.js 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244
  1. var __defProp = Object.defineProperty;
  2. var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  3. // src/constants/ansi-escape-codes.constants.ts
  4. var ANSI_ESCAPE = "\x1B[";
  5. var ANSI_ESCAPE_CODES = {
  6. CURSOR_HIDE: ANSI_ESCAPE + "?25l",
  7. CURSOR_SHOW: ANSI_ESCAPE + "?25h"
  8. };
  9. // src/constants/environment-variables.constants.ts
  10. var ListrEnvironmentVariables = /* @__PURE__ */ ((ListrEnvironmentVariables2) => {
  11. ListrEnvironmentVariables2["DISABLE_COLOR"] = "LISTR_DISABLE_COLOR";
  12. ListrEnvironmentVariables2["FORCE_UNICODE"] = "LISTR_FORCE_UNICODE";
  13. ListrEnvironmentVariables2["FORCE_COLOR"] = "FORCE_COLOR";
  14. return ListrEnvironmentVariables2;
  15. })(ListrEnvironmentVariables || {});
  16. // src/constants/listr-error.constants.ts
  17. var ListrErrorTypes = /* @__PURE__ */ ((ListrErrorTypes2) => {
  18. ListrErrorTypes2["WILL_RETRY"] = "WILL_RETRY";
  19. ListrErrorTypes2["WILL_ROLLBACK"] = "WILL_ROLLBACK";
  20. ListrErrorTypes2["HAS_FAILED_TO_ROLLBACK"] = "HAS_FAILED_TO_ROLLBACK";
  21. ListrErrorTypes2["HAS_FAILED"] = "HAS_FAILED";
  22. ListrErrorTypes2["HAS_FAILED_WITHOUT_ERROR"] = "HAS_FAILED_WITHOUT_ERROR";
  23. return ListrErrorTypes2;
  24. })(ListrErrorTypes || {});
  25. // src/constants/listr-events.constants.ts
  26. var ListrEventType = /* @__PURE__ */ ((ListrEventType2) => {
  27. ListrEventType2["SHOULD_REFRESH_RENDER"] = "SHOUD_REFRESH_RENDER";
  28. return ListrEventType2;
  29. })(ListrEventType || {});
  30. // src/constants/listr-task-events.constants.ts
  31. var ListrTaskEventType = /* @__PURE__ */ ((ListrTaskEventType2) => {
  32. ListrTaskEventType2["TITLE"] = "TITLE";
  33. ListrTaskEventType2["STATE"] = "STATE";
  34. ListrTaskEventType2["ENABLED"] = "ENABLED";
  35. ListrTaskEventType2["SUBTASK"] = "SUBTASK";
  36. ListrTaskEventType2["PROMPT"] = "PROMPT";
  37. ListrTaskEventType2["OUTPUT"] = "OUTPUT";
  38. ListrTaskEventType2["MESSAGE"] = "MESSAGE";
  39. ListrTaskEventType2["CLOSED"] = "CLOSED";
  40. return ListrTaskEventType2;
  41. })(ListrTaskEventType || {});
  42. // src/constants/listr-task-state.constants.ts
  43. var ListrTaskState = /* @__PURE__ */ ((ListrTaskState2) => {
  44. ListrTaskState2["WAITING"] = "WAITING";
  45. ListrTaskState2["STARTED"] = "STARTED";
  46. ListrTaskState2["COMPLETED"] = "COMPLETED";
  47. ListrTaskState2["FAILED"] = "FAILED";
  48. ListrTaskState2["SKIPPED"] = "SKIPPED";
  49. ListrTaskState2["ROLLING_BACK"] = "ROLLING_BACK";
  50. ListrTaskState2["ROLLED_BACK"] = "ROLLED_BACK";
  51. ListrTaskState2["RETRY"] = "RETRY";
  52. ListrTaskState2["PAUSED"] = "PAUSED";
  53. ListrTaskState2["PROMPT"] = "PROMPT";
  54. ListrTaskState2["PROMPT_COMPLETED"] = "PROMPT_COMPLETED";
  55. return ListrTaskState2;
  56. })(ListrTaskState || {});
  57. // src/lib/event-manager.ts
  58. import EventEmitter from "eventemitter3";
  59. var _EventManager = class _EventManager {
  60. constructor() {
  61. this.emitter = new EventEmitter();
  62. }
  63. emit(dispatch, args) {
  64. this.emitter.emit(dispatch, args);
  65. }
  66. on(dispatch, handler) {
  67. this.emitter.addListener(dispatch, handler);
  68. }
  69. once(dispatch, handler) {
  70. this.emitter.once(dispatch, handler);
  71. }
  72. off(dispatch, handler) {
  73. this.emitter.off(dispatch, handler);
  74. }
  75. complete() {
  76. this.emitter.removeAllListeners();
  77. }
  78. };
  79. __name(_EventManager, "EventManager");
  80. var EventManager = _EventManager;
  81. // src/interfaces/event.interface.ts
  82. var _BaseEventMap = class _BaseEventMap {
  83. };
  84. __name(_BaseEventMap, "BaseEventMap");
  85. var BaseEventMap = _BaseEventMap;
  86. // src/utils/environment/is-observable.ts
  87. function isObservable(obj) {
  88. return !!obj && typeof obj.lift === "function" && typeof obj.subscribe === "function";
  89. }
  90. __name(isObservable, "isObservable");
  91. // src/utils/environment/is-unicode-supported.ts
  92. function isUnicodeSupported() {
  93. return !!process.env["LISTR_FORCE_UNICODE" /* FORCE_UNICODE */] || process.platform !== "win32" || !!process.env.CI || !!process.env.WT_SESSION || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty";
  94. }
  95. __name(isUnicodeSupported, "isUnicodeSupported");
  96. // src/utils/format/cleanse-ansi.constants.ts
  97. var CLEAR_LINE_REGEX = "(?:\\u001b|\\u009b)\\[[\\=><~/#&.:=?%@~_-]*[0-9]*[\\a-ln-tqyz=><~/#&.:=?%@~_-]+";
  98. var BELL_REGEX = /\u0007/;
  99. // src/utils/format/cleanse-ansi.ts
  100. function cleanseAnsi(chunk) {
  101. return String(chunk).replace(new RegExp(CLEAR_LINE_REGEX, "gmi"), "").replace(new RegExp(BELL_REGEX, "gmi"), "").trim();
  102. }
  103. __name(cleanseAnsi, "cleanseAnsi");
  104. // src/utils/format/color.ts
  105. import { createColors } from "colorette";
  106. var color = createColors({ useColor: !process.env["LISTR_DISABLE_COLOR" /* DISABLE_COLOR */] });
  107. // src/utils/format/indent.ts
  108. function indent(string, count) {
  109. return string.replace(/^(?!\s*$)/gm, " ".repeat(count));
  110. }
  111. __name(indent, "indent");
  112. // src/utils/format/figures.ts
  113. var FIGURES_MAIN = {
  114. warning: "\u26A0",
  115. cross: "\u2716",
  116. arrowDown: "\u2193",
  117. tick: "\u2714",
  118. arrowRight: "\u2192",
  119. pointer: "\u276F",
  120. checkboxOn: "\u2612",
  121. arrowLeft: "\u2190",
  122. squareSmallFilled: "\u25FC",
  123. pointerSmall: "\u203A"
  124. };
  125. var FIGURES_FALLBACK = {
  126. ...FIGURES_MAIN,
  127. warning: "\u203C",
  128. cross: "\xD7",
  129. tick: "\u221A",
  130. pointer: ">",
  131. checkboxOn: "[\xD7]",
  132. squareSmallFilled: "\u25A0"
  133. };
  134. var figures = isUnicodeSupported() ? FIGURES_MAIN : FIGURES_FALLBACK;
  135. // src/utils/format/splat.ts
  136. import { format } from "util";
  137. function splat(message, ...splat2) {
  138. return format(String(message), ...splat2);
  139. }
  140. __name(splat, "splat");
  141. // src/utils/logger/logger.constants.ts
  142. var ListrLogLevels = /* @__PURE__ */ ((ListrLogLevels2) => {
  143. ListrLogLevels2["STARTED"] = "STARTED";
  144. ListrLogLevels2["COMPLETED"] = "COMPLETED";
  145. ListrLogLevels2["FAILED"] = "FAILED";
  146. ListrLogLevels2["SKIPPED"] = "SKIPPED";
  147. ListrLogLevels2["OUTPUT"] = "OUTPUT";
  148. ListrLogLevels2["TITLE"] = "TITLE";
  149. ListrLogLevels2["ROLLBACK"] = "ROLLBACK";
  150. ListrLogLevels2["RETRY"] = "RETRY";
  151. ListrLogLevels2["PROMPT"] = "PROMPT";
  152. ListrLogLevels2["PAUSED"] = "PAUSED";
  153. return ListrLogLevels2;
  154. })(ListrLogLevels || {});
  155. var LISTR_LOGGER_STYLE = {
  156. icon: {
  157. ["STARTED" /* STARTED */]: figures.pointer,
  158. ["FAILED" /* FAILED */]: figures.cross,
  159. ["SKIPPED" /* SKIPPED */]: figures.arrowDown,
  160. ["COMPLETED" /* COMPLETED */]: figures.tick,
  161. ["OUTPUT" /* OUTPUT */]: figures.pointerSmall,
  162. ["TITLE" /* TITLE */]: figures.arrowRight,
  163. ["RETRY" /* RETRY */]: figures.warning,
  164. ["ROLLBACK" /* ROLLBACK */]: figures.arrowLeft,
  165. ["PAUSED" /* PAUSED */]: figures.squareSmallFilled
  166. },
  167. color: {
  168. ["STARTED" /* STARTED */]: color.yellow,
  169. ["FAILED" /* FAILED */]: color.red,
  170. ["SKIPPED" /* SKIPPED */]: color.yellow,
  171. ["COMPLETED" /* COMPLETED */]: color.green,
  172. ["RETRY" /* RETRY */]: color.yellowBright,
  173. ["ROLLBACK" /* ROLLBACK */]: color.redBright,
  174. ["PAUSED" /* PAUSED */]: color.yellowBright
  175. }
  176. };
  177. var LISTR_LOGGER_STDERR_LEVELS = ["RETRY" /* RETRY */, "ROLLBACK" /* ROLLBACK */, "FAILED" /* FAILED */];
  178. // src/utils/logger/logger.ts
  179. import { EOL } from "os";
  180. var _ListrLogger = class _ListrLogger {
  181. constructor(options) {
  182. this.options = options;
  183. this.options = {
  184. useIcons: true,
  185. toStderr: [],
  186. ...options ?? {}
  187. };
  188. this.options.fields ??= {};
  189. this.options.fields.prefix ??= [];
  190. this.options.fields.suffix ??= [];
  191. this.process = this.options.processOutput ?? new ProcessOutput();
  192. }
  193. log(level, message, options) {
  194. const output = this.format(level, message, options);
  195. if (this.options.toStderr.includes(level)) {
  196. this.process.toStderr(output);
  197. return;
  198. }
  199. this.process.toStdout(output);
  200. }
  201. toStdout(message, options, eol = true) {
  202. this.process.toStdout(this.format(null, message, options), eol);
  203. }
  204. toStderr(message, options, eol = true) {
  205. this.process.toStderr(this.format(null, message, options), eol);
  206. }
  207. wrap(message, options) {
  208. if (!message) {
  209. return message;
  210. }
  211. return this.applyFormat(`[${message}]`, options);
  212. }
  213. splat(...args) {
  214. const message = args.shift() ?? "";
  215. return args.length === 0 ? message : splat(message, args);
  216. }
  217. suffix(message, ...suffixes) {
  218. suffixes.filter(Boolean).forEach((suffix) => {
  219. message += this.spacing(message);
  220. if (typeof suffix === "string") {
  221. message += this.wrap(suffix);
  222. } else if (typeof suffix === "object") {
  223. suffix.args ??= [];
  224. if (typeof suffix.condition === "function" ? !suffix.condition(...suffix.args) : !(suffix.condition ?? true)) {
  225. return message;
  226. }
  227. message += this.wrap(typeof suffix.field === "function" ? suffix.field(...suffix.args) : suffix.field, {
  228. format: suffix?.format(...suffix.args)
  229. });
  230. }
  231. });
  232. return message;
  233. }
  234. prefix(message, ...prefixes) {
  235. prefixes.filter(Boolean).forEach((prefix) => {
  236. message = this.spacing(message) + message;
  237. if (typeof prefix === "string") {
  238. message = this.wrap(prefix) + message;
  239. } else if (typeof prefix === "object") {
  240. prefix.args ??= [];
  241. if (typeof prefix.condition === "function" ? !prefix.condition(...prefix.args) : !(prefix.condition ?? true)) {
  242. return message;
  243. }
  244. message = this.wrap(typeof prefix.field === "function" ? prefix.field(...prefix.args) : prefix.field, {
  245. format: prefix?.format()
  246. }) + message;
  247. }
  248. });
  249. return message;
  250. }
  251. fields(message, options) {
  252. if (this.options?.fields?.prefix) {
  253. message = this.prefix(message, ...this.options.fields.prefix);
  254. }
  255. if (options?.prefix) {
  256. message = this.prefix(message, ...options.prefix);
  257. }
  258. if (options?.suffix) {
  259. message = this.suffix(message, ...options.suffix);
  260. }
  261. if (this.options?.fields?.suffix) {
  262. message = this.suffix(message, ...this.options.fields.suffix);
  263. }
  264. return message;
  265. }
  266. icon(level, icon) {
  267. if (!level) {
  268. return null;
  269. }
  270. icon ||= this.options.icon?.[level];
  271. const coloring = this.options.color?.[level];
  272. if (icon && coloring) {
  273. icon = coloring(icon);
  274. }
  275. return icon;
  276. }
  277. format(level, message, options) {
  278. if (!Array.isArray(message)) {
  279. message = [message];
  280. }
  281. message = this.splat(message.shift(), ...message).toString().split(EOL).filter((m) => !m || m.trim() !== "").map((m) => {
  282. return this.style(
  283. level,
  284. this.fields(m, {
  285. prefix: Array.isArray(options?.prefix) ? options.prefix : [options?.prefix],
  286. suffix: Array.isArray(options?.suffix) ? options.suffix : [options?.suffix]
  287. })
  288. );
  289. }).join(EOL);
  290. return message;
  291. }
  292. style(level, message) {
  293. if (!level || !message) {
  294. return message;
  295. }
  296. const icon = this.icon(level, !this.options.useIcons && this.wrap(level));
  297. if (icon) {
  298. message = icon + " " + message;
  299. }
  300. return message;
  301. }
  302. applyFormat(message, options) {
  303. if (options?.format) {
  304. return options.format(message);
  305. }
  306. return message;
  307. }
  308. spacing(message) {
  309. return typeof message === "undefined" || message.trim() === "" ? "" : " ";
  310. }
  311. };
  312. __name(_ListrLogger, "ListrLogger");
  313. var ListrLogger = _ListrLogger;
  314. // src/utils/process-output/process-output-buffer.ts
  315. import { StringDecoder } from "string_decoder";
  316. var _ProcessOutputBuffer = class _ProcessOutputBuffer {
  317. constructor(options) {
  318. this.options = options;
  319. this.buffer = [];
  320. this.decoder = new StringDecoder();
  321. }
  322. get all() {
  323. return this.buffer;
  324. }
  325. get last() {
  326. return this.buffer.at(-1);
  327. }
  328. get length() {
  329. return this.buffer.length;
  330. }
  331. write(data, ...args) {
  332. const callback = args[args.length - 1];
  333. this.buffer.push({
  334. time: Date.now(),
  335. stream: this.options?.stream,
  336. entry: this.decoder.write(typeof data === "string" ? Buffer.from(data, typeof args[0] === "string" ? args[0] : void 0) : Buffer.from(data))
  337. });
  338. if (this.options?.limit) {
  339. this.buffer = this.buffer.slice(-this.options.limit);
  340. }
  341. if (typeof callback === "function") {
  342. callback();
  343. }
  344. return true;
  345. }
  346. reset() {
  347. this.buffer = [];
  348. }
  349. };
  350. __name(_ProcessOutputBuffer, "ProcessOutputBuffer");
  351. var ProcessOutputBuffer = _ProcessOutputBuffer;
  352. // src/utils/process-output/process-output-stream.ts
  353. var _ProcessOutputStream = class _ProcessOutputStream {
  354. constructor(stream) {
  355. this.stream = stream;
  356. this.method = stream.write;
  357. this.buffer = new ProcessOutputBuffer({ stream });
  358. }
  359. get out() {
  360. return Object.assign({}, this.stream, {
  361. write: this.write.bind(this)
  362. });
  363. }
  364. hijack() {
  365. this.stream.write = this.buffer.write.bind(this.buffer);
  366. }
  367. release() {
  368. this.stream.write = this.method;
  369. const buffer = [...this.buffer.all];
  370. this.buffer.reset();
  371. return buffer;
  372. }
  373. write(...args) {
  374. return this.method.apply(this.stream, args);
  375. }
  376. };
  377. __name(_ProcessOutputStream, "ProcessOutputStream");
  378. var ProcessOutputStream = _ProcessOutputStream;
  379. // src/utils/process-output/process-output.ts
  380. import { EOL as EOL2 } from "os";
  381. var _ProcessOutput = class _ProcessOutput {
  382. constructor(stdout, stderr, options) {
  383. this.options = options;
  384. this.stream = {
  385. stdout: new ProcessOutputStream(stdout ?? process.stdout),
  386. stderr: new ProcessOutputStream(stderr ?? process.stderr)
  387. };
  388. this.options = {
  389. dump: ["stdout", "stderr"],
  390. leaveEmptyLine: true,
  391. ...options
  392. };
  393. }
  394. get stdout() {
  395. return this.stream.stdout.out;
  396. }
  397. get stderr() {
  398. return this.stream.stderr.out;
  399. }
  400. hijack() {
  401. if (this.active) {
  402. throw new Error("ProcessOutput has been already hijacked!");
  403. }
  404. this.stream.stdout.write(ANSI_ESCAPE_CODES.CURSOR_HIDE);
  405. Object.values(this.stream).forEach((stream) => stream.hijack());
  406. this.active = true;
  407. }
  408. release() {
  409. const output = Object.entries(this.stream).map(([name, stream]) => ({ name, buffer: stream.release() })).filter((output2) => this.options.dump.includes(output2.name)).flatMap((output2) => output2.buffer).sort((a, b) => a.time - b.time).map((message) => {
  410. return {
  411. ...message,
  412. entry: cleanseAnsi(message.entry)
  413. };
  414. }).filter((message) => message.entry);
  415. if (output.length > 0) {
  416. if (this.options.leaveEmptyLine) {
  417. this.stdout.write(EOL2);
  418. }
  419. output.forEach((message) => {
  420. const stream = message.stream ?? this.stdout;
  421. stream.write(message.entry + EOL2);
  422. });
  423. }
  424. this.stream.stdout.write(ANSI_ESCAPE_CODES.CURSOR_SHOW);
  425. this.active = false;
  426. }
  427. toStdout(buffer, eol = true) {
  428. if (eol) {
  429. buffer = buffer + EOL2;
  430. }
  431. return this.stream.stdout.write(buffer);
  432. }
  433. toStderr(buffer, eol = true) {
  434. if (eol) {
  435. buffer = buffer + EOL2;
  436. }
  437. return this.stream.stderr.write(buffer);
  438. }
  439. };
  440. __name(_ProcessOutput, "ProcessOutput");
  441. var ProcessOutput = _ProcessOutput;
  442. // src/utils/process-output/writable.ts
  443. import { Writable } from "stream";
  444. function createWritable(cb) {
  445. const writable = new Writable();
  446. writable.write = (chunk) => {
  447. cb(chunk.toString());
  448. return true;
  449. };
  450. return writable;
  451. }
  452. __name(createWritable, "createWritable");
  453. // src/utils/ui/spinner.ts
  454. var _Spinner = class _Spinner {
  455. constructor() {
  456. this.spinner = !isUnicodeSupported() ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
  457. this.spinnerPosition = 0;
  458. }
  459. spin() {
  460. this.spinnerPosition = ++this.spinnerPosition % this.spinner.length;
  461. }
  462. fetch() {
  463. return this.spinner[this.spinnerPosition];
  464. }
  465. isRunning() {
  466. return !!this.id;
  467. }
  468. start(cb, interval = 100) {
  469. this.id = setInterval(() => {
  470. this.spin();
  471. if (cb) {
  472. cb();
  473. }
  474. }, interval);
  475. }
  476. stop() {
  477. clearInterval(this.id);
  478. }
  479. };
  480. __name(_Spinner, "Spinner");
  481. var Spinner = _Spinner;
  482. // src/utils/ui/prompt.ts
  483. async function createPrompt(options, settings) {
  484. settings = {
  485. ...settings
  486. };
  487. if (!Array.isArray(options)) {
  488. options = [{ ...options, name: "default" }];
  489. } else if (options.length === 1) {
  490. options = options.map((option) => {
  491. return { ...option, name: "default" };
  492. });
  493. }
  494. options = options.map((option) => {
  495. return {
  496. onCancel: () => {
  497. const error = new PromptError("Cancelled prompt.");
  498. if (this instanceof TaskWrapper) {
  499. this.task.prompt = error;
  500. } else {
  501. throw error;
  502. }
  503. return true;
  504. },
  505. ...option,
  506. // this is for outside calls, if it is not called from taskwrapper with bind
  507. stdout: this instanceof TaskWrapper ? settings?.stdout ?? this.stdout("PROMPT" /* PROMPT */) : process.stdout
  508. };
  509. });
  510. let enquirer;
  511. if (settings?.enquirer) {
  512. enquirer = settings.enquirer;
  513. } else {
  514. try {
  515. enquirer = await import("enquirer").then((imported) => imported.default ? new imported.default() : new imported());
  516. } catch (e) {
  517. if (this instanceof TaskWrapper) {
  518. this.task.prompt = new PromptError("Enquirer is a peer dependency that must be installed separately.");
  519. }
  520. throw e;
  521. }
  522. }
  523. let state;
  524. if (this instanceof TaskWrapper) {
  525. state = this.task.state;
  526. this.task.state$ = "PROMPT" /* PROMPT */;
  527. enquirer.on("prompt", (prompt) => this.task.prompt = prompt).on("submit", () => this.task.prompt = void 0);
  528. this.task.on("STATE" /* STATE */, (event) => {
  529. if (event === "SKIPPED" /* SKIPPED */ && this.task.prompt && !(this.task.prompt instanceof PromptError)) {
  530. this.task.prompt.submit();
  531. }
  532. });
  533. }
  534. const response = await enquirer.prompt(options);
  535. if (this instanceof TaskWrapper) {
  536. this.task.state$ = "PROMPT_COMPLETED" /* PROMPT_COMPLETED */;
  537. this.task.state = state;
  538. }
  539. if (options.length === 1) {
  540. return response.default;
  541. } else {
  542. return response;
  543. }
  544. }
  545. __name(createPrompt, "createPrompt");
  546. // src/renderer/default/renderer.constants.ts
  547. var ListrDefaultRendererLogLevels = /* @__PURE__ */ ((ListrDefaultRendererLogLevels2) => {
  548. ListrDefaultRendererLogLevels2["SKIPPED_WITH_COLLAPSE"] = "SKIPPED_WITH_COLLAPSE";
  549. ListrDefaultRendererLogLevels2["SKIPPED_WITHOUT_COLLAPSE"] = "SKIPPED_WITHOUT_COLLAPSE";
  550. ListrDefaultRendererLogLevels2["OUTPUT"] = "OUTPUT";
  551. ListrDefaultRendererLogLevels2["OUTPUT_WITH_BOTTOMBAR"] = "OUTPUT_WITH_BOTTOMBAR";
  552. ListrDefaultRendererLogLevels2["PENDING"] = "PENDING";
  553. ListrDefaultRendererLogLevels2["COMPLETED"] = "COMPLETED";
  554. ListrDefaultRendererLogLevels2["COMPLETED_WITH_FAILED_SUBTASKS"] = "COMPLETED_WITH_FAILED_SUBTASKS";
  555. ListrDefaultRendererLogLevels2["COMPLETED_WITH_FAILED_SISTER_TASKS"] = "COMPLETED_WITH_SISTER_TASKS_FAILED";
  556. ListrDefaultRendererLogLevels2["RETRY"] = "RETRY";
  557. ListrDefaultRendererLogLevels2["ROLLING_BACK"] = "ROLLING_BACK";
  558. ListrDefaultRendererLogLevels2["ROLLED_BACK"] = "ROLLED_BACK";
  559. ListrDefaultRendererLogLevels2["FAILED"] = "FAILED";
  560. ListrDefaultRendererLogLevels2["FAILED_WITH_FAILED_SUBTASKS"] = "FAILED_WITH_SUBTASKS";
  561. ListrDefaultRendererLogLevels2["WAITING"] = "WAITING";
  562. ListrDefaultRendererLogLevels2["PAUSED"] = "PAUSED";
  563. return ListrDefaultRendererLogLevels2;
  564. })(ListrDefaultRendererLogLevels || {});
  565. var LISTR_DEFAULT_RENDERER_STYLE = {
  566. icon: {
  567. ["SKIPPED_WITH_COLLAPSE" /* SKIPPED_WITH_COLLAPSE */]: figures.arrowDown,
  568. ["SKIPPED_WITHOUT_COLLAPSE" /* SKIPPED_WITHOUT_COLLAPSE */]: figures.warning,
  569. ["OUTPUT" /* OUTPUT */]: figures.pointerSmall,
  570. ["OUTPUT_WITH_BOTTOMBAR" /* OUTPUT_WITH_BOTTOMBAR */]: figures.pointerSmall,
  571. ["PENDING" /* PENDING */]: figures.pointer,
  572. ["COMPLETED" /* COMPLETED */]: figures.tick,
  573. ["COMPLETED_WITH_FAILED_SUBTASKS" /* COMPLETED_WITH_FAILED_SUBTASKS */]: figures.warning,
  574. ["COMPLETED_WITH_SISTER_TASKS_FAILED" /* COMPLETED_WITH_FAILED_SISTER_TASKS */]: figures.squareSmallFilled,
  575. ["RETRY" /* RETRY */]: figures.warning,
  576. ["ROLLING_BACK" /* ROLLING_BACK */]: figures.warning,
  577. ["ROLLED_BACK" /* ROLLED_BACK */]: figures.arrowLeft,
  578. ["FAILED" /* FAILED */]: figures.cross,
  579. ["FAILED_WITH_SUBTASKS" /* FAILED_WITH_FAILED_SUBTASKS */]: figures.pointer,
  580. ["WAITING" /* WAITING */]: figures.squareSmallFilled,
  581. ["PAUSED" /* PAUSED */]: figures.squareSmallFilled
  582. },
  583. color: {
  584. ["SKIPPED_WITH_COLLAPSE" /* SKIPPED_WITH_COLLAPSE */]: color.yellow,
  585. ["SKIPPED_WITHOUT_COLLAPSE" /* SKIPPED_WITHOUT_COLLAPSE */]: color.yellow,
  586. ["PENDING" /* PENDING */]: color.yellow,
  587. ["COMPLETED" /* COMPLETED */]: color.green,
  588. ["COMPLETED_WITH_FAILED_SUBTASKS" /* COMPLETED_WITH_FAILED_SUBTASKS */]: color.yellow,
  589. ["COMPLETED_WITH_SISTER_TASKS_FAILED" /* COMPLETED_WITH_FAILED_SISTER_TASKS */]: color.red,
  590. ["RETRY" /* RETRY */]: color.yellowBright,
  591. ["ROLLING_BACK" /* ROLLING_BACK */]: color.redBright,
  592. ["ROLLED_BACK" /* ROLLED_BACK */]: color.redBright,
  593. ["FAILED" /* FAILED */]: color.red,
  594. ["FAILED_WITH_SUBTASKS" /* FAILED_WITH_FAILED_SUBTASKS */]: color.red,
  595. ["WAITING" /* WAITING */]: color.dim,
  596. ["PAUSED" /* PAUSED */]: color.yellowBright
  597. }
  598. };
  599. // src/renderer/default/renderer.ts
  600. import { EOL as EOL3 } from "os";
  601. // src/presets/timer/parser.ts
  602. function parseTimer(duration) {
  603. const seconds = Math.floor(duration / 1e3);
  604. const minutes = Math.floor(seconds / 60);
  605. let parsedTime;
  606. if (seconds === 0 && minutes === 0) {
  607. parsedTime = `0.${Math.floor(duration / 100)}s`;
  608. }
  609. if (seconds > 0) {
  610. parsedTime = `${seconds % 60}s`;
  611. }
  612. if (minutes > 0) {
  613. parsedTime = `${minutes}m${parsedTime}`;
  614. }
  615. return parsedTime;
  616. }
  617. __name(parseTimer, "parseTimer");
  618. // src/presets/timer/preset.ts
  619. var PRESET_TIMER = {
  620. condition: true,
  621. field: parseTimer,
  622. format: () => color.dim
  623. };
  624. // src/presets/timestamp/parser.ts
  625. function parseTimestamp() {
  626. const now = /* @__PURE__ */ new Date();
  627. return String(now.getHours()).padStart(2, "0") + ":" + String(now.getMinutes()).padStart(2, "0") + ":" + String(now.getSeconds()).padStart(2, "0");
  628. }
  629. __name(parseTimestamp, "parseTimestamp");
  630. // src/presets/timestamp/preset.ts
  631. var PRESET_TIMESTAMP = {
  632. condition: true,
  633. field: parseTimestamp,
  634. format: () => color.dim
  635. };
  636. // src/renderer/default/renderer.ts
  637. var _DefaultRenderer = class _DefaultRenderer {
  638. constructor(tasks, options, events) {
  639. this.tasks = tasks;
  640. this.options = options;
  641. this.events = events;
  642. this.bottom = /* @__PURE__ */ new Map();
  643. this.cache = {
  644. output: /* @__PURE__ */ new Map(),
  645. rendererOptions: /* @__PURE__ */ new Map(),
  646. rendererTaskOptions: /* @__PURE__ */ new Map()
  647. };
  648. this.options = {
  649. ..._DefaultRenderer.rendererOptions,
  650. ...this.options,
  651. icon: {
  652. ...LISTR_DEFAULT_RENDERER_STYLE.icon,
  653. ...options?.icon ?? {}
  654. },
  655. color: {
  656. ...LISTR_DEFAULT_RENDERER_STYLE.color,
  657. ...options?.color ?? {}
  658. }
  659. };
  660. this.spinner = this.options.spinner ?? new Spinner();
  661. this.logger = this.options.logger ?? new ListrLogger({ useIcons: true, toStderr: [] });
  662. this.logger.options.icon = this.options.icon;
  663. this.logger.options.color = this.options.color;
  664. }
  665. isBottomBar(task) {
  666. const bottomBar = this.cache.rendererTaskOptions.get(task.id).bottomBar;
  667. return typeof bottomBar === "number" && bottomBar !== 0 || typeof bottomBar === "boolean" && bottomBar !== false || !task.hasTitle();
  668. }
  669. async render() {
  670. const { createLogUpdate } = await import("log-update");
  671. const { default: truncate } = await import("cli-truncate");
  672. const { default: wrap } = await import("wrap-ansi");
  673. this.updater = createLogUpdate(this.logger.process.stdout);
  674. this.truncate = truncate;
  675. this.wrap = wrap;
  676. this.logger.process.hijack();
  677. if (!this.options?.lazy) {
  678. this.spinner.start(() => {
  679. this.update();
  680. });
  681. }
  682. this.events.on("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */, () => {
  683. this.update();
  684. });
  685. }
  686. update() {
  687. this.updater(this.create());
  688. }
  689. end() {
  690. this.spinner.stop();
  691. this.updater.clear();
  692. this.updater.done();
  693. if (!this.options.clearOutput) {
  694. this.logger.process.toStdout(this.create({ prompt: false }));
  695. }
  696. this.logger.process.release();
  697. }
  698. create(options) {
  699. options = {
  700. tasks: true,
  701. bottomBar: true,
  702. prompt: true,
  703. ...options
  704. };
  705. const render = [];
  706. const renderTasks = this.renderer(this.tasks);
  707. const renderBottomBar = this.renderBottomBar();
  708. const renderPrompt = this.renderPrompt();
  709. if (options.tasks && renderTasks.length > 0) {
  710. render.push(...renderTasks);
  711. }
  712. if (options.bottomBar && renderBottomBar.length > 0) {
  713. if (render.length > 0) {
  714. render.push("");
  715. }
  716. render.push(...renderBottomBar);
  717. }
  718. if (options.prompt && renderPrompt.length > 0) {
  719. if (render.length > 0) {
  720. render.push("");
  721. }
  722. render.push(...renderPrompt);
  723. }
  724. return render.join(EOL3);
  725. }
  726. // eslint-disable-next-line complexity
  727. style(task, output = false) {
  728. const rendererOptions = this.cache.rendererOptions.get(task.id);
  729. if (task.isSkipped()) {
  730. if (output || rendererOptions.collapseSkips) {
  731. return this.logger.icon("SKIPPED_WITH_COLLAPSE" /* SKIPPED_WITH_COLLAPSE */);
  732. } else if (rendererOptions.collapseSkips === false) {
  733. return this.logger.icon("SKIPPED_WITHOUT_COLLAPSE" /* SKIPPED_WITHOUT_COLLAPSE */);
  734. }
  735. }
  736. if (output) {
  737. if (this.isBottomBar(task)) {
  738. return this.logger.icon("OUTPUT_WITH_BOTTOMBAR" /* OUTPUT_WITH_BOTTOMBAR */);
  739. }
  740. return this.logger.icon("OUTPUT" /* OUTPUT */);
  741. }
  742. if (task.hasSubtasks()) {
  743. if (task.isStarted() || task.isPrompt() && rendererOptions.showSubtasks !== false && !task.subtasks.every((subtask) => !subtask.hasTitle())) {
  744. return this.logger.icon("PENDING" /* PENDING */);
  745. } else if (task.isCompleted() && task.subtasks.some((subtask) => subtask.hasFailed())) {
  746. return this.logger.icon("COMPLETED_WITH_FAILED_SUBTASKS" /* COMPLETED_WITH_FAILED_SUBTASKS */);
  747. } else if (task.hasFailed()) {
  748. return this.logger.icon("FAILED_WITH_SUBTASKS" /* FAILED_WITH_FAILED_SUBTASKS */);
  749. }
  750. }
  751. if (task.isStarted() || task.isPrompt()) {
  752. return this.logger.icon("PENDING" /* PENDING */, !this.options?.lazy && this.spinner.fetch());
  753. } else if (task.isCompleted()) {
  754. return this.logger.icon("COMPLETED" /* COMPLETED */);
  755. } else if (task.isRetrying()) {
  756. return this.logger.icon("RETRY" /* RETRY */, !this.options?.lazy && this.spinner.fetch());
  757. } else if (task.isRollingBack()) {
  758. return this.logger.icon("ROLLING_BACK" /* ROLLING_BACK */, !this.options?.lazy && this.spinner.fetch());
  759. } else if (task.hasRolledBack()) {
  760. return this.logger.icon("ROLLED_BACK" /* ROLLED_BACK */);
  761. } else if (task.hasFailed()) {
  762. return this.logger.icon("FAILED" /* FAILED */);
  763. } else if (task.isPaused()) {
  764. return this.logger.icon("PAUSED" /* PAUSED */);
  765. }
  766. return this.logger.icon("WAITING" /* WAITING */);
  767. }
  768. format(message, icon, level) {
  769. if (message.trim() === "") {
  770. return [];
  771. }
  772. if (icon) {
  773. message = icon + " " + message;
  774. }
  775. let parsed;
  776. const columns = (process.stdout.columns ?? 80) - level * this.options.indentation - 2;
  777. switch (this.options.formatOutput) {
  778. case "truncate":
  779. parsed = message.split(EOL3).map((s, i) => {
  780. return this.truncate(this.indent(s, i), columns);
  781. });
  782. break;
  783. case "wrap":
  784. parsed = this.wrap(message, columns, { hard: true }).split(EOL3).map((s, i) => this.indent(s, i));
  785. break;
  786. default:
  787. throw new ListrRendererError("Format option for the renderer is wrong.");
  788. }
  789. if (this.options.removeEmptyLines) {
  790. parsed = parsed.filter(Boolean);
  791. }
  792. return parsed.map((str) => indent(str, level * this.options.indentation));
  793. }
  794. renderer(tasks, level = 0) {
  795. return tasks.flatMap((task) => {
  796. if (!task.isEnabled()) {
  797. return [];
  798. }
  799. if (this.cache.output.has(task.id)) {
  800. return this.cache.output.get(task.id);
  801. }
  802. this.calculate(task);
  803. const rendererOptions = this.cache.rendererOptions.get(task.id);
  804. const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
  805. const output = [];
  806. if (task.isPrompt()) {
  807. if (this.activePrompt && this.activePrompt !== task.id) {
  808. throw new ListrRendererError("Only one prompt can be active at the given time, please re-evaluate your task design.");
  809. } else if (!this.activePrompt) {
  810. task.on("PROMPT" /* PROMPT */, (prompt) => {
  811. const cleansed = cleanseAnsi(prompt);
  812. if (cleansed) {
  813. this.prompt = cleansed;
  814. }
  815. });
  816. task.on("STATE" /* STATE */, (state) => {
  817. if (state === "PROMPT_COMPLETED" /* PROMPT_COMPLETED */ || task.hasFinalized() || task.hasReset()) {
  818. this.prompt = null;
  819. this.activePrompt = null;
  820. task.off("PROMPT" /* PROMPT */);
  821. }
  822. });
  823. this.activePrompt = task.id;
  824. }
  825. }
  826. if (task.hasTitle()) {
  827. if (!(tasks.some((task2) => task2.hasFailed()) && !task.hasFailed() && task.options.exitOnError !== false && !(task.isCompleted() || task.isSkipped()))) {
  828. if (task.hasFailed() && rendererOptions.collapseErrors) {
  829. output.push(...this.format(!task.hasSubtasks() && task.message.error && rendererOptions.showErrorMessage ? task.message.error : task.title, this.style(task), level));
  830. } else if (task.isSkipped() && rendererOptions.collapseSkips) {
  831. output.push(
  832. ...this.format(
  833. this.logger.suffix(task.message.skip && rendererOptions.showSkipMessage ? task.message.skip : task.title, {
  834. field: "SKIPPED" /* SKIPPED */,
  835. condition: rendererOptions.suffixSkips,
  836. format: () => color.dim
  837. }),
  838. this.style(task),
  839. level
  840. )
  841. );
  842. } else if (task.isRetrying()) {
  843. output.push(
  844. ...this.format(
  845. this.logger.suffix(task.title, {
  846. field: `${"RETRY" /* RETRY */}:${task.message.retry.count}`,
  847. format: () => color.yellow,
  848. condition: rendererOptions.suffixRetries
  849. }),
  850. this.style(task),
  851. level
  852. )
  853. );
  854. } else if (task.isCompleted() && task.hasTitle() && assertFunctionOrSelf(rendererTaskOptions.timer?.condition, task.message.duration)) {
  855. output.push(
  856. ...this.format(
  857. this.logger.suffix(task?.title, {
  858. ...rendererTaskOptions.timer,
  859. args: [task.message.duration]
  860. }),
  861. this.style(task),
  862. level
  863. )
  864. );
  865. } else if (task.isPaused()) {
  866. output.push(
  867. ...this.format(
  868. this.logger.suffix(task.title, {
  869. ...rendererOptions.pausedTimer,
  870. args: [task.message.paused - Date.now()]
  871. }),
  872. this.style(task),
  873. level
  874. )
  875. );
  876. } else {
  877. output.push(...this.format(task.title, this.style(task), level));
  878. }
  879. } else {
  880. output.push(...this.format(task.title, this.logger.icon("COMPLETED_WITH_SISTER_TASKS_FAILED" /* COMPLETED_WITH_FAILED_SISTER_TASKS */), level));
  881. }
  882. }
  883. if (!task.hasSubtasks() || !rendererOptions.showSubtasks) {
  884. if (task.hasFailed() && rendererOptions.collapseErrors === false && (rendererOptions.showErrorMessage || !rendererOptions.showSubtasks)) {
  885. output.push(...this.dump(task, level, "FAILED" /* FAILED */));
  886. } else if (task.isSkipped() && rendererOptions.collapseSkips === false && (rendererOptions.showSkipMessage || !rendererOptions.showSubtasks)) {
  887. output.push(...this.dump(task, level, "SKIPPED" /* SKIPPED */));
  888. }
  889. }
  890. if (task?.output) {
  891. if (this.isBottomBar(task)) {
  892. if (!this.bottom.has(task.id)) {
  893. this.bottom.set(task.id, new ProcessOutputBuffer({ limit: typeof rendererTaskOptions.bottomBar === "boolean" ? 1 : rendererTaskOptions.bottomBar }));
  894. task.on("OUTPUT" /* OUTPUT */, (output2) => {
  895. const data = this.dump(task, -1, "OUTPUT" /* OUTPUT */, output2);
  896. this.bottom.get(task.id).write(data.join(EOL3));
  897. });
  898. }
  899. } else if (task.isPending() || rendererTaskOptions.persistentOutput) {
  900. output.push(...this.dump(task, level));
  901. }
  902. }
  903. if (
  904. // check if renderer option is on first
  905. rendererOptions.showSubtasks !== false && // if it doesnt have subtasks no need to check
  906. task.hasSubtasks() && (task.isPending() || task.hasFinalized() && !task.hasTitle() || // have to be completed and have subtasks
  907. task.isCompleted() && rendererOptions.collapseSubtasks === false && !task.subtasks.some((subtask) => subtask.rendererOptions.collapseSubtasks === true) || // if any of the subtasks have the collapse option of
  908. task.subtasks.some((subtask) => subtask.rendererOptions.collapseSubtasks === false) || // if any of the subtasks has failed
  909. task.subtasks.some((subtask) => subtask.hasFailed()) || // if any of the subtasks rolled back
  910. task.subtasks.some((subtask) => subtask.hasRolledBack()))
  911. ) {
  912. const subtaskLevel = !task.hasTitle() ? level : level + 1;
  913. const subtaskRender = this.renderer(task.subtasks, subtaskLevel);
  914. output.push(...subtaskRender);
  915. }
  916. if (task.hasFinalized()) {
  917. if (!rendererTaskOptions.persistentOutput) {
  918. this.bottom.delete(task.id);
  919. }
  920. }
  921. if (task.isClosed()) {
  922. this.cache.output.set(task.id, output);
  923. this.reset(task);
  924. }
  925. return output;
  926. });
  927. }
  928. renderBottomBar() {
  929. if (this.bottom.size === 0) {
  930. return [];
  931. }
  932. return Array.from(this.bottom.values()).flatMap((output) => output.all).sort((a, b) => a.time - b.time).map((output) => output.entry);
  933. }
  934. renderPrompt() {
  935. if (!this.prompt) {
  936. return [];
  937. }
  938. return [this.prompt];
  939. }
  940. calculate(task) {
  941. if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) {
  942. return;
  943. }
  944. const rendererOptions = {
  945. ...this.options,
  946. ...task.rendererOptions
  947. };
  948. this.cache.rendererOptions.set(task.id, rendererOptions);
  949. this.cache.rendererTaskOptions.set(task.id, {
  950. ..._DefaultRenderer.rendererTaskOptions,
  951. timer: rendererOptions.timer,
  952. ...task.rendererTaskOptions
  953. });
  954. }
  955. reset(task) {
  956. this.cache.rendererOptions.delete(task.id);
  957. this.cache.rendererTaskOptions.delete(task.id);
  958. }
  959. dump(task, level, source = "OUTPUT" /* OUTPUT */, data) {
  960. if (!data) {
  961. switch (source) {
  962. case "OUTPUT" /* OUTPUT */:
  963. data = task.output;
  964. break;
  965. case "SKIPPED" /* SKIPPED */:
  966. data = task.message.skip;
  967. break;
  968. case "FAILED" /* FAILED */:
  969. data = task.message.error;
  970. break;
  971. }
  972. }
  973. if (task.hasTitle() && source === "FAILED" /* FAILED */ && data === task.title || typeof data !== "string") {
  974. return [];
  975. }
  976. if (source === "OUTPUT" /* OUTPUT */) {
  977. data = cleanseAnsi(data);
  978. }
  979. return this.format(data, this.style(task, true), level + 1);
  980. }
  981. indent(str, i) {
  982. return i > 0 ? indent(str.trim(), this.options.indentation) : str.trim();
  983. }
  984. };
  985. __name(_DefaultRenderer, "DefaultRenderer");
  986. _DefaultRenderer.nonTTY = false;
  987. _DefaultRenderer.rendererOptions = {
  988. indentation: 2,
  989. clearOutput: false,
  990. showSubtasks: true,
  991. collapseSubtasks: true,
  992. collapseSkips: true,
  993. showSkipMessage: true,
  994. suffixSkips: false,
  995. collapseErrors: true,
  996. showErrorMessage: true,
  997. suffixRetries: true,
  998. lazy: false,
  999. removeEmptyLines: true,
  1000. formatOutput: "wrap",
  1001. pausedTimer: {
  1002. ...PRESET_TIMER,
  1003. format: () => color.yellowBright
  1004. }
  1005. };
  1006. var DefaultRenderer = _DefaultRenderer;
  1007. // src/renderer/silent/renderer.ts
  1008. var _SilentRenderer = class _SilentRenderer {
  1009. constructor(tasks, options) {
  1010. this.tasks = tasks;
  1011. this.options = options;
  1012. }
  1013. render() {
  1014. return;
  1015. }
  1016. end() {
  1017. return;
  1018. }
  1019. };
  1020. __name(_SilentRenderer, "SilentRenderer");
  1021. _SilentRenderer.nonTTY = true;
  1022. var SilentRenderer = _SilentRenderer;
  1023. // src/renderer/simple/renderer.ts
  1024. var _SimpleRenderer = class _SimpleRenderer {
  1025. constructor(tasks, options) {
  1026. this.tasks = tasks;
  1027. this.options = options;
  1028. this.cache = {
  1029. rendererOptions: /* @__PURE__ */ new Map(),
  1030. rendererTaskOptions: /* @__PURE__ */ new Map()
  1031. };
  1032. this.options = {
  1033. ..._SimpleRenderer.rendererOptions,
  1034. ...options,
  1035. icon: {
  1036. ...LISTR_LOGGER_STYLE.icon,
  1037. ...options?.icon ?? {}
  1038. },
  1039. color: {
  1040. ...LISTR_LOGGER_STYLE.color,
  1041. ...options?.color ?? {}
  1042. }
  1043. };
  1044. this.logger = this.options.logger ?? new ListrLogger({ useIcons: true, toStderr: LISTR_LOGGER_STDERR_LEVELS });
  1045. this.logger.options.icon = this.options.icon;
  1046. this.logger.options.color = this.options.color;
  1047. if (this.options.timestamp) {
  1048. this.logger.options.fields.prefix.unshift(this.options.timestamp);
  1049. }
  1050. }
  1051. end() {
  1052. this.logger.process.release();
  1053. }
  1054. render() {
  1055. this.renderer(this.tasks);
  1056. }
  1057. renderer(tasks) {
  1058. tasks.forEach((task) => {
  1059. this.calculate(task);
  1060. task.once("CLOSED" /* CLOSED */, () => {
  1061. this.reset(task);
  1062. });
  1063. const rendererOptions = this.cache.rendererOptions.get(task.id);
  1064. const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
  1065. task.on("SUBTASK" /* SUBTASK */, (subtasks) => {
  1066. this.renderer(subtasks);
  1067. });
  1068. task.on("STATE" /* STATE */, (state) => {
  1069. if (!task.hasTitle()) {
  1070. return;
  1071. }
  1072. if (state === "STARTED" /* STARTED */) {
  1073. this.logger.log("STARTED" /* STARTED */, task.title);
  1074. } else if (state === "COMPLETED" /* COMPLETED */) {
  1075. const timer = rendererTaskOptions?.timer;
  1076. this.logger.log(
  1077. "COMPLETED" /* COMPLETED */,
  1078. task.title,
  1079. timer && {
  1080. suffix: {
  1081. ...timer,
  1082. condition: !!task.message?.duration && timer.condition,
  1083. args: [task.message.duration]
  1084. }
  1085. }
  1086. );
  1087. } else if (state === "PROMPT" /* PROMPT */) {
  1088. this.logger.process.hijack();
  1089. task.on("PROMPT" /* PROMPT */, (prompt) => {
  1090. this.logger.process.toStderr(prompt, false);
  1091. });
  1092. } else if (state === "PROMPT_COMPLETED" /* PROMPT_COMPLETED */) {
  1093. task.off("PROMPT" /* PROMPT */);
  1094. this.logger.process.release();
  1095. }
  1096. });
  1097. task.on("OUTPUT" /* OUTPUT */, (output) => {
  1098. this.logger.log("OUTPUT" /* OUTPUT */, output);
  1099. });
  1100. task.on("MESSAGE" /* MESSAGE */, (message) => {
  1101. if (message.error) {
  1102. this.logger.log("FAILED" /* FAILED */, task.title, {
  1103. suffix: {
  1104. field: `${"FAILED" /* FAILED */}: ${message.error}`,
  1105. format: () => color.red
  1106. }
  1107. });
  1108. } else if (message.skip) {
  1109. this.logger.log("SKIPPED" /* SKIPPED */, task.title, {
  1110. suffix: {
  1111. field: `${"SKIPPED" /* SKIPPED */}: ${message.skip}`,
  1112. format: () => color.yellow
  1113. }
  1114. });
  1115. } else if (message.rollback) {
  1116. this.logger.log("ROLLBACK" /* ROLLBACK */, task.title, {
  1117. suffix: {
  1118. field: `${"ROLLBACK" /* ROLLBACK */}: ${message.rollback}`,
  1119. format: () => color.red
  1120. }
  1121. });
  1122. } else if (message.retry) {
  1123. this.logger.log("RETRY" /* RETRY */, task.title, {
  1124. suffix: {
  1125. field: `${"RETRY" /* RETRY */}:${message.retry.count}`,
  1126. format: () => color.red
  1127. }
  1128. });
  1129. } else if (message.paused) {
  1130. const timer = rendererOptions?.pausedTimer;
  1131. this.logger.log(
  1132. "PAUSED" /* PAUSED */,
  1133. task.title,
  1134. timer && {
  1135. suffix: {
  1136. ...timer,
  1137. condition: !!message?.paused && timer.condition,
  1138. args: [message.paused - Date.now()]
  1139. }
  1140. }
  1141. );
  1142. }
  1143. });
  1144. });
  1145. }
  1146. calculate(task) {
  1147. if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) {
  1148. return;
  1149. }
  1150. const rendererOptions = {
  1151. ...this.options,
  1152. ...task.rendererOptions
  1153. };
  1154. this.cache.rendererOptions.set(task.id, rendererOptions);
  1155. this.cache.rendererTaskOptions.set(task.id, {
  1156. ..._SimpleRenderer.rendererTaskOptions,
  1157. timer: rendererOptions.timer,
  1158. ...task.rendererTaskOptions
  1159. });
  1160. }
  1161. reset(task) {
  1162. this.cache.rendererOptions.delete(task.id);
  1163. this.cache.rendererTaskOptions.delete(task.id);
  1164. }
  1165. };
  1166. __name(_SimpleRenderer, "SimpleRenderer");
  1167. _SimpleRenderer.nonTTY = true;
  1168. _SimpleRenderer.rendererOptions = {
  1169. pausedTimer: {
  1170. ...PRESET_TIMER,
  1171. field: (time) => `${"PAUSED" /* PAUSED */}:${time}`,
  1172. format: () => color.yellowBright
  1173. }
  1174. };
  1175. _SimpleRenderer.rendererTaskOptions = {};
  1176. var SimpleRenderer = _SimpleRenderer;
  1177. // src/renderer/test/serializer.ts
  1178. var _TestRendererSerializer = class _TestRendererSerializer {
  1179. constructor(options) {
  1180. this.options = options;
  1181. }
  1182. serialize(event, data, task) {
  1183. return JSON.stringify(this.generate(event, data, task));
  1184. }
  1185. generate(event, data, task) {
  1186. const output = {
  1187. event,
  1188. data
  1189. };
  1190. if (typeof this.options?.task !== "boolean") {
  1191. const t = Object.fromEntries(
  1192. this.options.task.map((entity) => {
  1193. const property = task[entity];
  1194. if (typeof property === "function") {
  1195. return [entity, property.call(task)];
  1196. }
  1197. return [entity, property];
  1198. })
  1199. );
  1200. if (Object.keys(task).length > 0) {
  1201. output.task = t;
  1202. }
  1203. }
  1204. return output;
  1205. }
  1206. };
  1207. __name(_TestRendererSerializer, "TestRendererSerializer");
  1208. var TestRendererSerializer = _TestRendererSerializer;
  1209. // src/renderer/test/renderer.ts
  1210. var _TestRenderer = class _TestRenderer {
  1211. constructor(tasks, options) {
  1212. this.tasks = tasks;
  1213. this.options = options;
  1214. this.options = { ..._TestRenderer.rendererOptions, ...this.options };
  1215. this.logger = this.options.logger ?? new ListrLogger({ useIcons: false });
  1216. this.serializer = new TestRendererSerializer(this.options);
  1217. }
  1218. render() {
  1219. this.renderer(this.tasks);
  1220. }
  1221. // eslint-disable-next-line @typescript-eslint/no-empty-function
  1222. end() {
  1223. }
  1224. // verbose renderer multi-level
  1225. renderer(tasks) {
  1226. tasks.forEach((task) => {
  1227. if (this.options.subtasks) {
  1228. task.on("SUBTASK" /* SUBTASK */, (subtasks) => {
  1229. this.renderer(subtasks);
  1230. });
  1231. }
  1232. if (this.options.state) {
  1233. task.on("STATE" /* STATE */, (state) => {
  1234. this.logger.toStdout(this.serializer.serialize("STATE" /* STATE */, state, task));
  1235. });
  1236. }
  1237. if (this.options.output) {
  1238. task.on("OUTPUT" /* OUTPUT */, (data) => {
  1239. this.logger.toStdout(this.serializer.serialize("OUTPUT" /* OUTPUT */, data, task));
  1240. });
  1241. }
  1242. if (this.options.prompt) {
  1243. task.on("PROMPT" /* PROMPT */, (prompt) => {
  1244. this.logger.toStdout(this.serializer.serialize("PROMPT" /* PROMPT */, prompt, task));
  1245. });
  1246. }
  1247. if (this.options.title) {
  1248. task.on("TITLE" /* TITLE */, (title) => {
  1249. this.logger.toStdout(this.serializer.serialize("TITLE" /* TITLE */, title, task));
  1250. });
  1251. }
  1252. task.on("MESSAGE" /* MESSAGE */, (message) => {
  1253. const parsed = Object.fromEntries(
  1254. Object.entries(message).map(([key, value]) => {
  1255. if (this.options.messages.includes(key)) {
  1256. return [key, value];
  1257. }
  1258. }).filter(Boolean)
  1259. );
  1260. if (Object.keys(parsed).length > 0) {
  1261. const output = this.serializer.serialize("MESSAGE" /* MESSAGE */, parsed, task);
  1262. if (this.options.messagesToStderr.some((state) => Object.keys(parsed).includes(state))) {
  1263. this.logger.toStderr(output);
  1264. } else {
  1265. this.logger.toStdout(output);
  1266. }
  1267. }
  1268. });
  1269. });
  1270. }
  1271. };
  1272. __name(_TestRenderer, "TestRenderer");
  1273. _TestRenderer.nonTTY = true;
  1274. _TestRenderer.rendererOptions = {
  1275. subtasks: true,
  1276. state: Object.values(ListrTaskState),
  1277. output: true,
  1278. prompt: true,
  1279. title: true,
  1280. messages: ["skip", "error", "retry", "rollback", "paused"],
  1281. messagesToStderr: ["error", "rollback", "retry"],
  1282. task: [
  1283. "hasRolledBack",
  1284. "isRollingBack",
  1285. "isCompleted",
  1286. "isSkipped",
  1287. "hasFinalized",
  1288. "hasSubtasks",
  1289. "title",
  1290. "hasReset",
  1291. "hasTitle",
  1292. "isPrompt",
  1293. "isPaused",
  1294. "isPending",
  1295. "isSkipped",
  1296. "isStarted",
  1297. "hasFailed",
  1298. "isEnabled",
  1299. "isRetrying",
  1300. "path"
  1301. ]
  1302. };
  1303. var TestRenderer = _TestRenderer;
  1304. // src/renderer/verbose/renderer.ts
  1305. var _VerboseRenderer = class _VerboseRenderer {
  1306. constructor(tasks, options) {
  1307. this.tasks = tasks;
  1308. this.options = options;
  1309. this.cache = {
  1310. rendererOptions: /* @__PURE__ */ new Map(),
  1311. rendererTaskOptions: /* @__PURE__ */ new Map()
  1312. };
  1313. this.options = {
  1314. ..._VerboseRenderer.rendererOptions,
  1315. ...this.options,
  1316. icon: {
  1317. ...LISTR_LOGGER_STYLE.icon,
  1318. ...options?.icon ?? {}
  1319. },
  1320. color: {
  1321. ...LISTR_LOGGER_STYLE.color,
  1322. ...options?.color ?? {}
  1323. }
  1324. };
  1325. this.logger = this.options.logger ?? new ListrLogger({ useIcons: false, toStderr: LISTR_LOGGER_STDERR_LEVELS });
  1326. this.logger.options.icon = this.options.icon;
  1327. this.logger.options.color = this.options.color;
  1328. if (this.options.timestamp) {
  1329. this.logger.options.fields.prefix.unshift(this.options.timestamp);
  1330. }
  1331. }
  1332. render() {
  1333. this.renderer(this.tasks);
  1334. }
  1335. // eslint-disable-next-line @typescript-eslint/no-empty-function
  1336. end() {
  1337. }
  1338. renderer(tasks) {
  1339. tasks.forEach((task) => {
  1340. this.calculate(task);
  1341. task.once("CLOSED" /* CLOSED */, () => {
  1342. this.reset(task);
  1343. });
  1344. const rendererOptions = this.cache.rendererOptions.get(task.id);
  1345. const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
  1346. task.on("SUBTASK" /* SUBTASK */, (subtasks) => {
  1347. this.renderer(subtasks);
  1348. });
  1349. task.on("STATE" /* STATE */, (state) => {
  1350. if (!task.hasTitle()) {
  1351. return;
  1352. }
  1353. if (state === "STARTED" /* STARTED */) {
  1354. this.logger.log("STARTED" /* STARTED */, task.title);
  1355. } else if (state === "COMPLETED" /* COMPLETED */) {
  1356. const timer = rendererTaskOptions.timer;
  1357. this.logger.log(
  1358. "COMPLETED" /* COMPLETED */,
  1359. task.title,
  1360. timer && {
  1361. suffix: {
  1362. ...timer,
  1363. condition: !!task.message?.duration && timer.condition,
  1364. args: [task.message.duration]
  1365. }
  1366. }
  1367. );
  1368. }
  1369. });
  1370. task.on("OUTPUT" /* OUTPUT */, (data) => {
  1371. this.logger.log("OUTPUT" /* OUTPUT */, data);
  1372. });
  1373. task.on("PROMPT" /* PROMPT */, (prompt) => {
  1374. const cleansed = cleanseAnsi(prompt);
  1375. if (cleansed) {
  1376. this.logger.log("PROMPT" /* PROMPT */, cleansed);
  1377. }
  1378. });
  1379. if (this.options?.logTitleChange !== false) {
  1380. task.on("TITLE" /* TITLE */, (title) => {
  1381. this.logger.log("TITLE" /* TITLE */, title);
  1382. });
  1383. }
  1384. task.on("MESSAGE" /* MESSAGE */, (message) => {
  1385. if (message?.error) {
  1386. this.logger.log("FAILED" /* FAILED */, message.error);
  1387. } else if (message?.skip) {
  1388. this.logger.log("SKIPPED" /* SKIPPED */, message.skip);
  1389. } else if (message?.rollback) {
  1390. this.logger.log("ROLLBACK" /* ROLLBACK */, message.rollback);
  1391. } else if (message?.retry) {
  1392. this.logger.log("RETRY" /* RETRY */, task.title, { suffix: message.retry.count.toString() });
  1393. } else if (message?.paused) {
  1394. const timer = rendererOptions?.pausedTimer;
  1395. this.logger.log(
  1396. "PAUSED" /* PAUSED */,
  1397. task.title,
  1398. timer && {
  1399. suffix: {
  1400. ...timer,
  1401. condition: !!message?.paused && timer.condition,
  1402. args: [message.paused - Date.now()]
  1403. }
  1404. }
  1405. );
  1406. }
  1407. });
  1408. });
  1409. }
  1410. calculate(task) {
  1411. if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id)) {
  1412. return;
  1413. }
  1414. const rendererOptions = {
  1415. ...this.options,
  1416. ...task.rendererOptions
  1417. };
  1418. this.cache.rendererOptions.set(task.id, rendererOptions);
  1419. this.cache.rendererTaskOptions.set(task.id, {
  1420. ..._VerboseRenderer.rendererTaskOptions,
  1421. timer: rendererOptions.timer,
  1422. ...task.rendererTaskOptions
  1423. });
  1424. }
  1425. reset(task) {
  1426. this.cache.rendererOptions.delete(task.id);
  1427. this.cache.rendererTaskOptions.delete(task.id);
  1428. }
  1429. };
  1430. __name(_VerboseRenderer, "VerboseRenderer");
  1431. _VerboseRenderer.nonTTY = true;
  1432. _VerboseRenderer.rendererOptions = {
  1433. logTitleChange: false,
  1434. pausedTimer: {
  1435. ...PRESET_TIMER,
  1436. format: () => color.yellowBright
  1437. }
  1438. };
  1439. var VerboseRenderer = _VerboseRenderer;
  1440. // src/utils/ui/renderer.ts
  1441. var RENDERERS = {
  1442. default: DefaultRenderer,
  1443. simple: SimpleRenderer,
  1444. verbose: VerboseRenderer,
  1445. test: TestRenderer,
  1446. silent: SilentRenderer
  1447. };
  1448. function isRendererSupported(renderer) {
  1449. return process.stdout.isTTY === true || renderer.nonTTY === true;
  1450. }
  1451. __name(isRendererSupported, "isRendererSupported");
  1452. function getRendererClass(renderer) {
  1453. if (typeof renderer === "string") {
  1454. return RENDERERS[renderer] ?? RENDERERS.default;
  1455. }
  1456. return typeof renderer === "function" ? renderer : RENDERERS.default;
  1457. }
  1458. __name(getRendererClass, "getRendererClass");
  1459. function getRenderer(options) {
  1460. if (assertFunctionOrSelf(options?.silentRendererCondition)) {
  1461. return { renderer: getRendererClass("silent") };
  1462. }
  1463. const r = { renderer: getRendererClass(options.renderer), options: options.rendererOptions };
  1464. if (!isRendererSupported(r.renderer) || assertFunctionOrSelf(options?.fallbackRendererCondition)) {
  1465. return { renderer: getRendererClass(options.fallbackRenderer), options: options.fallbackRendererOptions };
  1466. }
  1467. return r;
  1468. }
  1469. __name(getRenderer, "getRenderer");
  1470. // src/utils/assert.ts
  1471. function assertFunctionOrSelf(functionOrSelf, ...args) {
  1472. if (typeof functionOrSelf === "function") {
  1473. return functionOrSelf(...args);
  1474. } else {
  1475. return functionOrSelf;
  1476. }
  1477. }
  1478. __name(assertFunctionOrSelf, "assertFunctionOrSelf");
  1479. // src/utils/clone.ts
  1480. import rfdc from "rfdc";
  1481. var clone = rfdc({ circles: true });
  1482. function cloneObject(obj) {
  1483. return clone(obj);
  1484. }
  1485. __name(cloneObject, "cloneObject");
  1486. // src/utils/concurrency.ts
  1487. var _Concurrency = class _Concurrency {
  1488. constructor(options) {
  1489. this.concurrency = options.concurrency;
  1490. this.count = 0;
  1491. this.queue = /* @__PURE__ */ new Set();
  1492. }
  1493. add(fn) {
  1494. if (this.count < this.concurrency) {
  1495. return this.run(fn);
  1496. }
  1497. return new Promise((resolve) => {
  1498. const callback = /* @__PURE__ */ __name(() => resolve(this.run(fn)), "callback");
  1499. this.queue.add(callback);
  1500. });
  1501. }
  1502. flush() {
  1503. for (const callback of this.queue) {
  1504. if (this.count >= this.concurrency) {
  1505. break;
  1506. }
  1507. this.queue.delete(callback);
  1508. callback();
  1509. }
  1510. }
  1511. run(fn) {
  1512. this.count++;
  1513. const promise = fn();
  1514. const cleanup = /* @__PURE__ */ __name(() => {
  1515. this.count--;
  1516. this.flush();
  1517. }, "cleanup");
  1518. promise.then(cleanup, () => {
  1519. this.queue.clear();
  1520. });
  1521. return promise;
  1522. }
  1523. };
  1524. __name(_Concurrency, "Concurrency");
  1525. var Concurrency = _Concurrency;
  1526. // src/utils/delay.ts
  1527. function delay(time) {
  1528. return new Promise((resolve) => {
  1529. setTimeout(resolve, time);
  1530. });
  1531. }
  1532. __name(delay, "delay");
  1533. // src/interfaces/listr-error.interface.ts
  1534. var _ListrError = class _ListrError extends Error {
  1535. constructor(error, type, task) {
  1536. super(error.message);
  1537. this.error = error;
  1538. this.type = type;
  1539. this.task = task;
  1540. this.name = "ListrError";
  1541. this.path = task.path;
  1542. if (task?.options.collectErrors === "full") {
  1543. this.task = cloneObject(task);
  1544. this.ctx = cloneObject(task.listr.ctx);
  1545. }
  1546. this.stack = error?.stack;
  1547. }
  1548. };
  1549. __name(_ListrError, "ListrError");
  1550. var ListrError = _ListrError;
  1551. // src/interfaces/listr-renderer-error.interface.ts
  1552. var _ListrRendererError = class _ListrRendererError extends Error {
  1553. };
  1554. __name(_ListrRendererError, "ListrRendererError");
  1555. var ListrRendererError = _ListrRendererError;
  1556. // src/interfaces/prompt-error.interface.ts
  1557. var _PromptError = class _PromptError extends Error {
  1558. };
  1559. __name(_PromptError, "PromptError");
  1560. var PromptError = _PromptError;
  1561. // src/lib/task-wrapper.ts
  1562. var _TaskWrapper = class _TaskWrapper {
  1563. constructor(task, options) {
  1564. this.task = task;
  1565. this.options = options;
  1566. }
  1567. get title() {
  1568. return this.task.title;
  1569. }
  1570. /**
  1571. * Title of the current task.
  1572. *
  1573. * @see {@link https://listr2.kilic.dev/task/title.html}
  1574. */
  1575. set title(title) {
  1576. title = Array.isArray(title) ? title : [title];
  1577. this.task.title$ = splat(title.shift(), ...title);
  1578. }
  1579. get output() {
  1580. return this.task.output;
  1581. }
  1582. /**
  1583. * Send output from the current task to the renderer.
  1584. *
  1585. * @see {@link https://listr2.kilic.dev/task/output.html}
  1586. */
  1587. set output(output) {
  1588. output = Array.isArray(output) ? output : [output];
  1589. this.task.output$ = splat(output.shift(), ...output);
  1590. }
  1591. /** Send an output to the output channel as prompt. */
  1592. set promptOutput(output) {
  1593. this.task.promptOutput$ = output;
  1594. }
  1595. /**
  1596. * Creates a new set of Listr subtasks.
  1597. *
  1598. * @see {@link https://listr2.kilic.dev/task/subtasks.html}
  1599. */
  1600. newListr(task, options) {
  1601. let tasks;
  1602. if (typeof task === "function") {
  1603. tasks = task(this);
  1604. } else {
  1605. tasks = task;
  1606. }
  1607. return new Listr(tasks, options, this.task);
  1608. }
  1609. /**
  1610. * Report an error that has to be collected and handled.
  1611. *
  1612. * @see {@link https://listr2.kilic.dev/task/error-handling.html}
  1613. */
  1614. report(error, type) {
  1615. if (this.task.options.collectErrors !== false) {
  1616. this.task.listr.errors.push(new ListrError(error, type, this.task));
  1617. }
  1618. this.task.message$ = { error: error.message ?? this.task?.title };
  1619. }
  1620. /**
  1621. * Skip the current task.
  1622. *
  1623. * @see {@link https://listr2.kilic.dev/task/skip.html}
  1624. */
  1625. skip(message, ...metadata) {
  1626. this.task.state$ = "SKIPPED" /* SKIPPED */;
  1627. if (message) {
  1628. this.task.message$ = { skip: message ? splat(message, ...metadata) : this.task?.title };
  1629. }
  1630. }
  1631. /**
  1632. * Check whether this task is currently in a retry state.
  1633. *
  1634. * @see {@link https://listr2.kilic.dev/task/retry.html}
  1635. */
  1636. isRetrying() {
  1637. return this.task.isRetrying() ? this.task.retry : { count: 0 };
  1638. }
  1639. /**
  1640. * Create a new prompt for getting user input through `enquirer`.
  1641. *
  1642. * - `enquirer` is a optional peer dependency and has to be already installed separately.
  1643. *
  1644. * @see {@link https://listr2.kilic.dev/task/prompt.html}
  1645. */
  1646. async prompt(options) {
  1647. return createPrompt.bind(this)(options, { ...this.options?.injectWrapper });
  1648. }
  1649. /* istanbul ignore next */
  1650. /**
  1651. * Cancel the current active prompt, if there is any.
  1652. *
  1653. * @see {@link https://listr2.kilic.dev/task/prompt.html}
  1654. */
  1655. cancelPrompt(options) {
  1656. if (!this.task.prompt || this.task.prompt instanceof PromptError) {
  1657. return;
  1658. }
  1659. if (options?.throw) {
  1660. this.task.prompt.cancel();
  1661. } else {
  1662. this.task.prompt.submit();
  1663. }
  1664. }
  1665. /**
  1666. * Generates a fake stdout for your use case, where it will be tunnelled through Listr to handle the rendering process.
  1667. *
  1668. * @see {@link https://listr2.kilic.dev/renderer/process-output.html}
  1669. */
  1670. stdout(type) {
  1671. return createWritable((chunk) => {
  1672. switch (type) {
  1673. case "PROMPT" /* PROMPT */:
  1674. this.promptOutput = chunk.toString();
  1675. break;
  1676. default:
  1677. this.output = chunk.toString();
  1678. }
  1679. });
  1680. }
  1681. /** Run this task. */
  1682. run(ctx) {
  1683. return this.task.run(ctx, this);
  1684. }
  1685. };
  1686. __name(_TaskWrapper, "TaskWrapper");
  1687. var TaskWrapper = _TaskWrapper;
  1688. // src/lib/task.ts
  1689. import { randomUUID } from "crypto";
  1690. import { Readable } from "stream";
  1691. // src/lib/listr-task-event-manager.ts
  1692. var _ListrTaskEventManager = class _ListrTaskEventManager extends EventManager {
  1693. };
  1694. __name(_ListrTaskEventManager, "ListrTaskEventManager");
  1695. var ListrTaskEventManager = _ListrTaskEventManager;
  1696. // src/lib/task.ts
  1697. var _Task = class _Task extends ListrTaskEventManager {
  1698. constructor(listr, task, options, rendererOptions) {
  1699. super();
  1700. this.listr = listr;
  1701. this.task = task;
  1702. this.options = options;
  1703. this.rendererOptions = rendererOptions;
  1704. /** Unique id per task, can be used for identifying a Task. */
  1705. this.id = randomUUID();
  1706. /** The current state of the task. */
  1707. this.state = "WAITING" /* WAITING */;
  1708. /**
  1709. * A channel for messages.
  1710. *
  1711. * This requires a separate channel for messages like error, skip or runtime messages to further utilize in the renderers.
  1712. */
  1713. this.message = {};
  1714. if (task.title) {
  1715. const title = Array.isArray(task?.title) ? task.title : [task.title];
  1716. this.title = splat(title.shift(), ...title);
  1717. this.initialTitle = this.title;
  1718. }
  1719. this.taskFn = task.task;
  1720. this.parent = listr.parentTask;
  1721. this.rendererTaskOptions = task.options;
  1722. }
  1723. /**
  1724. * Update the current state of the Task and emit the neccassary events.
  1725. */
  1726. set state$(state) {
  1727. this.state = state;
  1728. this.emit("STATE" /* STATE */, state);
  1729. if (this.hasSubtasks() && this.hasFailed()) {
  1730. for (const subtask of this.subtasks) {
  1731. if (subtask.state === "STARTED" /* STARTED */) {
  1732. subtask.state$ = "FAILED" /* FAILED */;
  1733. }
  1734. }
  1735. }
  1736. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1737. }
  1738. /**
  1739. * Update the current output of the Task and emit the neccassary events.
  1740. */
  1741. set output$(data) {
  1742. this.output = data;
  1743. this.emit("OUTPUT" /* OUTPUT */, data);
  1744. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1745. }
  1746. /**
  1747. * Update the current prompt output of the Task and emit the neccassary events.
  1748. */
  1749. set promptOutput$(data) {
  1750. this.emit("PROMPT" /* PROMPT */, data);
  1751. if (cleanseAnsi(data)) {
  1752. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1753. }
  1754. }
  1755. /**
  1756. * Update or extend the current message of the Task and emit the neccassary events.
  1757. */
  1758. set message$(data) {
  1759. this.message = { ...this.message, ...data };
  1760. this.emit("MESSAGE" /* MESSAGE */, data);
  1761. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1762. }
  1763. /**
  1764. * Update the current title of the Task and emit the neccassary events.
  1765. */
  1766. set title$(title) {
  1767. this.title = title;
  1768. this.emit("TITLE" /* TITLE */, title);
  1769. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1770. }
  1771. /**
  1772. * Current task path in the hierarchy.
  1773. */
  1774. get path() {
  1775. return [...this.listr.path, this.initialTitle];
  1776. }
  1777. /**
  1778. * Checks whether the current task with the given context should be set as enabled.
  1779. */
  1780. async check(ctx) {
  1781. if (this.state === "WAITING" /* WAITING */) {
  1782. this.enabled = await assertFunctionOrSelf(this.task?.enabled ?? true, ctx);
  1783. this.emit("ENABLED" /* ENABLED */, this.enabled);
  1784. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1785. }
  1786. return this.enabled;
  1787. }
  1788. /** Returns whether this task has subtasks. */
  1789. hasSubtasks() {
  1790. return this.subtasks?.length > 0;
  1791. }
  1792. /** Returns whether this task is finalized in someform. */
  1793. hasFinalized() {
  1794. return this.isCompleted() || this.hasFailed() || this.isSkipped() || this.hasRolledBack();
  1795. }
  1796. /** Returns whether this task is in progress. */
  1797. isPending() {
  1798. return this.isStarted() || this.isPrompt() || this.hasReset();
  1799. }
  1800. /** Returns whether this task has started. */
  1801. isStarted() {
  1802. return this.state === "STARTED" /* STARTED */;
  1803. }
  1804. /** Returns whether this task is skipped. */
  1805. isSkipped() {
  1806. return this.state === "SKIPPED" /* SKIPPED */;
  1807. }
  1808. /** Returns whether this task has been completed. */
  1809. isCompleted() {
  1810. return this.state === "COMPLETED" /* COMPLETED */;
  1811. }
  1812. /** Returns whether this task has been failed. */
  1813. hasFailed() {
  1814. return this.state === "FAILED" /* FAILED */;
  1815. }
  1816. /** Returns whether this task has an active rollback task going on. */
  1817. isRollingBack() {
  1818. return this.state === "ROLLING_BACK" /* ROLLING_BACK */;
  1819. }
  1820. /** Returns whether the rollback action was successful. */
  1821. hasRolledBack() {
  1822. return this.state === "ROLLED_BACK" /* ROLLED_BACK */;
  1823. }
  1824. /** Returns whether this task has an actively retrying task going on. */
  1825. isRetrying() {
  1826. return this.state === "RETRY" /* RETRY */;
  1827. }
  1828. /** Returns whether this task has some kind of reset like retry and rollback going on. */
  1829. hasReset() {
  1830. return this.state === "RETRY" /* RETRY */ || this.state === "ROLLING_BACK" /* ROLLING_BACK */;
  1831. }
  1832. /** Returns whether enabled function resolves to true. */
  1833. isEnabled() {
  1834. return this.enabled;
  1835. }
  1836. /** Returns whether this task actually has a title. */
  1837. hasTitle() {
  1838. return typeof this?.title === "string";
  1839. }
  1840. /** Returns whether this task has a prompt inside. */
  1841. isPrompt() {
  1842. return this.state === "PROMPT" /* PROMPT */ || this.state === "PROMPT_COMPLETED" /* PROMPT_COMPLETED */;
  1843. }
  1844. /** Returns whether this task is currently paused. */
  1845. isPaused() {
  1846. return this.state === "PAUSED" /* PAUSED */;
  1847. }
  1848. /** Returns whether this task is closed. */
  1849. isClosed() {
  1850. return this.closed;
  1851. }
  1852. /** Pause the given task for certain time. */
  1853. async pause(time) {
  1854. const state = this.state;
  1855. this.state$ = "PAUSED" /* PAUSED */;
  1856. this.message$ = {
  1857. paused: Date.now() + time
  1858. };
  1859. await delay(time);
  1860. this.state$ = state;
  1861. this.message$ = {
  1862. paused: null
  1863. };
  1864. }
  1865. /** Run the current task. */
  1866. async run(context, wrapper) {
  1867. const handleResult = /* @__PURE__ */ __name((result) => {
  1868. if (result instanceof Listr) {
  1869. result.options = { ...this.options, ...result.options };
  1870. result.rendererClass = getRendererClass("silent");
  1871. this.subtasks = result.tasks;
  1872. result.errors = this.listr.errors;
  1873. this.emit("SUBTASK" /* SUBTASK */, this.subtasks);
  1874. result = result.run(context);
  1875. } else if (result instanceof Promise) {
  1876. result = result.then(handleResult);
  1877. } else if (result instanceof Readable) {
  1878. result = new Promise((resolve, reject) => {
  1879. result.on("data", (data) => {
  1880. this.output$ = data.toString();
  1881. });
  1882. result.on("error", (error) => reject(error));
  1883. result.on("end", () => resolve(null));
  1884. });
  1885. } else if (isObservable(result)) {
  1886. result = new Promise((resolve, reject) => {
  1887. result.subscribe({
  1888. next: (data) => {
  1889. this.output$ = data;
  1890. },
  1891. error: reject,
  1892. complete: resolve
  1893. });
  1894. });
  1895. }
  1896. return result;
  1897. }, "handleResult");
  1898. const startTime = Date.now();
  1899. this.state$ = "STARTED" /* STARTED */;
  1900. const skipped = await assertFunctionOrSelf(this.task?.skip ?? false, context);
  1901. if (skipped) {
  1902. if (typeof skipped === "string") {
  1903. this.message$ = { skip: skipped };
  1904. } else if (this.hasTitle()) {
  1905. this.message$ = { skip: this.title };
  1906. } else {
  1907. this.message$ = { skip: "Skipped task without a title." };
  1908. }
  1909. this.state$ = "SKIPPED" /* SKIPPED */;
  1910. return;
  1911. }
  1912. try {
  1913. const retryCount = typeof this.task?.retry === "number" && this.task.retry > 0 ? this.task.retry + 1 : typeof this.task?.retry === "object" && this.task.retry.tries > 0 ? this.task.retry.tries + 1 : 1;
  1914. const retryDelay = typeof this.task.retry === "object" && this.task.retry.delay;
  1915. for (let retries = 1; retries <= retryCount; retries++) {
  1916. try {
  1917. await handleResult(this.taskFn(context, wrapper));
  1918. break;
  1919. } catch (err) {
  1920. if (retries !== retryCount) {
  1921. this.retry = { count: retries, error: err };
  1922. this.message$ = { retry: this.retry };
  1923. this.title$ = this.initialTitle;
  1924. this.output = void 0;
  1925. wrapper.report(err, "WILL_RETRY" /* WILL_RETRY */);
  1926. this.state$ = "RETRY" /* RETRY */;
  1927. if (retryDelay) {
  1928. await this.pause(retryDelay);
  1929. }
  1930. } else {
  1931. throw err;
  1932. }
  1933. }
  1934. }
  1935. if (this.isStarted() || this.isRetrying()) {
  1936. this.message$ = { duration: Date.now() - startTime };
  1937. this.state$ = "COMPLETED" /* COMPLETED */;
  1938. }
  1939. } catch (error) {
  1940. if (this.prompt instanceof PromptError) {
  1941. error = this.prompt;
  1942. }
  1943. if (this.task?.rollback) {
  1944. wrapper.report(error, "WILL_ROLLBACK" /* WILL_ROLLBACK */);
  1945. try {
  1946. this.state$ = "ROLLING_BACK" /* ROLLING_BACK */;
  1947. await this.task.rollback(context, wrapper);
  1948. this.message$ = { rollback: this.title };
  1949. this.state$ = "ROLLED_BACK" /* ROLLED_BACK */;
  1950. } catch (err) {
  1951. this.state$ = "FAILED" /* FAILED */;
  1952. wrapper.report(err, "HAS_FAILED_TO_ROLLBACK" /* HAS_FAILED_TO_ROLLBACK */);
  1953. this.close();
  1954. throw err;
  1955. }
  1956. if (this.listr.options?.exitAfterRollback !== false) {
  1957. this.close();
  1958. throw error;
  1959. }
  1960. } else {
  1961. this.state$ = "FAILED" /* FAILED */;
  1962. if (this.listr.options.exitOnError !== false && await assertFunctionOrSelf(this.task?.exitOnError, context) !== false) {
  1963. wrapper.report(error, "HAS_FAILED" /* HAS_FAILED */);
  1964. this.close();
  1965. throw error;
  1966. } else if (!this.hasSubtasks()) {
  1967. wrapper.report(error, "HAS_FAILED_WITHOUT_ERROR" /* HAS_FAILED_WITHOUT_ERROR */);
  1968. }
  1969. }
  1970. } finally {
  1971. this.close();
  1972. }
  1973. }
  1974. close() {
  1975. this.emit("CLOSED" /* CLOSED */);
  1976. this.listr.events.emit("SHOUD_REFRESH_RENDER" /* SHOULD_REFRESH_RENDER */);
  1977. this.complete();
  1978. }
  1979. };
  1980. __name(_Task, "Task");
  1981. var Task = _Task;
  1982. // src/lib/listr-event-manager.ts
  1983. var _ListrEventManager = class _ListrEventManager extends EventManager {
  1984. };
  1985. __name(_ListrEventManager, "ListrEventManager");
  1986. var ListrEventManager = _ListrEventManager;
  1987. // src/listr.ts
  1988. var _Listr = class _Listr {
  1989. constructor(task, options, parentTask) {
  1990. this.task = task;
  1991. this.options = options;
  1992. this.parentTask = parentTask;
  1993. this.tasks = [];
  1994. this.errors = [];
  1995. this.path = [];
  1996. this.options = {
  1997. concurrent: false,
  1998. renderer: "default",
  1999. fallbackRenderer: "simple",
  2000. exitOnError: true,
  2001. exitAfterRollback: true,
  2002. collectErrors: false,
  2003. registerSignalListeners: true,
  2004. ...this.parentTask?.options ?? {},
  2005. ...options
  2006. };
  2007. if (this.options.concurrent === true) {
  2008. this.options.concurrent = Infinity;
  2009. } else if (typeof this.options.concurrent !== "number") {
  2010. this.options.concurrent = 1;
  2011. }
  2012. this.concurrency = new Concurrency({ concurrency: this.options.concurrent });
  2013. if (parentTask) {
  2014. this.path = [...parentTask.listr.path, parentTask.title];
  2015. this.errors = parentTask.listr.errors;
  2016. }
  2017. if (this.parentTask?.listr.events instanceof ListrEventManager) {
  2018. this.events = this.parentTask.listr.events;
  2019. } else {
  2020. this.events = new ListrEventManager();
  2021. }
  2022. const renderer = getRenderer({
  2023. renderer: this.options.renderer,
  2024. rendererOptions: this.options.rendererOptions,
  2025. fallbackRenderer: this.options.fallbackRenderer,
  2026. fallbackRendererOptions: this.options.fallbackRendererOptions,
  2027. fallbackRendererCondition: this.options?.fallbackRendererCondition,
  2028. silentRendererCondition: this.options?.silentRendererCondition
  2029. });
  2030. this.rendererClass = renderer.renderer;
  2031. this.rendererClassOptions = renderer.options;
  2032. this.add(task ?? []);
  2033. if (this.options.registerSignalListeners) {
  2034. process.once("SIGINT", () => {
  2035. this.tasks.forEach(async (task2) => {
  2036. if (task2.isPending()) {
  2037. task2.state$ = "FAILED" /* FAILED */;
  2038. }
  2039. });
  2040. this.renderer.end(new Error("Interrupted."));
  2041. process.exit(127);
  2042. }).setMaxListeners(0);
  2043. }
  2044. if (this.options?.disableColor) {
  2045. process.env["LISTR_DISABLE_COLOR" /* DISABLE_COLOR */] = "1";
  2046. } else if (this.options?.forceColor) {
  2047. process.env["FORCE_COLOR" /* FORCE_COLOR */] = "1";
  2048. }
  2049. if (this.options?.forceTTY) {
  2050. process.stdout.isTTY = true;
  2051. process.stderr.isTTY = true;
  2052. }
  2053. if (this.options?.forceUnicode) {
  2054. process.env["LISTR_FORCE_UNICODE" /* FORCE_UNICODE */] = "1";
  2055. }
  2056. }
  2057. add(tasks) {
  2058. this.tasks.push(...this.generate(tasks));
  2059. }
  2060. async run(context) {
  2061. if (!this.renderer) {
  2062. this.renderer = new this.rendererClass(this.tasks, this.rendererClassOptions, this.events);
  2063. }
  2064. await this.renderer.render();
  2065. this.ctx = this.options?.ctx ?? context ?? {};
  2066. await Promise.all(this.tasks.map((task) => task.check(this.ctx)));
  2067. try {
  2068. await Promise.all(this.tasks.map((task) => this.concurrency.add(() => this.runTask(task))));
  2069. this.renderer.end();
  2070. } catch (err) {
  2071. if (this.options.exitOnError !== false) {
  2072. this.renderer.end(err);
  2073. throw err;
  2074. }
  2075. }
  2076. return this.ctx;
  2077. }
  2078. generate(tasks) {
  2079. tasks = Array.isArray(tasks) ? tasks : [tasks];
  2080. return tasks.map((task) => new Task(this, task, this.options, { ...this.rendererClassOptions }));
  2081. }
  2082. async runTask(task) {
  2083. if (!await task.check(this.ctx)) {
  2084. return;
  2085. }
  2086. return new TaskWrapper(task, this.options).run(this.ctx);
  2087. }
  2088. };
  2089. __name(_Listr, "Listr");
  2090. var Listr = _Listr;
  2091. // src/manager.ts
  2092. var _Manager = class _Manager {
  2093. constructor(options) {
  2094. this.options = options;
  2095. this.errors = [];
  2096. this.tasks = [];
  2097. }
  2098. get ctx() {
  2099. return this.options.ctx;
  2100. }
  2101. set ctx(ctx) {
  2102. this.options.ctx = ctx;
  2103. }
  2104. add(tasks, options) {
  2105. options = { ...this.options, ...options };
  2106. this.tasks = [...this.tasks, this.indent(tasks, options)];
  2107. }
  2108. async runAll(options) {
  2109. options = { ...this.options, ...options };
  2110. const tasks = [...this.tasks];
  2111. this.tasks = [];
  2112. const ctx = await this.run(tasks, options);
  2113. return ctx;
  2114. }
  2115. newListr(tasks, options) {
  2116. return new Listr(tasks, options);
  2117. }
  2118. indent(tasks, options, taskOptions) {
  2119. options = { ...this.options, ...options };
  2120. if (typeof tasks === "function") {
  2121. return {
  2122. ...taskOptions,
  2123. task: (ctx) => this.newListr(tasks(ctx), options)
  2124. };
  2125. }
  2126. return {
  2127. ...taskOptions,
  2128. task: () => this.newListr(tasks, options)
  2129. };
  2130. }
  2131. async run(tasks, options) {
  2132. options = { ...this.options, ...options };
  2133. const task = this.newListr(tasks, options);
  2134. const ctx = await task.run();
  2135. this.errors.push(...task.errors);
  2136. return ctx;
  2137. }
  2138. };
  2139. __name(_Manager, "Manager");
  2140. var Manager = _Manager;
  2141. export {
  2142. ANSI_ESCAPE,
  2143. ANSI_ESCAPE_CODES,
  2144. BaseEventMap,
  2145. Concurrency,
  2146. DefaultRenderer,
  2147. EventManager,
  2148. LISTR_DEFAULT_RENDERER_STYLE,
  2149. LISTR_LOGGER_STDERR_LEVELS,
  2150. LISTR_LOGGER_STYLE,
  2151. Listr,
  2152. ListrDefaultRendererLogLevels,
  2153. ListrEnvironmentVariables,
  2154. ListrError,
  2155. ListrErrorTypes,
  2156. ListrEventManager,
  2157. ListrEventType,
  2158. ListrLogLevels,
  2159. ListrLogger,
  2160. ListrRendererError,
  2161. ListrTaskEventManager,
  2162. ListrTaskEventType,
  2163. ListrTaskState,
  2164. Manager,
  2165. PRESET_TIMER,
  2166. PRESET_TIMESTAMP,
  2167. ProcessOutput,
  2168. ProcessOutputBuffer,
  2169. ProcessOutputStream,
  2170. PromptError,
  2171. SilentRenderer,
  2172. SimpleRenderer,
  2173. Spinner,
  2174. TestRenderer,
  2175. TestRendererSerializer,
  2176. VerboseRenderer,
  2177. assertFunctionOrSelf,
  2178. cleanseAnsi,
  2179. cloneObject,
  2180. color,
  2181. createPrompt,
  2182. createWritable,
  2183. delay,
  2184. figures,
  2185. getRenderer,
  2186. getRendererClass,
  2187. indent,
  2188. isObservable,
  2189. isUnicodeSupported,
  2190. parseTimer,
  2191. parseTimestamp,
  2192. splat
  2193. };