@kubb/cli 5.0.0-beta.2 → 5.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/README.md +177 -26
  2. package/dist/agent-CjtFcQSP.js +68 -0
  3. package/dist/agent-CjtFcQSP.js.map +1 -0
  4. package/dist/agent-ImlBMmqx.cjs +70 -0
  5. package/dist/agent-ImlBMmqx.cjs.map +1 -0
  6. package/dist/{chunk--u3MIqq1.js → chunk-BvFE5Tac.js} +1 -0
  7. package/dist/constants-B2JTeRBb.js +42 -0
  8. package/dist/constants-B2JTeRBb.js.map +1 -0
  9. package/dist/constants-BINTA5VZ.cjs +77 -0
  10. package/dist/constants-BINTA5VZ.cjs.map +1 -0
  11. package/dist/constants-BYGmiFs0.cjs +139 -0
  12. package/dist/constants-BYGmiFs0.cjs.map +1 -0
  13. package/dist/constants-DSJ-Xrbv.js +116 -0
  14. package/dist/constants-DSJ-Xrbv.js.map +1 -0
  15. package/dist/define-Bdn8j5VM.cjs.map +1 -1
  16. package/dist/{define-Ctii4bel.js → define-m_fp-Aqm.js} +2 -2
  17. package/dist/{define-Ctii4bel.js.map → define-m_fp-Aqm.js.map} +1 -1
  18. package/dist/{errors-CjPmyZHy.js → errors-CINO1EIv.js} +2 -2
  19. package/dist/{errors-CjPmyZHy.js.map → errors-CINO1EIv.js.map} +1 -1
  20. package/dist/errors-CLCjoSg0.cjs.map +1 -1
  21. package/dist/{generate-DL_7a7Wd.cjs → generate-BzD-zvO8.cjs} +10 -4
  22. package/dist/generate-BzD-zvO8.cjs.map +1 -0
  23. package/dist/{generate-B3PZ6Dp-.js → generate-DMjDB40_.js} +12 -6
  24. package/dist/generate-DMjDB40_.js.map +1 -0
  25. package/dist/index.cjs +20 -11
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +22 -13
  29. package/dist/index.js.map +1 -1
  30. package/dist/init-DSUkgcQb.js +53 -0
  31. package/dist/init-DSUkgcQb.js.map +1 -0
  32. package/dist/init-DTtYizXX.cjs +53 -0
  33. package/dist/init-DTtYizXX.cjs.map +1 -0
  34. package/dist/mcp-WXRUaZnw.cjs +39 -0
  35. package/dist/mcp-WXRUaZnw.cjs.map +1 -0
  36. package/dist/mcp-mW5bt29k.js +39 -0
  37. package/dist/mcp-mW5bt29k.js.map +1 -0
  38. package/dist/package-B1xAdhcK.js +6 -0
  39. package/dist/package-B1xAdhcK.js.map +1 -0
  40. package/dist/{package-D8wlStAg.cjs → package-CxbQOn_j.cjs} +2 -2
  41. package/dist/package-CxbQOn_j.cjs.map +1 -0
  42. package/dist/run-B11-UaUs.cjs +33 -0
  43. package/dist/run-B11-UaUs.cjs.map +1 -0
  44. package/dist/{init-eNRlotJK.js → run-BNqMQygv.js} +107 -149
  45. package/dist/run-BNqMQygv.js.map +1 -0
  46. package/dist/{generate-B3jl4ukb.cjs → run-BP_t4Z6z.cjs} +472 -397
  47. package/dist/run-BP_t4Z6z.cjs.map +1 -0
  48. package/dist/{init-CZ5Xq2Hd.cjs → run-BnGfi7Cp.cjs} +105 -147
  49. package/dist/run-BnGfi7Cp.cjs.map +1 -0
  50. package/dist/{agent-Ev5hU5hH.js → run-BzpYYOQs.js} +53 -44
  51. package/dist/run-BzpYYOQs.js.map +1 -0
  52. package/dist/run-CCZ24VKk.js +51 -0
  53. package/dist/run-CCZ24VKk.js.map +1 -0
  54. package/dist/{generate-Dt_r0ELY.js → run-CM9IkB_6.js} +475 -400
  55. package/dist/run-CM9IkB_6.js.map +1 -0
  56. package/dist/run-CQbj3ley.cjs +52 -0
  57. package/dist/run-CQbj3ley.cjs.map +1 -0
  58. package/dist/{agent-B_pirbeB.cjs → run-DwdAwnLG.cjs} +51 -42
  59. package/dist/run-DwdAwnLG.cjs.map +1 -0
  60. package/dist/run-PSA9X7ci.js +32 -0
  61. package/dist/run-PSA9X7ci.js.map +1 -0
  62. package/dist/shell-475fQKaX.cjs.map +1 -1
  63. package/dist/{shell-DLzN4fRo.js → shell-CN6DNqeC.js} +2 -2
  64. package/dist/{shell-DLzN4fRo.js.map → shell-CN6DNqeC.js.map} +1 -1
  65. package/dist/{telemetry-DN95_2pF.cjs → telemetry-B2iWkY5e.cjs} +5 -7
  66. package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
  67. package/dist/{telemetry-LgT_sdPe.js → telemetry-BkektVz6.js} +6 -8
  68. package/dist/telemetry-BkektVz6.js.map +1 -0
  69. package/dist/validate-BQxNrR5z.js +26 -0
  70. package/dist/validate-BQxNrR5z.js.map +1 -0
  71. package/dist/validate-CvFVXmSa.cjs +26 -0
  72. package/dist/validate-CvFVXmSa.cjs.map +1 -0
  73. package/package.json +23 -15
  74. package/src/commands/agent/start.ts +10 -7
  75. package/src/commands/agent.ts +3 -1
  76. package/src/commands/generate.ts +5 -3
  77. package/src/commands/init.ts +34 -3
  78. package/src/commands/mcp.ts +28 -4
  79. package/src/commands/validate.ts +6 -4
  80. package/src/constants.ts +2 -58
  81. package/src/index.ts +5 -3
  82. package/src/loggers/clackLogger.ts +66 -72
  83. package/src/loggers/fileSystemLogger.ts +26 -13
  84. package/src/loggers/githubActionsLogger.ts +72 -26
  85. package/src/loggers/plainLogger.ts +51 -26
  86. package/src/loggers/types.ts +6 -0
  87. package/src/loggers/utils.ts +158 -9
  88. package/src/runners/agent/run.ts +113 -0
  89. package/src/runners/agent/utils.ts +98 -0
  90. package/src/runners/generate/run.ts +316 -0
  91. package/src/runners/generate/utils.ts +216 -0
  92. package/src/runners/init/run.ts +212 -0
  93. package/src/{utils/packageManager.ts → runners/init/utils.ts} +10 -0
  94. package/src/runners/mcp/run.ts +37 -0
  95. package/src/runners/validate/run.ts +63 -0
  96. package/src/{utils/telemetry.ts → telemetry.ts} +12 -5
  97. package/dist/agent-0Nk--lcr.cjs +0 -58
  98. package/dist/agent-0Nk--lcr.cjs.map +0 -1
  99. package/dist/agent-B_pirbeB.cjs.map +0 -1
  100. package/dist/agent-DKeVuiUC.js +0 -56
  101. package/dist/agent-DKeVuiUC.js.map +0 -1
  102. package/dist/agent-Ev5hU5hH.js.map +0 -1
  103. package/dist/constants-CnDXa1R6.cjs +0 -148
  104. package/dist/constants-CnDXa1R6.cjs.map +0 -1
  105. package/dist/constants-aL3CP_Wq.js +0 -95
  106. package/dist/constants-aL3CP_Wq.js.map +0 -1
  107. package/dist/generate-B3PZ6Dp-.js.map +0 -1
  108. package/dist/generate-B3jl4ukb.cjs.map +0 -1
  109. package/dist/generate-DL_7a7Wd.cjs.map +0 -1
  110. package/dist/generate-Dt_r0ELY.js.map +0 -1
  111. package/dist/init-Bj94Nvt8.js +0 -25
  112. package/dist/init-Bj94Nvt8.js.map +0 -1
  113. package/dist/init-CZ5Xq2Hd.cjs.map +0 -1
  114. package/dist/init-CyN1oyTF.cjs +0 -25
  115. package/dist/init-CyN1oyTF.cjs.map +0 -1
  116. package/dist/init-eNRlotJK.js.map +0 -1
  117. package/dist/mcp-BzW703d7.js +0 -16
  118. package/dist/mcp-BzW703d7.js.map +0 -1
  119. package/dist/mcp-CLcDV4Jm.cjs +0 -41
  120. package/dist/mcp-CLcDV4Jm.cjs.map +0 -1
  121. package/dist/mcp-D7EIR9fR.js +0 -40
  122. package/dist/mcp-D7EIR9fR.js.map +0 -1
  123. package/dist/mcp-ZY-ONTOp.cjs +0 -16
  124. package/dist/mcp-ZY-ONTOp.cjs.map +0 -1
  125. package/dist/package-D8wlStAg.cjs.map +0 -1
  126. package/dist/package-Yo-9_m5C.js +0 -6
  127. package/dist/package-Yo-9_m5C.js.map +0 -1
  128. package/dist/telemetry-DN95_2pF.cjs.map +0 -1
  129. package/dist/telemetry-LgT_sdPe.js.map +0 -1
  130. package/dist/validate-Dplr99xO.js +0 -25
  131. package/dist/validate-Dplr99xO.js.map +0 -1
  132. package/dist/validate-_8mBa63G.cjs +0 -25
  133. package/dist/validate-_8mBa63G.cjs.map +0 -1
  134. package/dist/validate-kLJoT_hi.js +0 -33
  135. package/dist/validate-kLJoT_hi.js.map +0 -1
  136. package/dist/validate-yKKzqEZ5.cjs +0 -34
  137. package/dist/validate-yKKzqEZ5.cjs.map +0 -1
  138. package/src/runners/agent.ts +0 -149
  139. package/src/runners/generate.ts +0 -333
  140. package/src/runners/init.ts +0 -296
  141. package/src/runners/mcp.ts +0 -45
  142. package/src/runners/validate.ts +0 -39
  143. package/src/types.ts +0 -11
  144. package/src/utils/Writables.ts +0 -17
  145. package/src/utils/executeHooks.ts +0 -45
  146. package/src/utils/flags.ts +0 -9
  147. package/src/utils/getConfig.ts +0 -10
  148. package/src/utils/getCosmiConfig.ts +0 -80
  149. package/src/utils/getSummary.ts +0 -68
  150. package/src/utils/runHook.ts +0 -91
  151. package/src/utils/watcher.ts +0 -19
@@ -1,9 +1,9 @@
1
1
  const require_chunk = require("./chunk-ByKO4r7w.cjs");
2
2
  const require_errors = require("./errors-CLCjoSg0.cjs");
3
- const require_telemetry = require("./telemetry-DN95_2pF.cjs");
3
+ const require_telemetry = require("./telemetry-B2iWkY5e.cjs");
4
4
  const require_shell = require("./shell-475fQKaX.cjs");
5
- const require_package = require("./package-D8wlStAg.cjs");
6
- const require_constants = require("./constants-CnDXa1R6.cjs");
5
+ const require_package = require("./package-CxbQOn_j.cjs");
6
+ const require_constants = require("./constants-BINTA5VZ.cjs");
7
7
  let node_util = require("node:util");
8
8
  let node_events = require("node:events");
9
9
  let node_crypto = require("node:crypto");
@@ -17,10 +17,9 @@ node_process = require_chunk.__toESM(node_process, 1);
17
17
  let _clack_prompts = require("@clack/prompts");
18
18
  _clack_prompts = require_chunk.__toESM(_clack_prompts, 1);
19
19
  let _kubb_core = require("@kubb/core");
20
- let tinyexec = require("tinyexec");
21
- let node_stream = require("node:stream");
22
20
  let cosmiconfig = require("cosmiconfig");
23
- let unrun = require("unrun");
21
+ let jiti = require("jiti");
22
+ let tinyexec = require("tinyexec");
24
23
  //#region ../../internals/utils/src/asyncEventEmitter.ts
25
24
  /**
26
25
  * Typed `EventEmitter` that awaits all async listeners before resolving.
@@ -51,9 +50,12 @@ var AsyncEventEmitter = class {
51
50
  * await emitter.emit('build', 'petstore')
52
51
  * ```
53
52
  */
54
- async emit(eventName, ...eventArgs) {
53
+ emit(eventName, ...eventArgs) {
55
54
  const listeners = this.#emitter.listeners(eventName);
56
55
  if (listeners.length === 0) return;
56
+ return this.#emitAll(eventName, listeners, eventArgs);
57
+ }
58
+ async #emitAll(eventName, listeners, eventArgs) {
57
59
  for (const listener of listeners) try {
58
60
  await listener(...eventArgs);
59
61
  } catch (err) {
@@ -489,112 +491,6 @@ async function detectLinter() {
489
491
  return null;
490
492
  }
491
493
  //#endregion
492
- //#region src/utils/getSummary.ts
493
- function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
494
- const duration = formatHrtime(hrStart);
495
- const pluginsCount = config.plugins?.length ?? 0;
496
- const successCount = pluginsCount - failedPlugins.size;
497
- const meta = {
498
- plugins: status === "success" ? `${(0, node_util.styleText)("green", `${successCount} successful`)}, ${pluginsCount} total` : `${(0, node_util.styleText)("green", `${successCount} successful`)}, ${(0, node_util.styleText)("red", `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
499
- pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
500
- filesCreated,
501
- time: (0, node_util.styleText)("green", duration),
502
- output: node_path.default.resolve(config.root, config.output.path)
503
- };
504
- const labels = {
505
- plugins: "Plugins:",
506
- failed: "Failed:",
507
- generated: "Generated:",
508
- pluginTimings: "Plugin Timings:",
509
- output: "Output:"
510
- };
511
- const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
512
- const summaryLines = [];
513
- summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
514
- if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
515
- summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
516
- if (pluginTimings && pluginTimings.size > 0) {
517
- const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
518
- summaryLines.push(`${labels.pluginTimings}`);
519
- sortedTimings.forEach(([name, time]) => {
520
- const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
521
- const barLength = Math.min(Math.ceil(time / 100), 10);
522
- const bar = (0, node_util.styleText)("dim", "█".repeat(barLength));
523
- summaryLines.push(`${(0, node_util.styleText)("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
524
- });
525
- }
526
- summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
527
- return summaryLines;
528
- }
529
- //#endregion
530
- //#region src/utils/runHook.ts
531
- /**
532
- * Executes a hook command, emits debug and completion events, and forwards output to an optional sink.
533
- */
534
- async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
535
- try {
536
- const proc = (0, tinyexec.x)(command, [...args ?? []], {
537
- nodeOptions: { detached: process.platform !== "win32" },
538
- throwOnError: true
539
- });
540
- if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
541
- const result = await proc;
542
- await context.emit("kubb:debug", {
543
- date: /* @__PURE__ */ new Date(),
544
- logs: [result.stdout.trimEnd()]
545
- });
546
- await context.emit("kubb:hook:end", {
547
- command,
548
- args,
549
- id,
550
- success: true,
551
- error: null
552
- });
553
- } catch (err) {
554
- if (!(err instanceof tinyexec.NonZeroExitError)) {
555
- await context.emit("kubb:hook:end", {
556
- command,
557
- args,
558
- id,
559
- success: false,
560
- error: require_errors.toError(err)
561
- });
562
- await context.emit("kubb:error", { error: require_errors.toError(err) });
563
- return;
564
- }
565
- const stderr = err.output?.stderr ?? "";
566
- const stdout = err.output?.stdout ?? "";
567
- await context.emit("kubb:debug", {
568
- date: /* @__PURE__ */ new Date(),
569
- logs: [stdout, stderr].filter(Boolean)
570
- });
571
- if (stderr) sink?.onStderr?.(stderr);
572
- if (stdout) sink?.onStdout?.(stdout);
573
- const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
574
- await context.emit("kubb:hook:end", {
575
- command,
576
- args,
577
- id,
578
- success: false,
579
- error: errorMessage
580
- });
581
- await context.emit("kubb:error", { error: errorMessage });
582
- }
583
- }
584
- //#endregion
585
- //#region src/utils/Writables.ts
586
- var ClackWritable = class extends node_stream.Writable {
587
- taskLog;
588
- constructor(taskLog, opts) {
589
- super(opts);
590
- this.taskLog = taskLog;
591
- }
592
- _write(chunk, _encoding, callback) {
593
- this.taskLog.message(`${(0, node_util.styleText)("dim", chunk.toString())}`);
594
- callback();
595
- }
596
- };
597
- //#endregion
598
494
  //#region src/loggers/clackLogger.ts
599
495
  /**
600
496
  * TTY logger with beautiful UI and progress indicators for local development.
@@ -612,7 +508,8 @@ const clackLogger = (0, _kubb_core.defineLogger)({
612
508
  hrStart: node_process.default.hrtime(),
613
509
  spinner: _clack_prompts.spinner(),
614
510
  isSpinning: false,
615
- activeProgress: /* @__PURE__ */ new Map()
511
+ activeProgress: /* @__PURE__ */ new Map(),
512
+ activeHookLogs: /* @__PURE__ */ new Map()
616
513
  };
617
514
  function reset() {
618
515
  for (const [_key, active] of state.activeProgress) {
@@ -628,6 +525,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
628
525
  state.spinner = _clack_prompts.spinner();
629
526
  state.isSpinning = false;
630
527
  state.activeProgress.clear();
528
+ state.activeHookLogs.clear();
631
529
  }
632
530
  function showProgressStep() {
633
531
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -642,6 +540,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
642
540
  state.isSpinning = true;
643
541
  }
644
542
  function stopSpinner(text) {
543
+ if (!state.isSpinning) return;
645
544
  state.spinner.stop(text);
646
545
  state.isSpinning = false;
647
546
  }
@@ -652,8 +551,11 @@ const clackLogger = (0, _kubb_core.defineLogger)({
652
551
  message,
653
552
  (0, node_util.styleText)("dim", info)
654
553
  ].join(" "));
655
- if (state.isSpinning) state.spinner.message(text);
656
- else _clack_prompts.log.info(text);
554
+ if (state.isSpinning) {
555
+ state.spinner.message(text);
556
+ return;
557
+ }
558
+ _clack_prompts.log.info(text);
657
559
  });
658
560
  context.on("kubb:success", ({ message, info = "" }) => {
659
561
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -662,8 +564,11 @@ const clackLogger = (0, _kubb_core.defineLogger)({
662
564
  message,
663
565
  logLevel >= _kubb_core.logLevel.info ? (0, node_util.styleText)("dim", info) : void 0
664
566
  ].filter(Boolean).join(" "));
665
- if (state.isSpinning) stopSpinner(text);
666
- else _clack_prompts.log.success(text);
567
+ if (state.isSpinning) {
568
+ stopSpinner(text);
569
+ return;
570
+ }
571
+ _clack_prompts.log.success(text);
667
572
  });
668
573
  context.on("kubb:warn", ({ message, info }) => {
669
574
  if (logLevel < _kubb_core.logLevel.warn) return;
@@ -677,8 +582,11 @@ const clackLogger = (0, _kubb_core.defineLogger)({
677
582
  context.on("kubb:error", ({ error }) => {
678
583
  const caused = require_errors.toCause(error);
679
584
  const text = [(0, node_util.styleText)("red", "✗"), error.message].join(" ");
680
- if (state.isSpinning) stopSpinner(getMessage(text));
681
- else _clack_prompts.log.error(getMessage(text));
585
+ if (state.isSpinning) {
586
+ stopSpinner(getMessage(text));
587
+ return;
588
+ }
589
+ _clack_prompts.log.error(getMessage(text));
682
590
  if (logLevel >= _kubb_core.logLevel.debug && error.stack) {
683
591
  const frames = error.stack.split("\n").slice(1, 4);
684
592
  for (const frame of frames) _clack_prompts.log.message(getMessage((0, node_util.styleText)("dim", frame.trim())));
@@ -729,6 +637,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
729
637
  context.on("kubb:generation:start", ({ config }) => {
730
638
  reset();
731
639
  state.totalPlugins = config.plugins?.length ?? 0;
640
+ if (logLevel <= _kubb_core.logLevel.silent) return;
732
641
  const text = getMessage(["Generation started", config.name ? `for ${(0, node_util.styleText)("dim", config.name)}` : void 0].filter(Boolean).join(" "));
733
642
  _clack_prompts.intro(text);
734
643
  });
@@ -798,68 +707,44 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
798
707
  showProgressStep();
799
708
  });
800
709
  context.on("kubb:generation:end", ({ config }) => {
710
+ stopSpinner();
801
711
  const text = getMessage(config.name ? `Generation completed for ${(0, node_util.styleText)("dim", config.name)}` : "Generation completed");
802
712
  _clack_prompts.outro(text);
803
713
  });
804
714
  context.on("kubb:format:start", () => {
805
715
  if (logLevel <= _kubb_core.logLevel.silent) return;
806
- const text = getMessage("Format started");
807
- _clack_prompts.intro(text);
808
- });
809
- context.on("kubb:format:end", () => {
810
- if (logLevel <= _kubb_core.logLevel.silent) return;
811
- const text = getMessage("Format completed");
812
- _clack_prompts.outro(text);
716
+ _clack_prompts.log.step(getMessage("Formatting"));
813
717
  });
814
718
  context.on("kubb:lint:start", () => {
815
719
  if (logLevel <= _kubb_core.logLevel.silent) return;
816
- const text = getMessage("Lint started");
817
- _clack_prompts.intro(text);
720
+ _clack_prompts.log.step(getMessage("Linting"));
818
721
  });
819
- context.on("kubb:lint:end", () => {
722
+ context.on("kubb:hooks:start", () => {
820
723
  if (logLevel <= _kubb_core.logLevel.silent) return;
821
- const text = getMessage("Lint completed");
822
- _clack_prompts.outro(text);
724
+ _clack_prompts.log.step(getMessage("Running hooks"));
823
725
  });
824
- context.on("kubb:hook:start", async ({ id, command, args }) => {
825
- const commandWithArgs = formatCommandWithArgs(command, args);
826
- const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} started`);
827
- if (!id) return;
828
- if (logLevel <= _kubb_core.logLevel.silent) {
829
- await runHook({
830
- id,
831
- command,
832
- args,
833
- commandWithArgs,
834
- context,
835
- sink: {
836
- onStderr: (s) => console.error(s),
837
- onStdout: (s) => console.log(s)
838
- }
839
- });
840
- return;
841
- }
842
- _clack_prompts.intro(text);
843
- const logger = _clack_prompts.taskLog({ title: getMessage(["Executing hook", logLevel >= _kubb_core.logLevel.info ? (0, node_util.styleText)("dim", commandWithArgs) : void 0].filter(Boolean).join(" ")) });
844
- const writable = new ClackWritable(logger);
845
- await runHook({
846
- id,
847
- command,
848
- args,
849
- commandWithArgs,
850
- context,
851
- stream: true,
852
- sink: {
853
- onLine: (line) => writable.write(line),
854
- onStderr: (s) => logger.error(s),
855
- onStdout: (s) => logger.message(s)
856
- }
726
+ context.on("kubb:hook:start", ({ id, command, args }) => {
727
+ if (logLevel <= _kubb_core.logLevel.silent || !id) return;
728
+ stopSpinner();
729
+ const title = getMessage(`Running ${(0, node_util.styleText)("dim", formatCommandWithArgs(command, args))}`);
730
+ const taskLog = _clack_prompts.taskLog({ title });
731
+ state.activeHookLogs.set(id, {
732
+ taskLog,
733
+ hrStart: node_process.default.hrtime()
857
734
  });
858
735
  });
859
- context.on("kubb:hook:end", ({ command, args }) => {
860
- if (logLevel <= _kubb_core.logLevel.silent) return;
861
- const text = getMessage(`Hook ${(0, node_util.styleText)("dim", formatCommandWithArgs(command, args))} successfully executed`);
862
- _clack_prompts.outro(text);
736
+ context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
737
+ if (logLevel <= _kubb_core.logLevel.silent || !id) return;
738
+ const active = state.activeHookLogs.get(id);
739
+ if (!active) return;
740
+ state.activeHookLogs.delete(id);
741
+ const commandWithArgs = formatCommandWithArgs(command, args);
742
+ const duration = formatMsWithColor(getElapsedMs(active.hrStart));
743
+ if (success) active.taskLog.success(getMessage(`${(0, node_util.styleText)("dim", commandWithArgs)} completed in ${duration}`));
744
+ else {
745
+ const reason = error?.message ? ` (${error.message})` : "";
746
+ active.taskLog.error(getMessage(`${(0, node_util.styleText)("dim", commandWithArgs)} failed${reason}`), { showLog: true });
747
+ }
863
748
  });
864
749
  context.on("kubb:generation:summary", ({ config, pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
865
750
  const summary = getSummary({
@@ -890,13 +775,29 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
890
775
  context.on("kubb:lifecycle:end", () => {
891
776
  reset();
892
777
  });
778
+ return (_commandWithArgs, hookId) => {
779
+ if (logLevel <= _kubb_core.logLevel.silent) return {
780
+ onStdout: (s) => console.log(s),
781
+ onStderr: (s) => console.error(s)
782
+ };
783
+ const active = state.activeHookLogs.get(hookId);
784
+ if (!active) return;
785
+ const { taskLog } = active;
786
+ return {
787
+ stream: true,
788
+ onLine: (line) => taskLog.message((0, node_util.styleText)("dim", line)),
789
+ onStdout: (s) => taskLog.message(s),
790
+ onStderr: (s) => taskLog.message((0, node_util.styleText)("red", s))
791
+ };
792
+ };
893
793
  }
894
794
  });
895
795
  //#endregion
896
796
  //#region src/loggers/fileSystemLogger.ts
897
797
  /**
898
798
  * FileSystem logger that captures debug events and writes them to `.kubb` directory files.
899
- * Note: Logs write on `lifecycle:end` or process exit. Cached logs may be lost if the process crashes before these events.
799
+ *
800
+ * @note Logs are written on `kubb:lifecycle:end` or process exit. Cached logs may be lost if the process crashes before either event.
900
801
  */
901
802
  const fileSystemLogger = (0, _kubb_core.defineLogger)({
902
803
  name: "filesystem",
@@ -921,29 +822,31 @@ const fileSystemLogger = (0, _kubb_core.defineLogger)({
921
822
  const pathName = (0, node_path.resolve)(node_process.default.cwd(), ".kubb", baseName);
922
823
  if (!files[pathName]) files[pathName] = [];
923
824
  if (log.logs.length > 0) {
924
- const timestamp = log.date.toLocaleString();
925
- files[pathName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
825
+ const prefix = `[${log.date.toLocaleString()}] `;
826
+ const indent = " ".repeat(prefix.length);
827
+ const [first, ...rest] = log.logs;
828
+ files[pathName].push([prefix + first, ...rest.map((line) => indent + line)].join("\n"));
926
829
  }
927
830
  }
928
- for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n\n"));
831
+ for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n"));
929
832
  return Object.keys(files);
930
833
  }
931
834
  context.on("kubb:info", ({ message, info }) => {
932
835
  state.cachedLogs.add({
933
836
  date: /* @__PURE__ */ new Date(),
934
- logs: [`ℹ ${message} ${info}`]
837
+ logs: [`ℹ ${[message, info].filter(Boolean).join(" ")}`]
935
838
  });
936
839
  });
937
840
  context.on("kubb:success", ({ message, info }) => {
938
841
  state.cachedLogs.add({
939
842
  date: /* @__PURE__ */ new Date(),
940
- logs: [`✓ ${message} ${info}`]
843
+ logs: [`✓ ${[message, info].filter(Boolean).join(" ")}`]
941
844
  });
942
845
  });
943
846
  context.on("kubb:warn", ({ message, info }) => {
944
847
  state.cachedLogs.add({
945
848
  date: /* @__PURE__ */ new Date(),
946
- logs: [`⚠ ${message} ${info}`]
849
+ logs: [`⚠ ${[message, info].filter(Boolean).join(" ")}`]
947
850
  });
948
851
  });
949
852
  context.on("kubb:error", ({ error }) => {
@@ -952,29 +855,30 @@ const fileSystemLogger = (0, _kubb_core.defineLogger)({
952
855
  logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
953
856
  });
954
857
  });
955
- context.on("kubb:debug", (message) => {
858
+ context.on("kubb:debug", ({ date, fileName, logs }) => {
956
859
  state.cachedLogs.add({
957
- date: /* @__PURE__ */ new Date(),
958
- logs: message.logs
860
+ date,
861
+ fileName,
862
+ logs
959
863
  });
960
864
  });
961
865
  context.on("kubb:plugin:start", ({ plugin }) => {
962
866
  state.cachedLogs.add({
963
867
  date: /* @__PURE__ */ new Date(),
964
- logs: [`Generating ${plugin.name}`]
868
+ logs: [`► Generating ${plugin.name}`]
965
869
  });
966
870
  });
967
871
  context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
968
872
  const durationStr = formatMs(duration);
969
873
  state.cachedLogs.add({
970
874
  date: /* @__PURE__ */ new Date(),
971
- logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`]
875
+ logs: [success ? `✓ ${plugin.name} completed in ${durationStr}` : `✗ ${plugin.name} failed in ${durationStr}`]
972
876
  });
973
877
  });
974
878
  context.on("kubb:files:processing:start", ({ files }) => {
975
879
  state.cachedLogs.add({
976
880
  date: /* @__PURE__ */ new Date(),
977
- logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)]
881
+ logs: [`► Writing ${files.length} files`, ...files.map((file) => ` ${file.path}`)]
978
882
  });
979
883
  });
980
884
  context.on("kubb:generation:end", async ({ config }) => {
@@ -1011,17 +915,21 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1011
915
  failedPlugins: 0,
1012
916
  totalFiles: 0,
1013
917
  processedFiles: 0,
1014
- hrStart: process.hrtime(),
1015
- currentConfigs: []
918
+ hrStart: node_process.default.hrtime(),
919
+ currentConfigs: [],
920
+ hookStarts: /* @__PURE__ */ new Map(),
921
+ openGroupDepth: 0
1016
922
  };
1017
923
  function reset() {
924
+ closeAllGroups();
1018
925
  state.totalPlugins = 0;
1019
926
  state.completedPlugins = 0;
1020
927
  state.failedPlugins = 0;
1021
928
  state.totalFiles = 0;
1022
929
  state.processedFiles = 0;
1023
- state.hrStart = process.hrtime();
930
+ state.hrStart = node_process.default.hrtime();
1024
931
  state.currentConfigs = [];
932
+ state.hookStarts.clear();
1025
933
  }
1026
934
  function showProgressStep() {
1027
935
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -1033,9 +941,17 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1033
941
  }
1034
942
  function openGroup(name) {
1035
943
  console.log(`::group::${name}`);
944
+ state.openGroupDepth++;
1036
945
  }
1037
946
  function closeGroup(_name) {
1038
947
  console.log("::endgroup::");
948
+ if (state.openGroupDepth > 0) state.openGroupDepth--;
949
+ }
950
+ function closeAllGroups() {
951
+ while (state.openGroupDepth > 0) {
952
+ console.log("::endgroup::");
953
+ state.openGroupDepth--;
954
+ }
1039
955
  }
1040
956
  context.on("kubb:info", ({ message, info = "" }) => {
1041
957
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -1066,6 +982,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1066
982
  });
1067
983
  context.on("kubb:error", ({ error }) => {
1068
984
  const caused = require_errors.toCause(error);
985
+ closeAllGroups();
1069
986
  if (logLevel <= _kubb_core.logLevel.silent) return;
1070
987
  const message = error.message || String(error);
1071
988
  console.error(`::error::${message}`);
@@ -1083,6 +1000,9 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1083
1000
  console.log((0, node_util.styleText)("yellow", `Kubb ${version} 🧩`));
1084
1001
  reset();
1085
1002
  });
1003
+ context.on("kubb:version:new", ({ currentVersion, latestVersion }) => {
1004
+ console.log(`::notice::Update available for Kubb: v${currentVersion} → v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`);
1005
+ });
1086
1006
  context.on("kubb:config:start", () => {
1087
1007
  if (logLevel <= _kubb_core.logLevel.silent) return;
1088
1008
  const text = getMessage("Configuration started");
@@ -1167,31 +1087,35 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1167
1087
  console.log(text);
1168
1088
  if (state.currentConfigs.length === 1) closeGroup("Linting");
1169
1089
  });
1170
- context.on("kubb:hook:start", async ({ id, command, args }) => {
1090
+ context.on("kubb:hooks:start", () => {
1091
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1092
+ if (state.currentConfigs.length === 1) openGroup("Hooks");
1093
+ console.log(getMessage("Hooks started"));
1094
+ });
1095
+ context.on("kubb:hooks:end", () => {
1096
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1097
+ console.log(getMessage("Hooks completed"));
1098
+ if (state.currentConfigs.length === 1) closeGroup("Hooks");
1099
+ });
1100
+ context.on("kubb:hook:start", ({ id, command, args }) => {
1101
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1102
+ if (id) state.hookStarts.set(id, node_process.default.hrtime());
1171
1103
  const commandWithArgs = formatCommandWithArgs(command, args);
1172
1104
  const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} started`);
1173
- if (logLevel > _kubb_core.logLevel.silent) {
1174
- if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
1175
- console.log(text);
1176
- }
1177
- if (!id) return;
1178
- await runHook({
1179
- id,
1180
- command,
1181
- args,
1182
- commandWithArgs,
1183
- context,
1184
- sink: {
1185
- onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1186
- onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
1187
- }
1188
- });
1105
+ if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
1106
+ console.log(text);
1189
1107
  });
1190
- context.on("kubb:hook:end", ({ command, args }) => {
1108
+ context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
1191
1109
  if (logLevel <= _kubb_core.logLevel.silent) return;
1110
+ const hrStart = id ? state.hookStarts.get(id) : void 0;
1111
+ if (id) state.hookStarts.delete(id);
1112
+ const durationStr = hrStart ? ` in ${formatMsWithColor(getElapsedMs(hrStart))}` : "";
1192
1113
  const commandWithArgs = formatCommandWithArgs(command, args);
1193
- const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} completed`);
1194
- console.log(text);
1114
+ if (success) console.log(getMessage(`${(0, node_util.styleText)("green", "✓")} Hook ${(0, node_util.styleText)("dim", commandWithArgs)} completed${durationStr}`));
1115
+ else {
1116
+ const reason = error?.message ? ` (${error.message})` : "";
1117
+ console.log(`::error::Hook ${commandWithArgs} failed${durationStr}${reason}`);
1118
+ }
1195
1119
  if (state.currentConfigs.length === 1) closeGroup(`Hook ${commandWithArgs}`);
1196
1120
  });
1197
1121
  context.on("kubb:generation:summary", ({ config, status, hrStart, failedPlugins }) => {
@@ -1205,6 +1129,10 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1205
1129
  context.on("kubb:lifecycle:end", () => {
1206
1130
  reset();
1207
1131
  });
1132
+ return (_commandWithArgs, _hookId) => ({
1133
+ onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1134
+ onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
1135
+ });
1208
1136
  }
1209
1137
  });
1210
1138
  //#endregion
@@ -1216,6 +1144,7 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1216
1144
  name: "plain",
1217
1145
  install(context, options) {
1218
1146
  const logLevel = options?.logLevel ?? _kubb_core.logLevel.info;
1147
+ const hookStarts = /* @__PURE__ */ new Map();
1219
1148
  function getMessage(message) {
1220
1149
  return formatMessage(message, logLevel);
1221
1150
  }
@@ -1260,8 +1189,12 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1260
1189
  }
1261
1190
  }
1262
1191
  });
1263
- context.on("kubb:lifecycle:start", () => {
1264
- console.log("Kubb CLI 🧩");
1192
+ context.on("kubb:lifecycle:start", ({ version }) => {
1193
+ console.log(`Kubb CLI v${version}`);
1194
+ });
1195
+ context.on("kubb:version:new", ({ currentVersion, latestVersion }) => {
1196
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1197
+ console.log(getMessage(`Update available: v${currentVersion} → v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`));
1265
1198
  });
1266
1199
  context.on("kubb:config:start", () => {
1267
1200
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -1327,27 +1260,31 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1327
1260
  const text = getMessage("Lint completed");
1328
1261
  console.log(text);
1329
1262
  });
1330
- context.on("kubb:hook:start", async ({ id, command, args }) => {
1263
+ context.on("kubb:hooks:start", () => {
1264
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1265
+ console.log(getMessage("Hooks started"));
1266
+ });
1267
+ context.on("kubb:hooks:end", () => {
1268
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1269
+ console.log(getMessage("Hooks completed"));
1270
+ });
1271
+ context.on("kubb:hook:start", ({ id, command, args }) => {
1272
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1273
+ if (id) hookStarts.set(id, node_process.default.hrtime());
1331
1274
  const commandWithArgs = formatCommandWithArgs(command, args);
1332
- const text = getMessage(`Hook ${commandWithArgs} started`);
1333
- if (logLevel > _kubb_core.logLevel.silent) console.log(text);
1334
- if (!id) return;
1335
- await runHook({
1336
- id,
1337
- command,
1338
- args,
1339
- commandWithArgs,
1340
- context,
1341
- sink: {
1342
- onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1343
- onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(s) : void 0
1344
- }
1345
- });
1275
+ console.log(getMessage(`Hook ${commandWithArgs} started`));
1346
1276
  });
1347
- context.on("kubb:hook:end", ({ command, args }) => {
1277
+ context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
1348
1278
  if (logLevel <= _kubb_core.logLevel.silent) return;
1349
- const text = getMessage(`Hook ${formatCommandWithArgs(command, args)} completed`);
1350
- console.log(text);
1279
+ const hrStart = id ? hookStarts.get(id) : void 0;
1280
+ if (id) hookStarts.delete(id);
1281
+ const durationStr = hrStart ? ` in ${formatMs(getElapsedMs(hrStart))}` : "";
1282
+ const commandWithArgs = formatCommandWithArgs(command, args);
1283
+ if (success) console.log(getMessage(`✓ Hook ${commandWithArgs} completed${durationStr}`));
1284
+ else {
1285
+ const reason = error?.message ? ` (${error.message})` : "";
1286
+ console.log(getMessage(`✗ Hook ${commandWithArgs} failed${durationStr}${reason}`));
1287
+ }
1351
1288
  });
1352
1289
  context.on("kubb:generation:summary", ({ config, pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
1353
1290
  const summary = getSummary({
@@ -1362,6 +1299,10 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1362
1299
  console.log(summary.join("\n"));
1363
1300
  console.log(require_constants.SUMMARY_SEPARATOR);
1364
1301
  });
1302
+ return (_commandWithArgs, _hookId) => ({
1303
+ onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1304
+ onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(s) : void 0
1305
+ });
1365
1306
  }
1366
1307
  });
1367
1308
  //#endregion
@@ -1416,125 +1357,241 @@ async function setupLogger(context, { logLevel }) {
1416
1357
  const type = detectLogger();
1417
1358
  const logger = logMapper[type];
1418
1359
  if (!logger) throw new Error(`Unknown adapter type: ${type}`);
1419
- const cleanup = await logger.install(context, { logLevel });
1360
+ const makeSink = await logger.install(context, { logLevel });
1420
1361
  if (logLevel >= _kubb_core.logLevel.debug) await fileSystemLogger.install(context, { logLevel });
1421
- return cleanup;
1362
+ return typeof makeSink === "function" ? makeSink : void 0;
1422
1363
  }
1423
- //#endregion
1424
- //#region src/utils/executeHooks.ts
1425
- async function executeHooks({ configHooks, hooks }) {
1426
- const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
1427
- for (const command of commands) {
1428
- const [cmd, ...args] = require_shell.tokenize(command);
1429
- if (!cmd) continue;
1430
- const hookId = (0, node_crypto.createHash)("sha256").update(command).digest("hex");
1431
- const hookEndPromise = new Promise((resolve, reject) => {
1432
- const handler = (ctx) => {
1433
- if (ctx.id !== hookId) return;
1434
- hooks.off("kubb:hook:end", handler);
1435
- if (!ctx.success) {
1436
- reject(ctx.error ?? /* @__PURE__ */ new Error(`Hook failed: ${command}`));
1437
- return;
1438
- }
1439
- hooks.emit("kubb:success", { message: `${(0, node_util.styleText)("dim", command)} successfully executed` }).then(resolve).catch(reject);
1440
- };
1441
- hooks.on("kubb:hook:end", handler);
1442
- });
1443
- await hooks.emit("kubb:hook:start", {
1444
- id: hookId,
1445
- command: cmd,
1446
- args
1364
+ /**
1365
+ * Builds the generation summary lines rendered in the end-of-run box.
1366
+ * Returns an array of styled strings, one per summary row.
1367
+ */
1368
+ function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
1369
+ const duration = formatHrtime(hrStart);
1370
+ const pluginsCount = config.plugins?.length ?? 0;
1371
+ const successCount = pluginsCount - failedPlugins.size;
1372
+ const meta = {
1373
+ plugins: status === "success" ? `${(0, node_util.styleText)("green", `${successCount} successful`)}, ${pluginsCount} total` : `${(0, node_util.styleText)("green", `${successCount} successful`)}, ${(0, node_util.styleText)("red", `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
1374
+ pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
1375
+ filesCreated,
1376
+ time: (0, node_util.styleText)("green", duration),
1377
+ output: node_path.default.resolve(config.root, config.output.path)
1378
+ };
1379
+ const labels = {
1380
+ plugins: "Plugins:",
1381
+ failed: "Failed:",
1382
+ generated: "Generated:",
1383
+ pluginTimings: "Plugin Timings:",
1384
+ output: "Output:"
1385
+ };
1386
+ const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
1387
+ const summaryLines = [];
1388
+ summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
1389
+ if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
1390
+ summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
1391
+ if (pluginTimings && pluginTimings.size > 0) {
1392
+ const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
1393
+ summaryLines.push(`${labels.pluginTimings}`);
1394
+ sortedTimings.forEach(([name, time]) => {
1395
+ const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
1396
+ const barLength = Math.min(Math.ceil(time / 100), 10);
1397
+ const bar = (0, node_util.styleText)("dim", "█".repeat(barLength));
1398
+ summaryLines.push(`${(0, node_util.styleText)("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
1447
1399
  });
1448
- await hookEndPromise;
1449
1400
  }
1401
+ summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
1402
+ return summaryLines;
1450
1403
  }
1451
1404
  //#endregion
1452
- //#region src/utils/getConfig.ts
1453
- async function getConfigs(config, args) {
1454
- const resolved = await (typeof config === "function" ? config(args) : config);
1455
- return (Array.isArray(resolved) ? resolved : [resolved]).map((item) => ({
1456
- ...item,
1457
- plugins: item.plugins ?? []
1458
- }));
1459
- }
1460
- //#endregion
1461
- //#region src/utils/getCosmiConfig.ts
1462
- const unrunInputOptions = { transform: { jsx: {
1463
- runtime: "automatic",
1464
- importSource: "@kubb/renderer-jsx"
1465
- } } };
1466
- const tsLoader = async (configFile) => {
1467
- const { module } = await (0, unrun.unrun)({
1468
- path: configFile,
1469
- inputOptions: unrunInputOptions
1470
- });
1471
- return module;
1472
- };
1473
- async function getCosmiConfig(moduleName, config) {
1474
- let result;
1475
- const searchPlaces = [
1476
- "package.json",
1477
- `.${moduleName}rc`,
1478
- `.${moduleName}rc.json`,
1479
- `.${moduleName}rc.yaml`,
1480
- `.${moduleName}rc.yml`,
1481
- `.${moduleName}rc.ts`,
1482
- `.${moduleName}rc.mts`,
1483
- `.${moduleName}rc.cts`,
1484
- `.${moduleName}rc.js`,
1485
- `.${moduleName}rc.mjs`,
1486
- `.${moduleName}rc.cjs`,
1487
- `${moduleName}.config.ts`,
1488
- `${moduleName}.config.mts`,
1489
- `${moduleName}.config.cts`,
1490
- `${moduleName}.config.js`,
1491
- `${moduleName}.config.mjs`,
1492
- `${moduleName}.config.cjs`
1493
- ];
1494
- const explorer = (0, cosmiconfig.cosmiconfig)(moduleName, {
1405
+ //#region src/runners/generate/utils.ts
1406
+ const jiti$1 = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).href, {
1407
+ jsx: {
1408
+ runtime: "automatic",
1409
+ importSource: "@kubb/renderer-jsx"
1410
+ },
1411
+ moduleCache: false
1412
+ });
1413
+ const tsLoader = (configFile) => jiti$1.import(configFile, { default: true });
1414
+ const MODULE_NAME = "kubb";
1415
+ const BASE_SEARCH_PLACES = [
1416
+ "package.json",
1417
+ `.${MODULE_NAME}rc`,
1418
+ `.${MODULE_NAME}rc.json`,
1419
+ `.${MODULE_NAME}rc.yaml`,
1420
+ `.${MODULE_NAME}rc.yml`,
1421
+ `.${MODULE_NAME}rc.ts`,
1422
+ `.${MODULE_NAME}rc.mts`,
1423
+ `.${MODULE_NAME}rc.cts`,
1424
+ `.${MODULE_NAME}rc.js`,
1425
+ `.${MODULE_NAME}rc.mjs`,
1426
+ `.${MODULE_NAME}rc.cjs`,
1427
+ `${MODULE_NAME}.config.ts`,
1428
+ `${MODULE_NAME}.config.mts`,
1429
+ `${MODULE_NAME}.config.cts`,
1430
+ `${MODULE_NAME}.config.js`,
1431
+ `${MODULE_NAME}.config.mjs`,
1432
+ `${MODULE_NAME}.config.cjs`
1433
+ ];
1434
+ const SEARCH_PLACES = [
1435
+ "",
1436
+ ".config/",
1437
+ "configs/"
1438
+ ].flatMap((prefix) => BASE_SEARCH_PLACES.map((p) => `${prefix}${p}`));
1439
+ async function getCosmiConfig(configFile) {
1440
+ const explorer = (0, cosmiconfig.cosmiconfig)(MODULE_NAME, {
1495
1441
  cache: false,
1496
- searchPlaces: [
1497
- ...searchPlaces.map((searchPlace) => {
1498
- return `.config/${searchPlace}`;
1499
- }),
1500
- ...searchPlaces.map((searchPlace) => {
1501
- return `configs/${searchPlace}`;
1502
- }),
1503
- ...searchPlaces
1504
- ],
1442
+ searchPlaces: SEARCH_PLACES,
1505
1443
  loaders: {
1506
1444
  ".ts": tsLoader,
1507
1445
  ".mts": tsLoader,
1508
1446
  ".cts": tsLoader
1509
1447
  }
1510
1448
  });
1449
+ let result;
1511
1450
  try {
1512
- result = config ? await explorer.load(config) : await explorer.search();
1451
+ result = configFile ? await explorer.load(configFile) : await explorer.search();
1513
1452
  } catch (error) {
1514
1453
  throw new Error("Config failed loading", { cause: error });
1515
1454
  }
1516
- if (result?.isEmpty || !result || !result.config) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
1455
+ if (!result?.config || result.isEmpty) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
1517
1456
  return result;
1518
1457
  }
1519
- //#endregion
1520
- //#region src/utils/watcher.ts
1521
- async function startWatcher(path, cb) {
1458
+ /**
1459
+ * Discovers the Kubb config via cosmiconfig and resolves it into a normalized array of configs.
1460
+ * Every config in the result is guaranteed to have a `plugins` array.
1461
+ */
1462
+ async function getConfigs({ configPath, input }) {
1463
+ const result = await getCosmiConfig(configPath);
1464
+ const resolved = await (typeof result.config === "function" ? result.config({ input }) : result.config);
1465
+ const userConfigs = Array.isArray(resolved) ? resolved : [resolved];
1466
+ return {
1467
+ configPath: result.filepath,
1468
+ configs: userConfigs.map((item) => ({
1469
+ ...item,
1470
+ plugins: item.plugins ?? []
1471
+ }))
1472
+ };
1473
+ }
1474
+ /**
1475
+ * Runs the `done` hooks defined in a Kubb config in sequence.
1476
+ */
1477
+ async function executeHooks({ configHooks, hooks, makeSink }) {
1478
+ const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
1479
+ for (const command of commands) {
1480
+ const [cmd, ...args] = require_shell.tokenize(command);
1481
+ if (!cmd) continue;
1482
+ const hookId = (0, node_crypto.createHash)("sha256").update(command).digest("hex");
1483
+ const commandWithArgs = [cmd, ...args].join(" ");
1484
+ await hooks.emit("kubb:hook:start", {
1485
+ id: hookId,
1486
+ command: cmd,
1487
+ args
1488
+ });
1489
+ const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
1490
+ await runHook({
1491
+ id: hookId,
1492
+ command: cmd,
1493
+ args,
1494
+ commandWithArgs,
1495
+ context: hooks,
1496
+ stream,
1497
+ sink: {
1498
+ onLine,
1499
+ onStdout,
1500
+ onStderr
1501
+ }
1502
+ });
1503
+ }
1504
+ }
1505
+ async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
1506
+ const emitEnd = (success, error) => context.emit("kubb:hook:end", {
1507
+ command,
1508
+ args,
1509
+ id,
1510
+ success,
1511
+ error
1512
+ });
1513
+ try {
1514
+ const proc = (0, tinyexec.x)(command, [...args ?? []], {
1515
+ nodeOptions: { detached: process.platform !== "win32" },
1516
+ throwOnError: true
1517
+ });
1518
+ if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
1519
+ const result = await proc;
1520
+ await context.emit("kubb:debug", {
1521
+ date: /* @__PURE__ */ new Date(),
1522
+ logs: [result.stdout.trimEnd()]
1523
+ });
1524
+ await context.emit("kubb:success", { message: `${(0, node_util.styleText)("dim", commandWithArgs)} successfully executed` });
1525
+ await emitEnd(true, null);
1526
+ } catch (err) {
1527
+ if (!(err instanceof tinyexec.NonZeroExitError)) {
1528
+ const error = require_errors.toError(err);
1529
+ await emitEnd(false, error);
1530
+ await context.emit("kubb:error", { error });
1531
+ return;
1532
+ }
1533
+ const stderr = err.output?.stderr ?? "";
1534
+ const stdout = err.output?.stdout ?? "";
1535
+ await context.emit("kubb:debug", {
1536
+ date: /* @__PURE__ */ new Date(),
1537
+ logs: [stdout, stderr].filter(Boolean)
1538
+ });
1539
+ if (stderr) sink?.onStderr?.(stderr);
1540
+ if (stdout) sink?.onStdout?.(stdout);
1541
+ const error = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
1542
+ await emitEnd(false, error);
1543
+ await context.emit("kubb:error", { error });
1544
+ }
1545
+ }
1546
+ /**
1547
+ * Starts a file watcher on the given paths and calls `cb` on any change.
1548
+ * Ignores `.git` and `node_modules` directories.
1549
+ */
1550
+ async function startWatcher(path, cb, log = {
1551
+ info: console.log,
1552
+ error: console.log
1553
+ }) {
1522
1554
  const { watch } = await import("chokidar");
1523
- watch(path, {
1555
+ const watcher = watch(path, {
1524
1556
  ignorePermissionErrors: true,
1525
1557
  ignored: require_constants.WATCHER_IGNORED_PATHS
1526
- }).on("all", async (type, file) => {
1527
- console.log((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${type} ${file}`)));
1558
+ });
1559
+ process.once("SIGINT", () => {
1560
+ watcher.close();
1561
+ });
1562
+ process.once("SIGTERM", () => {
1563
+ watcher.close();
1564
+ });
1565
+ watcher.on("all", async (type, file) => {
1566
+ log.info((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${type} ${file}`)));
1528
1567
  try {
1529
1568
  await cb(path);
1530
1569
  } catch (_e) {
1531
- console.log((0, node_util.styleText)("red", "Watcher failed"));
1570
+ log.error((0, node_util.styleText)("red", "Watcher failed"));
1532
1571
  }
1533
1572
  });
1534
1573
  }
1535
1574
  //#endregion
1536
- //#region src/runners/generate.ts
1537
- async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel, hooks, onStart, onEnd }) {
1575
+ //#region src/runners/generate/run.ts
1576
+ /**
1577
+ * Registers a one-shot `kubb:hook:end` listener for `hookId` BEFORE the caller emits `kubb:hook:start`,
1578
+ * avoiding the race where a synchronous emitter fires end before the listener is attached.
1579
+ */
1580
+ function waitForHookEnd(hooks, hookId, onSuccess, fallbackErrorMessage) {
1581
+ return new Promise((resolve, reject) => {
1582
+ const handler = (ctx) => {
1583
+ if (ctx.id !== hookId) return;
1584
+ hooks.off("kubb:hook:end", handler);
1585
+ if (!ctx.success) {
1586
+ reject(ctx.error ?? new Error(fallbackErrorMessage));
1587
+ return;
1588
+ }
1589
+ Promise.resolve(onSuccess()).then(resolve).catch(reject);
1590
+ };
1591
+ hooks.on("kubb:hook:end", handler);
1592
+ });
1593
+ }
1594
+ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel, hooks, makeSink, onStart, onEnd }) {
1538
1595
  await onStart();
1539
1596
  let resolvedTool = toolValue;
1540
1597
  if (resolvedTool === "auto") {
@@ -1548,29 +1605,35 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1548
1605
  let toolError;
1549
1606
  if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
1550
1607
  const toolConfig = toolMap[resolvedTool];
1608
+ const hookId = (0, node_crypto.createHash)("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
1609
+ const successMessage = [
1610
+ `${successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1611
+ logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1612
+ "successfully"
1613
+ ].filter(Boolean).join(" ");
1551
1614
  try {
1552
- const hookId = (0, node_crypto.createHash)("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
1553
- const hookEndPromise = new Promise((resolve, reject) => {
1554
- const handler = (ctx) => {
1555
- if (ctx.id !== hookId) return;
1556
- hooks.off("kubb:hook:end", handler);
1557
- if (!ctx.success) {
1558
- reject(ctx.error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
1559
- return;
1560
- }
1561
- hooks.emit("kubb:success", { message: [
1562
- `${successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1563
- logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1564
- "successfully"
1565
- ].filter(Boolean).join(" ") }).then(resolve).catch(reject);
1566
- };
1567
- hooks.on("kubb:hook:end", handler);
1568
- });
1615
+ const hookArgs = toolConfig.args(outputPath);
1616
+ const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
1617
+ const hookEndPromise = waitForHookEnd(hooks, hookId, () => hooks.emit("kubb:success", { message: successMessage }), toolConfig.errorMessage);
1569
1618
  await hooks.emit("kubb:hook:start", {
1570
1619
  id: hookId,
1571
1620
  command: toolConfig.command,
1572
- args: toolConfig.args(outputPath)
1621
+ args: hookArgs
1573
1622
  });
1623
+ const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
1624
+ runHook({
1625
+ id: hookId,
1626
+ command: toolConfig.command,
1627
+ args: hookArgs,
1628
+ commandWithArgs,
1629
+ context: hooks,
1630
+ stream,
1631
+ sink: {
1632
+ onLine,
1633
+ onStdout,
1634
+ onStderr
1635
+ }
1636
+ }).catch(() => {});
1574
1637
  await hookEndPromise;
1575
1638
  } catch (caughtError) {
1576
1639
  const err = require_errors.toError(caughtError);
@@ -1582,9 +1645,9 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1582
1645
  if (toolError) throw toolError;
1583
1646
  }
1584
1647
  async function generate(options) {
1585
- const { input, hooks, logLevel } = options;
1648
+ const { input, hooks, logLevel, makeSink } = options;
1586
1649
  const hrStart = node_process.default.hrtime();
1587
- const inputPath = input ?? ("path" in options.config.input ? options.config.input.path : void 0);
1650
+ const inputPath = input ?? (options.config.input && "path" in options.config.input ? options.config.input.path : void 0);
1588
1651
  const config = {
1589
1652
  ...options.config,
1590
1653
  input: inputPath ? {
@@ -1594,25 +1657,36 @@ async function generate(options) {
1594
1657
  ...options.config.output
1595
1658
  };
1596
1659
  const kubb = (0, _kubb_core.createKubb)(config, { hooks });
1597
- await kubb.setup();
1598
1660
  await hooks.emit("kubb:generation:start", { config });
1599
1661
  await hooks.emit("kubb:info", {
1600
1662
  message: config.name ? `Setup generation ${(0, node_util.styleText)("bold", config.name)}` : "Setup generation",
1601
1663
  info: inputPath
1602
1664
  });
1665
+ await kubb.setup();
1603
1666
  await hooks.emit("kubb:info", {
1604
1667
  message: config.name ? `Build generation ${(0, node_util.styleText)("bold", config.name)}` : "Build generation",
1605
1668
  info: inputPath
1606
1669
  });
1607
1670
  const { files, failedPlugins, pluginTimings, error, driver } = await kubb.safeBuild();
1608
1671
  await hooks.emit("kubb:info", { message: "Load summary" });
1672
+ const telemetryPlugins = Array.from(driver.plugins.values(), (p) => ({
1673
+ name: p.name,
1674
+ options: p.options
1675
+ }));
1676
+ const reportTelemetry = (status) => require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1677
+ command: "generate",
1678
+ kubbVersion: require_package.version,
1679
+ plugins: telemetryPlugins,
1680
+ hrStart,
1681
+ filesCreated: files.length,
1682
+ status
1683
+ }));
1609
1684
  if (failedPlugins.size > 0 || error) {
1610
- const allErrors = [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean);
1685
+ const allErrors = [error, ...Array.from(failedPlugins, (it) => it.error)].filter(Boolean);
1611
1686
  for (const err of allErrors) await hooks.emit("kubb:error", { error: err });
1612
1687
  await hooks.emit("kubb:generation:end", {
1613
1688
  config,
1614
- files,
1615
- sources: kubb.sources
1689
+ storage: kubb.storage
1616
1690
  });
1617
1691
  await hooks.emit("kubb:generation:summary", {
1618
1692
  config,
@@ -1622,62 +1696,51 @@ async function generate(options) {
1622
1696
  hrStart,
1623
1697
  pluginTimings: logLevel >= _kubb_core.logLevel.verbose ? pluginTimings : void 0
1624
1698
  });
1625
- await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1626
- command: "generate",
1627
- kubbVersion: require_package.version,
1628
- plugins: Array.from(driver.plugins.values(), (p) => ({
1629
- name: p.name,
1630
- options: p.options
1631
- })),
1632
- hrStart,
1633
- filesCreated: files.length,
1634
- status: "failed"
1635
- }));
1636
- node_process.default.exit(1);
1699
+ await reportTelemetry("failed");
1700
+ return false;
1637
1701
  }
1638
1702
  await hooks.emit("kubb:success", {
1639
- message: "Generation successfully",
1703
+ message: "Generation succeeded",
1640
1704
  info: inputPath
1641
1705
  });
1642
1706
  await hooks.emit("kubb:generation:end", {
1643
1707
  config,
1644
- files,
1645
- sources: kubb.sources
1708
+ storage: kubb.storage
1646
1709
  });
1647
1710
  const outputPath = node_path.default.resolve(config.root, config.output.path);
1648
- if (config.output.format) await runToolPass({
1711
+ const toolPasses = [config.output.format && {
1649
1712
  toolValue: config.output.format,
1650
1713
  detect: detectFormatter,
1651
1714
  toolMap: formatters,
1652
1715
  toolLabel: "formatter",
1653
1716
  successPrefix: "Formatting",
1654
1717
  noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
1655
- configName: config.name,
1656
- outputPath,
1657
- logLevel,
1658
- hooks,
1659
1718
  onStart: () => hooks.emit("kubb:format:start"),
1660
1719
  onEnd: () => hooks.emit("kubb:format:end")
1661
- });
1662
- if (config.output.lint) await runToolPass({
1720
+ }, config.output.lint && {
1663
1721
  toolValue: config.output.lint,
1664
1722
  detect: detectLinter,
1665
1723
  toolMap: linters,
1666
1724
  toolLabel: "linter",
1667
1725
  successPrefix: "Linting",
1668
1726
  noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
1727
+ onStart: () => hooks.emit("kubb:lint:start"),
1728
+ onEnd: () => hooks.emit("kubb:lint:end")
1729
+ }].filter(Boolean);
1730
+ for (const pass of toolPasses) await runToolPass({
1731
+ ...pass,
1669
1732
  configName: config.name,
1670
1733
  outputPath,
1671
1734
  logLevel,
1672
1735
  hooks,
1673
- onStart: () => hooks.emit("kubb:lint:start"),
1674
- onEnd: () => hooks.emit("kubb:lint:end")
1736
+ makeSink
1675
1737
  });
1676
1738
  if (config.hooks) {
1677
1739
  await hooks.emit("kubb:hooks:start");
1678
1740
  await executeHooks({
1679
1741
  configHooks: config.hooks,
1680
- hooks
1742
+ hooks,
1743
+ makeSink
1681
1744
  });
1682
1745
  await hooks.emit("kubb:hooks:end");
1683
1746
  }
@@ -1689,68 +1752,80 @@ async function generate(options) {
1689
1752
  hrStart,
1690
1753
  pluginTimings
1691
1754
  });
1692
- await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1693
- command: "generate",
1694
- kubbVersion: require_package.version,
1695
- plugins: Array.from(driver.plugins.values(), (p) => ({
1696
- name: p.name,
1697
- options: p.options
1698
- })),
1699
- hrStart,
1700
- filesCreated: files.length,
1701
- status: "success"
1702
- }));
1755
+ await reportTelemetry("success");
1756
+ return true;
1703
1757
  }
1704
- async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }) {
1705
- const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1706
- const hooks = new AsyncEventEmitter();
1707
- await setupLogger(hooks, { logLevel });
1758
+ async function checkForUpdate(hooks) {
1708
1759
  await require_telemetry.executeIfOnline(async () => {
1709
1760
  try {
1710
- const latestVersion = (await (await fetch(require_constants.KUBB_NPM_PACKAGE_URL)).json()).version;
1711
- if (latestVersion && require_package.version < latestVersion) await hooks.emit("kubb:version:new", {
1761
+ const data = await (await fetch(require_constants.KUBB_NPM_PACKAGE_URL)).json();
1762
+ if (data.version && require_package.version < data.version) await hooks.emit("kubb:version:new", {
1712
1763
  currentVersion: require_package.version,
1713
- latestVersion
1764
+ latestVersion: data.version
1714
1765
  });
1715
1766
  } catch {}
1716
1767
  });
1768
+ }
1769
+ /**
1770
+ * Runs the full Kubb generation lifecycle for the given CLI options.
1771
+ * Sets up the logger, checks for a newer version, loads configs, and calls `generate` for each config entry.
1772
+ */
1773
+ async function run({ input, configPath, logLevel: logLevelKey, watch }) {
1774
+ const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1775
+ const hooks = new AsyncEventEmitter();
1776
+ const makeSink = await setupLogger(hooks, { logLevel });
1777
+ await hooks.emit("kubb:lifecycle:start", { version: require_package.version });
1778
+ await checkForUpdate(hooks);
1717
1779
  try {
1718
- const result = await getCosmiConfig("kubb", configPath);
1719
- const configs = await getConfigs(result.config, { input });
1720
1780
  await hooks.emit("kubb:config:start");
1781
+ const { configs, configPath: resolvedConfigPath } = await getConfigs({
1782
+ configPath,
1783
+ input
1784
+ });
1785
+ const relativeConfigPath = node_path.default.relative(node_process.default.cwd(), resolvedConfigPath);
1721
1786
  await hooks.emit("kubb:info", {
1722
1787
  message: "Config loaded",
1723
- info: node_path.default.relative(node_process.default.cwd(), result.filepath)
1788
+ info: relativeConfigPath
1724
1789
  });
1725
1790
  await hooks.emit("kubb:success", {
1726
1791
  message: "Config loaded successfully",
1727
- info: node_path.default.relative(node_process.default.cwd(), result.filepath)
1792
+ info: relativeConfigPath
1728
1793
  });
1729
1794
  await hooks.emit("kubb:config:end", { configs });
1730
- await hooks.emit("kubb:lifecycle:start", { version: require_package.version });
1795
+ let anyFailed = false;
1731
1796
  for (const config of configs) if ((0, _kubb_core.isInputPath)(config) && watch) await startWatcher([input || config.input.path], async (paths) => {
1732
- hooks.removeAll();
1733
1797
  await generate({
1734
1798
  input,
1735
1799
  config,
1736
1800
  logLevel,
1737
- hooks
1801
+ hooks,
1802
+ makeSink
1738
1803
  });
1739
1804
  _clack_prompts.log.step((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
1805
+ }, {
1806
+ info: (msg) => _clack_prompts.log.info(msg),
1807
+ error: (msg) => _clack_prompts.log.error(msg)
1740
1808
  });
1741
- else await generate({
1742
- input,
1743
- config,
1744
- logLevel,
1745
- hooks
1746
- });
1809
+ else try {
1810
+ if (!await generate({
1811
+ input,
1812
+ config,
1813
+ logLevel,
1814
+ hooks,
1815
+ makeSink
1816
+ })) anyFailed = true;
1817
+ } catch (configError) {
1818
+ await hooks.emit("kubb:error", { error: require_errors.toError(configError) });
1819
+ anyFailed = true;
1820
+ }
1747
1821
  await hooks.emit("kubb:lifecycle:end");
1822
+ if (anyFailed) node_process.default.exit(1);
1748
1823
  } catch (error) {
1749
1824
  await hooks.emit("kubb:error", { error: require_errors.toError(error) });
1750
1825
  node_process.default.exit(1);
1751
1826
  }
1752
1827
  }
1753
1828
  //#endregion
1754
- exports.runGenerateCommand = runGenerateCommand;
1829
+ exports.run = run;
1755
1830
 
1756
- //# sourceMappingURL=generate-B3jl4ukb.cjs.map
1831
+ //# sourceMappingURL=run-BP_t4Z6z.cjs.map