@kubb/cli 5.0.0-beta.6 → 5.0.0-beta.7

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 (117) hide show
  1. package/README.md +177 -26
  2. package/dist/{agent-BJEvbSiP.js → agent-DN7o8nlE.js} +7 -7
  3. package/dist/agent-DN7o8nlE.js.map +1 -0
  4. package/dist/{agent-CXNO6dgj.cjs → agent-Fm9_8BBH.cjs} +5 -5
  5. package/dist/agent-Fm9_8BBH.cjs.map +1 -0
  6. package/dist/{chunk--u3MIqq1.js → chunk-BvFE5Tac.js} +1 -0
  7. package/dist/{constants-BPJBMT_6.js → constants-B2JTeRBb.js} +1 -4
  8. package/dist/{constants-BPJBMT_6.js.map → constants-B2JTeRBb.js.map} +1 -1
  9. package/dist/{constants-Rcaqzyd-.cjs → constants-BINTA5VZ.cjs} +1 -4
  10. package/dist/{constants-Rcaqzyd-.cjs.map → constants-BINTA5VZ.cjs.map} +1 -1
  11. package/dist/{define-Ctii4bel.js → define-m_fp-Aqm.js} +2 -2
  12. package/dist/{define-Ctii4bel.js.map → define-m_fp-Aqm.js.map} +1 -1
  13. package/dist/{errors-CjPmyZHy.js → errors-CINO1EIv.js} +2 -2
  14. package/dist/{errors-CjPmyZHy.js.map → errors-CINO1EIv.js.map} +1 -1
  15. package/dist/{generate-BmulGxIM.js → generate-BY-juRdH.js} +5 -5
  16. package/dist/{generate-BmulGxIM.js.map → generate-BY-juRdH.js.map} +1 -1
  17. package/dist/{generate-BB2Q7I9s.cjs → generate-Bod9YCbF.cjs} +3 -3
  18. package/dist/{generate-BB2Q7I9s.cjs.map → generate-Bod9YCbF.cjs.map} +1 -1
  19. package/dist/index.cjs +9 -9
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +11 -11
  23. package/dist/index.js.map +1 -1
  24. package/dist/{init-Dpg8e1HN.cjs → init-BIkZU6mB.cjs} +4 -4
  25. package/dist/{init-Dpg8e1HN.cjs.map → init-BIkZU6mB.cjs.map} +1 -1
  26. package/dist/{init-BTp9if7K.js → init-Cs3Fp6nN.js} +6 -6
  27. package/dist/{init-BTp9if7K.js.map → init-Cs3Fp6nN.js.map} +1 -1
  28. package/dist/{mcp-C9RoU-Dg.js → mcp-BSNulBcC.js} +6 -6
  29. package/dist/{mcp-C9RoU-Dg.js.map → mcp-BSNulBcC.js.map} +1 -1
  30. package/dist/{mcp-wpl6sYYR.cjs → mcp-DcSrFhhP.cjs} +4 -4
  31. package/dist/{mcp-wpl6sYYR.cjs.map → mcp-DcSrFhhP.cjs.map} +1 -1
  32. package/dist/package-D5wmvFl4.js +6 -0
  33. package/dist/package-D5wmvFl4.js.map +1 -0
  34. package/dist/{package-iheSdfas.cjs → package-DrUndPET.cjs} +2 -2
  35. package/dist/package-DrUndPET.cjs.map +1 -0
  36. package/dist/{generate-DAsdUw3z.js → run-BAJubgdA.js} +298 -315
  37. package/dist/run-BAJubgdA.js.map +1 -0
  38. package/dist/{agent-VXKxLCho.js → run-BzpYYOQs.js} +46 -43
  39. package/dist/run-BzpYYOQs.js.map +1 -0
  40. package/dist/{validate-k9s_hFah.js → run-CCZ24VKk.js} +25 -20
  41. package/dist/run-CCZ24VKk.js.map +1 -0
  42. package/dist/{init-DCqcEq86.js → run-CF97BWVa.js} +77 -68
  43. package/dist/run-CF97BWVa.js.map +1 -0
  44. package/dist/{validate-BU4fPTMc.cjs → run-CQbj3ley.cjs} +23 -18
  45. package/dist/run-CQbj3ley.cjs.map +1 -0
  46. package/dist/{generate-B_p5dl68.cjs → run-CqKd6JNc.cjs} +295 -312
  47. package/dist/run-CqKd6JNc.cjs.map +1 -0
  48. package/dist/{mcp-DNUw8nqb.js → run-D0hmRpHy.js} +23 -23
  49. package/dist/run-D0hmRpHy.js.map +1 -0
  50. package/dist/{agent-D9CKYh4K.cjs → run-DwdAwnLG.cjs} +44 -41
  51. package/dist/run-DwdAwnLG.cjs.map +1 -0
  52. package/dist/{mcp-D1llTaRM.cjs → run-Lr0Ctnu0.cjs} +21 -21
  53. package/dist/run-Lr0Ctnu0.cjs.map +1 -0
  54. package/dist/{init-CJ80lKSP.cjs → run-YsoCk5we.cjs} +75 -66
  55. package/dist/run-YsoCk5we.cjs.map +1 -0
  56. package/dist/{shell-DLzN4fRo.js → shell-CN6DNqeC.js} +2 -2
  57. package/dist/{shell-DLzN4fRo.js.map → shell-CN6DNqeC.js.map} +1 -1
  58. package/dist/{telemetry-BLX0NzRk.cjs → telemetry-B2iWkY5e.cjs} +5 -7
  59. package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
  60. package/dist/{telemetry-juq4QBf7.js → telemetry-BkektVz6.js} +6 -8
  61. package/dist/telemetry-BkektVz6.js.map +1 -0
  62. package/dist/{validate-DIDBROB2.cjs → validate-Bfpf_UIh.cjs} +4 -4
  63. package/dist/{validate-DIDBROB2.cjs.map → validate-Bfpf_UIh.cjs.map} +1 -1
  64. package/dist/{validate-BfJoCxrC.js → validate-lbUkWQ5o.js} +6 -6
  65. package/dist/{validate-BfJoCxrC.js.map → validate-lbUkWQ5o.js.map} +1 -1
  66. package/package.json +7 -12
  67. package/src/commands/agent/start.ts +2 -2
  68. package/src/commands/generate.ts +2 -2
  69. package/src/commands/init.ts +2 -2
  70. package/src/commands/mcp.ts +2 -2
  71. package/src/commands/validate.ts +2 -2
  72. package/src/constants.ts +0 -4
  73. package/src/index.ts +5 -3
  74. package/src/loggers/clackLogger.ts +45 -43
  75. package/src/loggers/fileSystemLogger.ts +11 -1
  76. package/src/loggers/githubActionsLogger.ts +13 -25
  77. package/src/loggers/plainLogger.ts +12 -23
  78. package/src/loggers/types.ts +6 -0
  79. package/src/loggers/utils.ts +155 -9
  80. package/src/runners/agent/run.ts +113 -0
  81. package/src/runners/agent/utils.ts +98 -0
  82. package/src/runners/generate/run.ts +276 -0
  83. package/src/runners/generate/utils.ts +209 -0
  84. package/src/runners/{init.ts → init/run.ts} +70 -66
  85. package/src/{utils/packageManager.ts → runners/init/utils.ts} +10 -0
  86. package/src/runners/mcp/run.ts +55 -0
  87. package/src/runners/{validate.ts → validate/run.ts} +25 -20
  88. package/src/{utils/telemetry.ts → telemetry.ts} +12 -5
  89. package/dist/agent-BJEvbSiP.js.map +0 -1
  90. package/dist/agent-CXNO6dgj.cjs.map +0 -1
  91. package/dist/agent-D9CKYh4K.cjs.map +0 -1
  92. package/dist/agent-VXKxLCho.js.map +0 -1
  93. package/dist/generate-B_p5dl68.cjs.map +0 -1
  94. package/dist/generate-DAsdUw3z.js.map +0 -1
  95. package/dist/init-CJ80lKSP.cjs.map +0 -1
  96. package/dist/init-DCqcEq86.js.map +0 -1
  97. package/dist/mcp-D1llTaRM.cjs.map +0 -1
  98. package/dist/mcp-DNUw8nqb.js.map +0 -1
  99. package/dist/package-iheSdfas.cjs.map +0 -1
  100. package/dist/package-vLafMWCe.js +0 -6
  101. package/dist/package-vLafMWCe.js.map +0 -1
  102. package/dist/telemetry-BLX0NzRk.cjs.map +0 -1
  103. package/dist/telemetry-juq4QBf7.js.map +0 -1
  104. package/dist/validate-BU4fPTMc.cjs.map +0 -1
  105. package/dist/validate-k9s_hFah.js.map +0 -1
  106. package/src/runners/agent.ts +0 -155
  107. package/src/runners/generate.ts +0 -333
  108. package/src/runners/mcp.ts +0 -56
  109. package/src/types.ts +0 -11
  110. package/src/utils/Writables.ts +0 -17
  111. package/src/utils/executeHooks.ts +0 -45
  112. package/src/utils/flags.ts +0 -9
  113. package/src/utils/getConfig.ts +0 -10
  114. package/src/utils/getCosmiConfig.ts +0 -75
  115. package/src/utils/getSummary.ts +0 -68
  116. package/src/utils/runHook.ts +0 -91
  117. 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-BLX0NzRk.cjs");
3
+ const require_telemetry = require("./telemetry-B2iWkY5e.cjs");
4
4
  const require_shell = require("./shell-475fQKaX.cjs");
5
- const require_package = require("./package-iheSdfas.cjs");
6
- const require_constants = require("./constants-Rcaqzyd-.cjs");
5
+ const require_package = require("./package-DrUndPET.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,10 @@ 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
20
  let node_stream = require("node:stream");
22
21
  let cosmiconfig = require("cosmiconfig");
23
22
  let jiti = require("jiti");
23
+ let tinyexec = require("tinyexec");
24
24
  //#region ../../internals/utils/src/asyncEventEmitter.ts
25
25
  /**
26
26
  * Typed `EventEmitter` that awaits all async listeners before resolving.
@@ -489,100 +489,11 @@ async function detectLinter() {
489
489
  return null;
490
490
  }
491
491
  //#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
492
+ //#region src/loggers/clackLogger.ts
531
493
  /**
532
- * Executes a hook command, emits debug and completion events, and forwards output to an optional sink.
494
+ * Node.js `Writable` stream that forwards each chunk to a clack `taskLog` message.
495
+ * Used to pipe hook subprocess output into the clack task log UI.
533
496
  */
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
497
  var ClackWritable = class extends node_stream.Writable {
587
498
  taskLog;
588
499
  constructor(taskLog, opts) {
@@ -594,8 +505,6 @@ var ClackWritable = class extends node_stream.Writable {
594
505
  callback();
595
506
  }
596
507
  };
597
- //#endregion
598
- //#region src/loggers/clackLogger.ts
599
508
  /**
600
509
  * TTY logger with beautiful UI and progress indicators for local development.
601
510
  */
@@ -821,40 +730,10 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
821
730
  const text = getMessage("Lint completed");
822
731
  _clack_prompts.outro(text);
823
732
  });
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
- }
733
+ context.on("kubb:hook:start", ({ command, args }) => {
734
+ if (logLevel <= _kubb_core.logLevel.silent) return;
735
+ const text = getMessage(`Hook ${(0, node_util.styleText)("dim", formatCommandWithArgs(command, args))} started`);
842
736
  _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
- }
857
- });
858
737
  });
859
738
  context.on("kubb:hook:end", ({ command, args }) => {
860
739
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -890,13 +769,28 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
890
769
  context.on("kubb:lifecycle:end", () => {
891
770
  reset();
892
771
  });
772
+ return (commandWithArgs) => {
773
+ if (logLevel <= _kubb_core.logLevel.silent) return {
774
+ onStdout: (s) => console.log(s),
775
+ onStderr: (s) => console.error(s)
776
+ };
777
+ 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(" ")) });
778
+ const writable = new ClackWritable(logger);
779
+ return {
780
+ stream: true,
781
+ onLine: (line) => writable.write(line),
782
+ onStdout: (s) => logger.message(s),
783
+ onStderr: (s) => logger.error(s)
784
+ };
785
+ };
893
786
  }
894
787
  });
895
788
  //#endregion
896
789
  //#region src/loggers/fileSystemLogger.ts
897
790
  /**
898
791
  * 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.
792
+ *
793
+ * @note Logs are written on `kubb:lifecycle:end` or process exit. Cached logs may be lost if the process crashes before either event.
900
794
  */
901
795
  const fileSystemLogger = (0, _kubb_core.defineLogger)({
902
796
  name: "filesystem",
@@ -1167,25 +1061,12 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1167
1061
  console.log(text);
1168
1062
  if (state.currentConfigs.length === 1) closeGroup("Linting");
1169
1063
  });
1170
- context.on("kubb:hook:start", async ({ id, command, args }) => {
1064
+ context.on("kubb:hook:start", ({ command, args }) => {
1065
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1171
1066
  const commandWithArgs = formatCommandWithArgs(command, args);
1172
1067
  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
- });
1068
+ if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
1069
+ console.log(text);
1189
1070
  });
1190
1071
  context.on("kubb:hook:end", ({ command, args }) => {
1191
1072
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -1205,6 +1086,10 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
1205
1086
  context.on("kubb:lifecycle:end", () => {
1206
1087
  reset();
1207
1088
  });
1089
+ return (_commandWithArgs) => ({
1090
+ onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1091
+ onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
1092
+ });
1208
1093
  }
1209
1094
  });
1210
1095
  //#endregion
@@ -1327,22 +1212,10 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1327
1212
  const text = getMessage("Lint completed");
1328
1213
  console.log(text);
1329
1214
  });
1330
- context.on("kubb:hook:start", async ({ id, command, args }) => {
1331
- 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
- });
1215
+ context.on("kubb:hook:start", ({ command, args }) => {
1216
+ if (logLevel <= _kubb_core.logLevel.silent) return;
1217
+ const text = getMessage(`Hook ${formatCommandWithArgs(command, args)} started`);
1218
+ console.log(text);
1346
1219
  });
1347
1220
  context.on("kubb:hook:end", ({ command, args }) => {
1348
1221
  if (logLevel <= _kubb_core.logLevel.silent) return;
@@ -1362,6 +1235,10 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1362
1235
  console.log(summary.join("\n"));
1363
1236
  console.log(require_constants.SUMMARY_SEPARATOR);
1364
1237
  });
1238
+ return (_commandWithArgs) => ({
1239
+ onStdout: logLevel > _kubb_core.logLevel.silent ? (s) => console.log(s) : void 0,
1240
+ onStderr: logLevel > _kubb_core.logLevel.silent ? (s) => console.error(s) : void 0
1241
+ });
1365
1242
  }
1366
1243
  });
1367
1244
  //#endregion
@@ -1416,49 +1293,52 @@ async function setupLogger(context, { logLevel }) {
1416
1293
  const type = detectLogger();
1417
1294
  const logger = logMapper[type];
1418
1295
  if (!logger) throw new Error(`Unknown adapter type: ${type}`);
1419
- const cleanup = await logger.install(context, { logLevel });
1296
+ const makeSink = await logger.install(context, { logLevel });
1420
1297
  if (logLevel >= _kubb_core.logLevel.debug) await fileSystemLogger.install(context, { logLevel });
1421
- return cleanup;
1298
+ return typeof makeSink === "function" ? makeSink : void 0;
1422
1299
  }
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
1300
+ /**
1301
+ * Builds the generation summary lines rendered in the end-of-run box.
1302
+ * Returns an array of styled strings, one per summary row.
1303
+ */
1304
+ function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
1305
+ const duration = formatHrtime(hrStart);
1306
+ const pluginsCount = config.plugins?.length ?? 0;
1307
+ const successCount = pluginsCount - failedPlugins.size;
1308
+ const meta = {
1309
+ 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`,
1310
+ pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
1311
+ filesCreated,
1312
+ time: (0, node_util.styleText)("green", duration),
1313
+ output: node_path.default.resolve(config.root, config.output.path)
1314
+ };
1315
+ const labels = {
1316
+ plugins: "Plugins:",
1317
+ failed: "Failed:",
1318
+ generated: "Generated:",
1319
+ pluginTimings: "Plugin Timings:",
1320
+ output: "Output:"
1321
+ };
1322
+ const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
1323
+ const summaryLines = [];
1324
+ summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
1325
+ if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
1326
+ summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
1327
+ if (pluginTimings && pluginTimings.size > 0) {
1328
+ const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
1329
+ summaryLines.push(`${labels.pluginTimings}`);
1330
+ sortedTimings.forEach(([name, time]) => {
1331
+ const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
1332
+ const barLength = Math.min(Math.ceil(time / 100), 10);
1333
+ const bar = (0, node_util.styleText)("dim", "█".repeat(barLength));
1334
+ summaryLines.push(`${(0, node_util.styleText)("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
1447
1335
  });
1448
- await hookEndPromise;
1449
1336
  }
1337
+ summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
1338
+ return summaryLines;
1450
1339
  }
1451
1340
  //#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
1341
+ //#region src/runners/generate/utils.ts
1462
1342
  const jiti$1 = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).href, {
1463
1343
  jsx: {
1464
1344
  runtime: "automatic",
@@ -1466,73 +1346,180 @@ const jiti$1 = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).hre
1466
1346
  },
1467
1347
  moduleCache: false
1468
1348
  });
1469
- const tsLoader = async (configFile) => {
1470
- return jiti$1.import(configFile, { default: true });
1471
- };
1472
- async function getCosmiConfig(moduleName, config) {
1473
- let result;
1474
- const searchPlaces = [
1475
- "package.json",
1476
- `.${moduleName}rc`,
1477
- `.${moduleName}rc.json`,
1478
- `.${moduleName}rc.yaml`,
1479
- `.${moduleName}rc.yml`,
1480
- `.${moduleName}rc.ts`,
1481
- `.${moduleName}rc.mts`,
1482
- `.${moduleName}rc.cts`,
1483
- `.${moduleName}rc.js`,
1484
- `.${moduleName}rc.mjs`,
1485
- `.${moduleName}rc.cjs`,
1486
- `${moduleName}.config.ts`,
1487
- `${moduleName}.config.mts`,
1488
- `${moduleName}.config.cts`,
1489
- `${moduleName}.config.js`,
1490
- `${moduleName}.config.mjs`,
1491
- `${moduleName}.config.cjs`
1492
- ];
1493
- const explorer = (0, cosmiconfig.cosmiconfig)(moduleName, {
1349
+ const tsLoader = (configFile) => jiti$1.import(configFile, { default: true });
1350
+ const MODULE_NAME = "kubb";
1351
+ const BASE_SEARCH_PLACES = [
1352
+ "package.json",
1353
+ `.${MODULE_NAME}rc`,
1354
+ `.${MODULE_NAME}rc.json`,
1355
+ `.${MODULE_NAME}rc.yaml`,
1356
+ `.${MODULE_NAME}rc.yml`,
1357
+ `.${MODULE_NAME}rc.ts`,
1358
+ `.${MODULE_NAME}rc.mts`,
1359
+ `.${MODULE_NAME}rc.cts`,
1360
+ `.${MODULE_NAME}rc.js`,
1361
+ `.${MODULE_NAME}rc.mjs`,
1362
+ `.${MODULE_NAME}rc.cjs`,
1363
+ `${MODULE_NAME}.config.ts`,
1364
+ `${MODULE_NAME}.config.mts`,
1365
+ `${MODULE_NAME}.config.cts`,
1366
+ `${MODULE_NAME}.config.js`,
1367
+ `${MODULE_NAME}.config.mjs`,
1368
+ `${MODULE_NAME}.config.cjs`
1369
+ ];
1370
+ const SEARCH_PLACES = [
1371
+ "",
1372
+ ".config/",
1373
+ "configs/"
1374
+ ].flatMap((prefix) => BASE_SEARCH_PLACES.map((p) => `${prefix}${p}`));
1375
+ async function getCosmiConfig(configFile) {
1376
+ const explorer = (0, cosmiconfig.cosmiconfig)(MODULE_NAME, {
1494
1377
  cache: false,
1495
- searchPlaces: [
1496
- ...searchPlaces.map((searchPlace) => {
1497
- return `.config/${searchPlace}`;
1498
- }),
1499
- ...searchPlaces.map((searchPlace) => {
1500
- return `configs/${searchPlace}`;
1501
- }),
1502
- ...searchPlaces
1503
- ],
1378
+ searchPlaces: SEARCH_PLACES,
1504
1379
  loaders: {
1505
1380
  ".ts": tsLoader,
1506
1381
  ".mts": tsLoader,
1507
1382
  ".cts": tsLoader
1508
1383
  }
1509
1384
  });
1385
+ let result;
1510
1386
  try {
1511
- result = config ? await explorer.load(config) : await explorer.search();
1387
+ result = configFile ? await explorer.load(configFile) : await explorer.search();
1512
1388
  } catch (error) {
1513
1389
  throw new Error("Config failed loading", { cause: error });
1514
1390
  }
1515
- 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");
1391
+ 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");
1516
1392
  return result;
1517
1393
  }
1518
- //#endregion
1519
- //#region src/utils/watcher.ts
1520
- async function startWatcher(path, cb) {
1394
+ /**
1395
+ * Discovers the Kubb config via cosmiconfig and resolves it into a normalized array of configs.
1396
+ * Every config in the result is guaranteed to have a `plugins` array.
1397
+ */
1398
+ async function getConfigs({ configPath, input }) {
1399
+ const result = await getCosmiConfig(configPath);
1400
+ const resolved = await (typeof result.config === "function" ? result.config({ input }) : result.config);
1401
+ const userConfigs = Array.isArray(resolved) ? resolved : [resolved];
1402
+ return {
1403
+ configPath: result.filepath,
1404
+ configs: userConfigs.map((item) => ({
1405
+ ...item,
1406
+ plugins: item.plugins ?? []
1407
+ }))
1408
+ };
1409
+ }
1410
+ /**
1411
+ * Runs the `done` hooks defined in a Kubb config in sequence.
1412
+ */
1413
+ async function executeHooks({ configHooks, hooks, makeSink }) {
1414
+ const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
1415
+ for (const command of commands) {
1416
+ const [cmd, ...args] = require_shell.tokenize(command);
1417
+ if (!cmd) continue;
1418
+ const hookId = (0, node_crypto.createHash)("sha256").update(command).digest("hex");
1419
+ const commandWithArgs = [cmd, ...args].join(" ");
1420
+ await hooks.emit("kubb:hook:start", {
1421
+ id: hookId,
1422
+ command: cmd,
1423
+ args
1424
+ });
1425
+ const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs) ?? {};
1426
+ await runHook({
1427
+ id: hookId,
1428
+ command: cmd,
1429
+ args,
1430
+ commandWithArgs,
1431
+ context: hooks,
1432
+ stream,
1433
+ sink: {
1434
+ onLine,
1435
+ onStdout,
1436
+ onStderr
1437
+ }
1438
+ });
1439
+ }
1440
+ }
1441
+ async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
1442
+ const emitEnd = (success, error) => context.emit("kubb:hook:end", {
1443
+ command,
1444
+ args,
1445
+ id,
1446
+ success,
1447
+ error
1448
+ });
1449
+ try {
1450
+ const proc = (0, tinyexec.x)(command, [...args ?? []], {
1451
+ nodeOptions: { detached: process.platform !== "win32" },
1452
+ throwOnError: true
1453
+ });
1454
+ if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
1455
+ const result = await proc;
1456
+ await context.emit("kubb:debug", {
1457
+ date: /* @__PURE__ */ new Date(),
1458
+ logs: [result.stdout.trimEnd()]
1459
+ });
1460
+ await context.emit("kubb:success", { message: `${(0, node_util.styleText)("dim", commandWithArgs)} successfully executed` });
1461
+ await emitEnd(true, null);
1462
+ } catch (err) {
1463
+ if (!(err instanceof tinyexec.NonZeroExitError)) {
1464
+ const error = require_errors.toError(err);
1465
+ await emitEnd(false, error);
1466
+ await context.emit("kubb:error", { error });
1467
+ return;
1468
+ }
1469
+ const stderr = err.output?.stderr ?? "";
1470
+ const stdout = err.output?.stdout ?? "";
1471
+ await context.emit("kubb:debug", {
1472
+ date: /* @__PURE__ */ new Date(),
1473
+ logs: [stdout, stderr].filter(Boolean)
1474
+ });
1475
+ if (stderr) sink?.onStderr?.(stderr);
1476
+ if (stdout) sink?.onStdout?.(stdout);
1477
+ const error = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
1478
+ await emitEnd(false, error);
1479
+ await context.emit("kubb:error", { error });
1480
+ }
1481
+ }
1482
+ /**
1483
+ * Starts a file watcher on the given paths and calls `cb` on any change.
1484
+ * Ignores `.git` and `node_modules` directories.
1485
+ */
1486
+ async function startWatcher(path, cb, log = {
1487
+ info: console.log,
1488
+ error: console.log
1489
+ }) {
1521
1490
  const { watch } = await import("chokidar");
1522
1491
  watch(path, {
1523
1492
  ignorePermissionErrors: true,
1524
1493
  ignored: require_constants.WATCHER_IGNORED_PATHS
1525
1494
  }).on("all", async (type, file) => {
1526
- console.log((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${type} ${file}`)));
1495
+ log.info((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${type} ${file}`)));
1527
1496
  try {
1528
1497
  await cb(path);
1529
1498
  } catch (_e) {
1530
- console.log((0, node_util.styleText)("red", "Watcher failed"));
1499
+ log.error((0, node_util.styleText)("red", "Watcher failed"));
1531
1500
  }
1532
1501
  });
1533
1502
  }
1534
1503
  //#endregion
1535
- //#region src/runners/generate.ts
1504
+ //#region src/runners/generate/run.ts
1505
+ /**
1506
+ * Registers a one-shot `kubb:hook:end` listener for `hookId` BEFORE the caller emits `kubb:hook:start`,
1507
+ * avoiding the race where a synchronous emitter fires end before the listener is attached.
1508
+ */
1509
+ function waitForHookEnd(hooks, hookId, onSuccess, fallbackErrorMessage) {
1510
+ return new Promise((resolve, reject) => {
1511
+ const handler = (ctx) => {
1512
+ if (ctx.id !== hookId) return;
1513
+ hooks.off("kubb:hook:end", handler);
1514
+ if (!ctx.success) {
1515
+ reject(ctx.error ?? new Error(fallbackErrorMessage));
1516
+ return;
1517
+ }
1518
+ onSuccess().then(resolve).catch(reject);
1519
+ };
1520
+ hooks.on("kubb:hook:end", handler);
1521
+ });
1522
+ }
1536
1523
  async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel, hooks, onStart, onEnd }) {
1537
1524
  await onStart();
1538
1525
  let resolvedTool = toolValue;
@@ -1547,24 +1534,14 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1547
1534
  let toolError;
1548
1535
  if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
1549
1536
  const toolConfig = toolMap[resolvedTool];
1537
+ const hookId = (0, node_crypto.createHash)("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
1538
+ const successMessage = [
1539
+ `${successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1540
+ logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1541
+ "successfully"
1542
+ ].filter(Boolean).join(" ");
1550
1543
  try {
1551
- const hookId = (0, node_crypto.createHash)("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
1552
- const hookEndPromise = new Promise((resolve, reject) => {
1553
- const handler = (ctx) => {
1554
- if (ctx.id !== hookId) return;
1555
- hooks.off("kubb:hook:end", handler);
1556
- if (!ctx.success) {
1557
- reject(ctx.error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
1558
- return;
1559
- }
1560
- hooks.emit("kubb:success", { message: [
1561
- `${successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1562
- logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1563
- "successfully"
1564
- ].filter(Boolean).join(" ") }).then(resolve).catch(reject);
1565
- };
1566
- hooks.on("kubb:hook:end", handler);
1567
- });
1544
+ const hookEndPromise = waitForHookEnd(hooks, hookId, () => hooks.emit("kubb:success", { message: successMessage }), toolConfig.errorMessage);
1568
1545
  await hooks.emit("kubb:hook:start", {
1569
1546
  id: hookId,
1570
1547
  command: toolConfig.command,
@@ -1581,7 +1558,7 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1581
1558
  if (toolError) throw toolError;
1582
1559
  }
1583
1560
  async function generate(options) {
1584
- const { input, hooks, logLevel } = options;
1561
+ const { input, hooks, logLevel, makeSink } = options;
1585
1562
  const hrStart = node_process.default.hrtime();
1586
1563
  const inputPath = input ?? (options.config.input && "path" in options.config.input ? options.config.input.path : void 0);
1587
1564
  const config = {
@@ -1605,8 +1582,20 @@ async function generate(options) {
1605
1582
  });
1606
1583
  const { files, failedPlugins, pluginTimings, error, driver } = await kubb.safeBuild();
1607
1584
  await hooks.emit("kubb:info", { message: "Load summary" });
1585
+ const telemetryPlugins = Array.from(driver.plugins.values(), (p) => ({
1586
+ name: p.name,
1587
+ options: p.options
1588
+ }));
1589
+ const reportTelemetry = (status) => require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1590
+ command: "generate",
1591
+ kubbVersion: require_package.version,
1592
+ plugins: telemetryPlugins,
1593
+ hrStart,
1594
+ filesCreated: files.length,
1595
+ status
1596
+ }));
1608
1597
  if (failedPlugins.size > 0 || error) {
1609
- const allErrors = [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean);
1598
+ const allErrors = [error, ...Array.from(failedPlugins, (it) => it.error)].filter(Boolean);
1610
1599
  for (const err of allErrors) await hooks.emit("kubb:error", { error: err });
1611
1600
  await hooks.emit("kubb:generation:end", {
1612
1601
  config,
@@ -1621,21 +1610,11 @@ async function generate(options) {
1621
1610
  hrStart,
1622
1611
  pluginTimings: logLevel >= _kubb_core.logLevel.verbose ? pluginTimings : void 0
1623
1612
  });
1624
- await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1625
- command: "generate",
1626
- kubbVersion: require_package.version,
1627
- plugins: Array.from(driver.plugins.values(), (p) => ({
1628
- name: p.name,
1629
- options: p.options
1630
- })),
1631
- hrStart,
1632
- filesCreated: files.length,
1633
- status: "failed"
1634
- }));
1613
+ await reportTelemetry("failed");
1635
1614
  node_process.default.exit(1);
1636
1615
  }
1637
1616
  await hooks.emit("kubb:success", {
1638
- message: "Generation successfully",
1617
+ message: "Generation succeeded",
1639
1618
  info: inputPath
1640
1619
  });
1641
1620
  await hooks.emit("kubb:generation:end", {
@@ -1644,39 +1623,38 @@ async function generate(options) {
1644
1623
  sources: kubb.sources
1645
1624
  });
1646
1625
  const outputPath = node_path.default.resolve(config.root, config.output.path);
1647
- if (config.output.format) await runToolPass({
1626
+ const toolPasses = [config.output.format && {
1648
1627
  toolValue: config.output.format,
1649
1628
  detect: detectFormatter,
1650
1629
  toolMap: formatters,
1651
1630
  toolLabel: "formatter",
1652
1631
  successPrefix: "Formatting",
1653
1632
  noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
1654
- configName: config.name,
1655
- outputPath,
1656
- logLevel,
1657
- hooks,
1658
1633
  onStart: () => hooks.emit("kubb:format:start"),
1659
1634
  onEnd: () => hooks.emit("kubb:format:end")
1660
- });
1661
- if (config.output.lint) await runToolPass({
1635
+ }, config.output.lint && {
1662
1636
  toolValue: config.output.lint,
1663
1637
  detect: detectLinter,
1664
1638
  toolMap: linters,
1665
1639
  toolLabel: "linter",
1666
1640
  successPrefix: "Linting",
1667
1641
  noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
1642
+ onStart: () => hooks.emit("kubb:lint:start"),
1643
+ onEnd: () => hooks.emit("kubb:lint:end")
1644
+ }].filter(Boolean);
1645
+ for (const pass of toolPasses) await runToolPass({
1646
+ ...pass,
1668
1647
  configName: config.name,
1669
1648
  outputPath,
1670
1649
  logLevel,
1671
- hooks,
1672
- onStart: () => hooks.emit("kubb:lint:start"),
1673
- onEnd: () => hooks.emit("kubb:lint:end")
1650
+ hooks
1674
1651
  });
1675
1652
  if (config.hooks) {
1676
1653
  await hooks.emit("kubb:hooks:start");
1677
1654
  await executeHooks({
1678
1655
  configHooks: config.hooks,
1679
- hooks
1656
+ hooks,
1657
+ makeSink
1680
1658
  });
1681
1659
  await hooks.emit("kubb:hooks:end");
1682
1660
  }
@@ -1688,42 +1666,42 @@ async function generate(options) {
1688
1666
  hrStart,
1689
1667
  pluginTimings
1690
1668
  });
1691
- await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1692
- command: "generate",
1693
- kubbVersion: require_package.version,
1694
- plugins: Array.from(driver.plugins.values(), (p) => ({
1695
- name: p.name,
1696
- options: p.options
1697
- })),
1698
- hrStart,
1699
- filesCreated: files.length,
1700
- status: "success"
1701
- }));
1669
+ await reportTelemetry("success");
1702
1670
  }
1703
- async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }) {
1704
- const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1705
- const hooks = new AsyncEventEmitter();
1706
- await setupLogger(hooks, { logLevel });
1671
+ async function checkForUpdate(hooks) {
1707
1672
  await require_telemetry.executeIfOnline(async () => {
1708
1673
  try {
1709
- const latestVersion = (await (await fetch(require_constants.KUBB_NPM_PACKAGE_URL)).json()).version;
1710
- if (latestVersion && require_package.version < latestVersion) await hooks.emit("kubb:version:new", {
1674
+ const data = await (await fetch(require_constants.KUBB_NPM_PACKAGE_URL)).json();
1675
+ if (data.version && require_package.version < data.version) await hooks.emit("kubb:version:new", {
1711
1676
  currentVersion: require_package.version,
1712
- latestVersion
1677
+ latestVersion: data.version
1713
1678
  });
1714
1679
  } catch {}
1715
1680
  });
1681
+ }
1682
+ /**
1683
+ * Runs the full Kubb generation lifecycle for the given CLI options.
1684
+ * Sets up the logger, checks for a newer version, loads configs, and calls `generate` for each config entry.
1685
+ */
1686
+ async function run({ input, configPath, logLevel: logLevelKey, watch }) {
1687
+ const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1688
+ const hooks = new AsyncEventEmitter();
1689
+ const makeSink = await setupLogger(hooks, { logLevel });
1690
+ await checkForUpdate(hooks);
1716
1691
  try {
1717
- const result = await getCosmiConfig("kubb", configPath);
1718
- const configs = await getConfigs(result.config, { input });
1692
+ const { configs, configPath: resolvedConfigPath } = await getConfigs({
1693
+ configPath,
1694
+ input
1695
+ });
1696
+ const relativeConfigPath = node_path.default.relative(node_process.default.cwd(), resolvedConfigPath);
1719
1697
  await hooks.emit("kubb:config:start");
1720
1698
  await hooks.emit("kubb:info", {
1721
1699
  message: "Config loaded",
1722
- info: node_path.default.relative(node_process.default.cwd(), result.filepath)
1700
+ info: relativeConfigPath
1723
1701
  });
1724
1702
  await hooks.emit("kubb:success", {
1725
1703
  message: "Config loaded successfully",
1726
- info: node_path.default.relative(node_process.default.cwd(), result.filepath)
1704
+ info: relativeConfigPath
1727
1705
  });
1728
1706
  await hooks.emit("kubb:config:end", { configs });
1729
1707
  await hooks.emit("kubb:lifecycle:start", { version: require_package.version });
@@ -1733,15 +1711,20 @@ async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, wa
1733
1711
  input,
1734
1712
  config,
1735
1713
  logLevel,
1736
- hooks
1714
+ hooks,
1715
+ makeSink
1737
1716
  });
1738
1717
  _clack_prompts.log.step((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
1718
+ }, {
1719
+ info: (msg) => _clack_prompts.log.info(msg),
1720
+ error: (msg) => _clack_prompts.log.error(msg)
1739
1721
  });
1740
1722
  else await generate({
1741
1723
  input,
1742
1724
  config,
1743
1725
  logLevel,
1744
- hooks
1726
+ hooks,
1727
+ makeSink
1745
1728
  });
1746
1729
  await hooks.emit("kubb:lifecycle:end");
1747
1730
  } catch (error) {
@@ -1750,6 +1733,6 @@ async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, wa
1750
1733
  }
1751
1734
  }
1752
1735
  //#endregion
1753
- exports.runGenerateCommand = runGenerateCommand;
1736
+ exports.run = run;
1754
1737
 
1755
- //# sourceMappingURL=generate-B_p5dl68.cjs.map
1738
+ //# sourceMappingURL=run-CqKd6JNc.cjs.map