@kubb/cli 5.0.0-alpha.5 → 5.0.0-alpha.50

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 (138) hide show
  1. package/README.md +4 -2
  2. package/bin/kubb.js +6 -0
  3. package/dist/agent-Bt-Z24BD.cjs +116 -0
  4. package/dist/agent-Bt-Z24BD.cjs.map +1 -0
  5. package/dist/{agent-SWUT_sgq.js → agent-CHqQt6-j.js} +5 -5
  6. package/dist/agent-CHqQt6-j.js.map +1 -0
  7. package/dist/agent-LgBdb1gx.js +112 -0
  8. package/dist/agent-LgBdb1gx.js.map +1 -0
  9. package/dist/{agent-CEHZSBVT.cjs → agent-l26FqXrz.cjs} +5 -5
  10. package/dist/agent-l26FqXrz.cjs.map +1 -0
  11. package/dist/{constants-BTUap0zs.cjs → constants-B2q7VPbi.cjs} +91 -9
  12. package/dist/constants-B2q7VPbi.cjs.map +1 -0
  13. package/dist/constants-T_2rsi7T.js +137 -0
  14. package/dist/constants-T_2rsi7T.js.map +1 -0
  15. package/dist/define-Bdn8j5VM.cjs +54 -0
  16. package/dist/define-Bdn8j5VM.cjs.map +1 -0
  17. package/dist/define-Ctii4bel.js +43 -0
  18. package/dist/define-Ctii4bel.js.map +1 -0
  19. package/dist/{errors-DBW0N9w4.cjs → errors-CLCjoSg0.cjs} +22 -6
  20. package/dist/errors-CLCjoSg0.cjs.map +1 -0
  21. package/dist/errors-CjPmyZHy.js +43 -0
  22. package/dist/errors-CjPmyZHy.js.map +1 -0
  23. package/dist/{generate-CNkdrX6u.cjs → generate-BSqljMWH.cjs} +3 -3
  24. package/dist/generate-BSqljMWH.cjs.map +1 -0
  25. package/dist/{generate-CtFkZeTU.js → generate-CQPHU8Xt.js} +493 -248
  26. package/dist/generate-CQPHU8Xt.js.map +1 -0
  27. package/dist/{generate-nJaqPdGL.cjs → generate-I-SQLa8R.cjs} +500 -255
  28. package/dist/generate-I-SQLa8R.cjs.map +1 -0
  29. package/dist/{generate-CfoLoEd0.js → generate-TP0il_KX.js} +3 -3
  30. package/dist/generate-TP0il_KX.js.map +1 -0
  31. package/dist/index.cjs +49 -21
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +49 -21
  35. package/dist/index.js.map +1 -1
  36. package/dist/{init-D_oERuMn.js → init-13Vizgki.js} +4 -4
  37. package/dist/init-13Vizgki.js.map +1 -0
  38. package/dist/{init-hmolV6B4.cjs → init-AVT-2Uxi.cjs} +31 -21
  39. package/dist/init-AVT-2Uxi.cjs.map +1 -0
  40. package/dist/{init-C-InrmSY.js → init-BecEYFRb.js} +27 -17
  41. package/dist/init-BecEYFRb.js.map +1 -0
  42. package/dist/{init-BAs1d5rK.cjs → init-POdCjZS0.cjs} +4 -4
  43. package/dist/init-POdCjZS0.cjs.map +1 -0
  44. package/dist/{mcp-D2SHEg_d.js → mcp-BDHEbuy3.js} +11 -4
  45. package/dist/mcp-BDHEbuy3.js.map +1 -0
  46. package/dist/{mcp-DEvDB6FY.cjs → mcp-BotRrBI-.cjs} +4 -4
  47. package/dist/{mcp-DEvDB6FY.cjs.map → mcp-BotRrBI-.cjs.map} +1 -1
  48. package/dist/{mcp-ChHFPRzD.cjs → mcp-CqpVw3PO.cjs} +12 -6
  49. package/dist/mcp-CqpVw3PO.cjs.map +1 -0
  50. package/dist/{mcp-jKYiomZT.js → mcp-q4XumdSd.js} +4 -4
  51. package/dist/{mcp-jKYiomZT.js.map → mcp-q4XumdSd.js.map} +1 -1
  52. package/dist/package-BRmZkKt7.js +6 -0
  53. package/dist/package-BRmZkKt7.js.map +1 -0
  54. package/dist/{package-C-fC2Eoy.cjs → package-D86Y6wqb.cjs} +2 -2
  55. package/dist/package-D86Y6wqb.cjs.map +1 -0
  56. package/dist/{shell-7HPrTCJ5.cjs → shell-475fQKaX.cjs} +8 -3
  57. package/dist/shell-475fQKaX.cjs.map +1 -0
  58. package/dist/{shell-DqqWsHCD.js → shell-DLzN4fRo.js} +8 -3
  59. package/dist/shell-DLzN4fRo.js.map +1 -0
  60. package/dist/{telemetry-Cn9X1I5B.cjs → telemetry-B6ZbZOrb.cjs} +50 -8
  61. package/dist/telemetry-B6ZbZOrb.cjs.map +1 -0
  62. package/dist/{telemetry-DxiR7clS.js → telemetry-Dis5nWR_.js} +48 -6
  63. package/dist/telemetry-Dis5nWR_.js.map +1 -0
  64. package/dist/{validate--IXRJEhp.js → validate-AV-0RFuL.js} +4 -4
  65. package/dist/validate-AV-0RFuL.js.map +1 -0
  66. package/dist/{validate-BK3pc8zv.cjs → validate-Cu8Sfj-n.cjs} +4 -4
  67. package/dist/validate-Cu8Sfj-n.cjs.map +1 -0
  68. package/dist/{validate-Bbrn3Q-A.cjs → validate-D-8_wAFV.cjs} +6 -14
  69. package/dist/validate-D-8_wAFV.cjs.map +1 -0
  70. package/dist/{validate-l8vLmwKA.js → validate-GfErHsnI.js} +5 -13
  71. package/dist/validate-GfErHsnI.js.map +1 -0
  72. package/package.json +47 -46
  73. package/src/commands/agent/start.ts +20 -4
  74. package/src/commands/generate.ts +35 -6
  75. package/src/commands/init.ts +6 -1
  76. package/src/commands/validate.ts +6 -1
  77. package/src/constants.ts +65 -11
  78. package/src/index.ts +10 -12
  79. package/src/loggers/clackLogger.ts +54 -46
  80. package/src/loggers/fileSystemLogger.ts +13 -11
  81. package/src/loggers/githubActionsLogger.ts +22 -22
  82. package/src/loggers/plainLogger.ts +21 -21
  83. package/src/runners/agent.ts +81 -34
  84. package/src/runners/generate.ts +90 -109
  85. package/src/runners/init.ts +9 -9
  86. package/src/runners/mcp.ts +19 -3
  87. package/src/runners/validate.ts +19 -15
  88. package/src/types.ts +11 -0
  89. package/src/utils/executeHooks.ts +11 -11
  90. package/src/utils/flags.ts +10 -0
  91. package/src/utils/getConfig.ts +10 -0
  92. package/src/utils/getCosmiConfig.ts +9 -3
  93. package/src/utils/getSummary.ts +1 -1
  94. package/src/utils/runHook.ts +27 -9
  95. package/src/utils/telemetry.ts +16 -3
  96. package/bin/kubb.cjs +0 -18
  97. package/dist/agent-C6o_6GSJ.cjs +0 -92
  98. package/dist/agent-C6o_6GSJ.cjs.map +0 -1
  99. package/dist/agent-CEHZSBVT.cjs.map +0 -1
  100. package/dist/agent-L50VNhXv.js +0 -88
  101. package/dist/agent-L50VNhXv.js.map +0 -1
  102. package/dist/agent-SWUT_sgq.js.map +0 -1
  103. package/dist/constants-BTUap0zs.cjs.map +0 -1
  104. package/dist/constants-CM3dJzjK.js +0 -67
  105. package/dist/constants-CM3dJzjK.js.map +0 -1
  106. package/dist/define--M_JMcDC.js +0 -25
  107. package/dist/define--M_JMcDC.js.map +0 -1
  108. package/dist/define-D6Kfm7-Z.cjs +0 -36
  109. package/dist/define-D6Kfm7-Z.cjs.map +0 -1
  110. package/dist/errors-6mF_WKxg.js +0 -27
  111. package/dist/errors-6mF_WKxg.js.map +0 -1
  112. package/dist/errors-DBW0N9w4.cjs.map +0 -1
  113. package/dist/generate-CNkdrX6u.cjs.map +0 -1
  114. package/dist/generate-CfoLoEd0.js.map +0 -1
  115. package/dist/generate-CtFkZeTU.js.map +0 -1
  116. package/dist/generate-nJaqPdGL.cjs.map +0 -1
  117. package/dist/init-BAs1d5rK.cjs.map +0 -1
  118. package/dist/init-C-InrmSY.js.map +0 -1
  119. package/dist/init-D_oERuMn.js.map +0 -1
  120. package/dist/init-hmolV6B4.cjs.map +0 -1
  121. package/dist/jiti-Cd3S0xwr.cjs +0 -16
  122. package/dist/jiti-Cd3S0xwr.cjs.map +0 -1
  123. package/dist/jiti-e08mD2Ph.js +0 -11
  124. package/dist/jiti-e08mD2Ph.js.map +0 -1
  125. package/dist/mcp-ChHFPRzD.cjs.map +0 -1
  126. package/dist/mcp-D2SHEg_d.js.map +0 -1
  127. package/dist/package-C-fC2Eoy.cjs.map +0 -1
  128. package/dist/package-DxH_MEG4.js +0 -6
  129. package/dist/package-DxH_MEG4.js.map +0 -1
  130. package/dist/shell-7HPrTCJ5.cjs.map +0 -1
  131. package/dist/shell-DqqWsHCD.js.map +0 -1
  132. package/dist/telemetry-Cn9X1I5B.cjs.map +0 -1
  133. package/dist/telemetry-DxiR7clS.js.map +0 -1
  134. package/dist/validate--IXRJEhp.js.map +0 -1
  135. package/dist/validate-BK3pc8zv.cjs.map +0 -1
  136. package/dist/validate-Bbrn3Q-A.cjs.map +0 -1
  137. package/dist/validate-l8vLmwKA.js.map +0 -1
  138. package/src/utils/getIntro.ts +0 -1
@@ -1,20 +1,21 @@
1
1
  const require_chunk = require("./chunk-ByKO4r7w.cjs");
2
- const require_errors = require("./errors-DBW0N9w4.cjs");
3
- const require_telemetry = require("./telemetry-Cn9X1I5B.cjs");
4
- const require_shell = require("./shell-7HPrTCJ5.cjs");
5
- const require_package = require("./package-C-fC2Eoy.cjs");
6
- const require_constants = require("./constants-BTUap0zs.cjs");
2
+ const require_errors = require("./errors-CLCjoSg0.cjs");
3
+ const require_telemetry = require("./telemetry-B6ZbZOrb.cjs");
4
+ const require_shell = require("./shell-475fQKaX.cjs");
5
+ const require_package = require("./package-D86Y6wqb.cjs");
6
+ const require_constants = require("./constants-B2q7VPbi.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");
10
- require("node:fs");
10
+ let node_child_process = require("node:child_process");
11
+ let node_fs = require("node:fs");
11
12
  let node_fs_promises = require("node:fs/promises");
12
13
  let node_path = require("node:path");
13
- node_path = require_chunk.__toESM(node_path);
14
+ node_path = require_chunk.__toESM(node_path, 1);
14
15
  let node_process = require("node:process");
15
- node_process = require_chunk.__toESM(node_process);
16
+ node_process = require_chunk.__toESM(node_process, 1);
16
17
  let _clack_prompts = require("@clack/prompts");
17
- _clack_prompts = require_chunk.__toESM(_clack_prompts);
18
+ _clack_prompts = require_chunk.__toESM(_clack_prompts, 1);
18
19
  let _kubb_core = require("@kubb/core");
19
20
  let tinyexec = require("tinyexec");
20
21
  let node_stream = require("node:stream");
@@ -22,12 +23,19 @@ let cosmiconfig = require("cosmiconfig");
22
23
  let jiti = require("jiti");
23
24
  //#region ../../internals/utils/src/asyncEventEmitter.ts
24
25
  /**
25
- * A typed EventEmitter that awaits all async listeners before resolving.
26
+ * Typed `EventEmitter` that awaits all async listeners before resolving.
26
27
  * Wraps Node's `EventEmitter` with full TypeScript event-map inference.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
32
+ * emitter.on('build', async (name) => { console.log(name) })
33
+ * await emitter.emit('build', 'petstore') // all listeners awaited
34
+ * ```
27
35
  */
28
36
  var AsyncEventEmitter = class {
29
37
  /**
30
- * `maxListener` controls the maximum number of listeners per event before Node emits a memory-leak warning.
38
+ * Maximum number of listeners per event before Node emits a memory-leak warning.
31
39
  * @default 10
32
40
  */
33
41
  constructor(maxListener = 10) {
@@ -35,31 +43,48 @@ var AsyncEventEmitter = class {
35
43
  }
36
44
  #emitter = new node_events.EventEmitter();
37
45
  /**
38
- * Emits an event and awaits all registered listeners in parallel.
46
+ * Emits `eventName` and awaits all registered listeners sequentially.
39
47
  * Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * await emitter.emit('build', 'petstore')
52
+ * ```
40
53
  */
41
54
  async emit(eventName, ...eventArgs) {
42
55
  const listeners = this.#emitter.listeners(eventName);
43
56
  if (listeners.length === 0) return;
44
- await Promise.all(listeners.map(async (listener) => {
57
+ for (const listener of listeners) try {
58
+ await listener(...eventArgs);
59
+ } catch (err) {
60
+ let serializedArgs;
45
61
  try {
46
- return await listener(...eventArgs);
47
- } catch (err) {
48
- let serializedArgs;
49
- try {
50
- serializedArgs = JSON.stringify(eventArgs);
51
- } catch {
52
- serializedArgs = String(eventArgs);
53
- }
54
- throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: require_errors.toError(err) });
62
+ serializedArgs = JSON.stringify(eventArgs);
63
+ } catch {
64
+ serializedArgs = String(eventArgs);
55
65
  }
56
- }));
66
+ throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: require_errors.toError(err) });
67
+ }
57
68
  }
58
- /** Registers a persistent listener for the given event. */
69
+ /**
70
+ * Registers a persistent listener for `eventName`.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * emitter.on('build', async (name) => { console.log(name) })
75
+ * ```
76
+ */
59
77
  on(eventName, handler) {
60
78
  this.#emitter.on(eventName, handler);
61
79
  }
62
- /** Registers a one-shot listener that removes itself after the first invocation. */
80
+ /**
81
+ * Registers a one-shot listener that removes itself after the first invocation.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * emitter.onOnce('build', async (name) => { console.log(name) })
86
+ * ```
87
+ */
63
88
  onOnce(eventName, handler) {
64
89
  const wrapper = (...args) => {
65
90
  this.off(eventName, wrapper);
@@ -67,11 +92,37 @@ var AsyncEventEmitter = class {
67
92
  };
68
93
  this.on(eventName, wrapper);
69
94
  }
70
- /** Removes a previously registered listener. */
95
+ /**
96
+ * Removes a previously registered listener.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * emitter.off('build', handler)
101
+ * ```
102
+ */
71
103
  off(eventName, handler) {
72
104
  this.#emitter.off(eventName, handler);
73
105
  }
74
- /** Removes all listeners from every event channel. */
106
+ /**
107
+ * Returns the number of listeners registered for `eventName`.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * emitter.on('build', handler)
112
+ * emitter.listenerCount('build') // 1
113
+ * ```
114
+ */
115
+ listenerCount(eventName) {
116
+ return this.#emitter.listenerCount(eventName);
117
+ }
118
+ /**
119
+ * Removes all listeners from every event channel.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * emitter.removeAll()
124
+ * ```
125
+ */
75
126
  removeAll() {
76
127
  this.#emitter.removeAllListeners();
77
128
  }
@@ -79,8 +130,15 @@ var AsyncEventEmitter = class {
79
130
  //#endregion
80
131
  //#region ../../internals/utils/src/time.ts
81
132
  /**
82
- * Calculates elapsed time in milliseconds from a high-resolution start time.
83
- * Rounds to 2 decimal places to provide sub-millisecond precision without noise.
133
+ * Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
134
+ * Rounds to 2 decimal places for sub-millisecond precision without noise.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const start = process.hrtime()
139
+ * doWork()
140
+ * getElapsedMs(start) // 42.35
141
+ * ```
84
142
  */
85
143
  function getElapsedMs(hrStart) {
86
144
  const [seconds, nanoseconds] = process.hrtime(hrStart);
@@ -88,8 +146,14 @@ function getElapsedMs(hrStart) {
88
146
  return Math.round(ms * 100) / 100;
89
147
  }
90
148
  /**
91
- * Converts a millisecond duration into a human-readable string.
92
- * Adjusts units (ms, s, m s) based on the magnitude of the duration.
149
+ * Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * formatMs(250) // '250ms'
154
+ * formatMs(1500) // '1.50s'
155
+ * formatMs(90000) // '1m 30.0s'
156
+ * ```
93
157
  */
94
158
  function formatMs(ms) {
95
159
  if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
@@ -97,7 +161,14 @@ function formatMs(ms) {
97
161
  return `${Math.round(ms)}ms`;
98
162
  }
99
163
  /**
100
- * Convenience helper: formats the elapsed time since `hrStart` in one step.
164
+ * Formats the elapsed time since `hrStart` as a human-readable string.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const start = process.hrtime()
169
+ * doWork()
170
+ * formatHrtime(start) // '1.50s'
171
+ * ```
101
172
  */
102
173
  function formatHrtime(hrStart) {
103
174
  return formatMs(getElapsedMs(hrStart));
@@ -139,7 +210,9 @@ function gradient(colorStops, text) {
139
210
  return `\x1b[38;2;${Math.round(from.r + (to.r - from.r) * lt)};${Math.round(from.g + (to.g - from.g) * lt)};${Math.round(from.b + (to.b - from.b) * lt)}m${char}\x1b[0m`;
140
211
  }).join("");
141
212
  }
142
- /** ANSI color functions for each part of the Kubb mascot illustration. */
213
+ /**
214
+ * ANSI color functions for each part of the Kubb mascot illustration.
215
+ */
143
216
  const palette = {
144
217
  lid: hex("#F55A17"),
145
218
  woodTop: hex("#F5A217"),
@@ -150,7 +223,12 @@ const palette = {
150
223
  blush: hex("#FDA4AF")
151
224
  };
152
225
  /**
153
- * Generates the Kubb mascot welcome banner.
226
+ * Generates the Kubb mascot welcome banner as an ANSI-colored string.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * console.log(getIntro({ title: 'kubb.config.ts', description: 'generating…', version: '5.0.0', areEyesOpen: true }))
231
+ * ```
154
232
  */
155
233
  function getIntro({ title, description, version, areEyesOpen }) {
156
234
  const kubbVersion = gradient([
@@ -168,7 +246,13 @@ function getIntro({ title, description, version, areEyesOpen }) {
168
246
  ${palette.woodBase("▀▀▀▀▀▀▀▀▀▀▀▀▀")}
169
247
  `;
170
248
  }
171
- /** ANSI color names available for terminal output. */
249
+ /** ANSI color names available for deterministic terminal coloring.
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * const color = randomColors[2] // 'green'
254
+ * ```
255
+ */
172
256
  const randomColors = [
173
257
  "black",
174
258
  "red",
@@ -181,15 +265,27 @@ const randomColors = [
181
265
  "gray"
182
266
  ];
183
267
  /**
184
- * Returns the text wrapped in a deterministic ANSI color derived from the text's SHA-256 hash.
268
+ * Wraps `text` in a deterministic ANSI color derived from the text's SHA-256 hash.
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * randomCliColor('petstore') // '\x1b[33m' + 'petstore' + '\x1b[39m' (always the same color for 'petstore')
273
+ * ```
185
274
  */
186
275
  function randomCliColor(text) {
187
276
  if (!text) return "";
188
277
  return (0, node_util.styleText)(randomColors[(0, node_crypto.createHash)("sha256").update(text).digest().readUInt32BE(0) % randomColors.length] ?? "white", text);
189
278
  }
190
279
  /**
191
- * Formats a millisecond duration with an ANSI color based on thresholds:
192
- * green 500 ms · yellow 1 000 ms · red > 1 000 ms
280
+ * Formats a millisecond duration with a threshold-based ANSI color.
281
+ * `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * formatMsWithColor(200) // '\x1b[32m200ms\x1b[39m'
286
+ * formatMsWithColor(800) // '\x1b[33m800ms\x1b[39m'
287
+ * formatMsWithColor(1500) // '\x1b[31m1.50s\x1b[39m'
288
+ * ```
193
289
  */
194
290
  function formatMsWithColor(ms) {
195
291
  const formatted = formatMs(ms);
@@ -198,27 +294,96 @@ function formatMsWithColor(ms) {
198
294
  return (0, node_util.styleText)("red", formatted);
199
295
  }
200
296
  //#endregion
297
+ //#region ../../internals/utils/src/formatters.ts
298
+ /**
299
+ * CLI command descriptors for each supported code formatter.
300
+ *
301
+ * Each entry contains the executable `command`, an `args` factory that maps an
302
+ * output path to the correct argument list, and an `errorMessage` shown when
303
+ * the formatter is not found.
304
+ */
305
+ const formatters = {
306
+ prettier: {
307
+ command: "prettier",
308
+ args: (outputPath) => [
309
+ "--ignore-unknown",
310
+ "--write",
311
+ outputPath
312
+ ],
313
+ errorMessage: "Prettier not found"
314
+ },
315
+ biome: {
316
+ command: "biome",
317
+ args: (outputPath) => [
318
+ "format",
319
+ "--write",
320
+ outputPath
321
+ ],
322
+ errorMessage: "Biome not found"
323
+ },
324
+ oxfmt: {
325
+ command: "oxfmt",
326
+ args: (outputPath) => [outputPath],
327
+ errorMessage: "Oxfmt not found"
328
+ }
329
+ };
330
+ async function isFormatterAvailable(formatter) {
331
+ return new Promise((resolve) => {
332
+ const child = (0, node_child_process.spawn)(formatter, ["--version"], { stdio: "ignore" });
333
+ child.on("close", (code) => resolve(code === 0));
334
+ child.on("error", () => resolve(false));
335
+ });
336
+ }
337
+ /**
338
+ * Detects the first available code formatter on the current system.
339
+ *
340
+ * - Checks in preference order: `oxfmt`, `biome`, `prettier`.
341
+ * - Returns `null` when none are found.
342
+ *
343
+ * @example
344
+ * ```ts
345
+ * const formatter = await detectFormatter()
346
+ * if (formatter) {
347
+ * console.log(`Using ${formatter} for formatting`)
348
+ * }
349
+ * ```
350
+ */
351
+ async function detectFormatter() {
352
+ const formatterNames = new Set([
353
+ "oxfmt",
354
+ "biome",
355
+ "prettier"
356
+ ]);
357
+ for (const formatter of formatterNames) if (await isFormatterAvailable(formatter)) return formatter;
358
+ return null;
359
+ }
360
+ //#endregion
201
361
  //#region ../../internals/utils/src/fs.ts
202
362
  /**
203
363
  * Writes `data` to `path`, trimming leading/trailing whitespace before saving.
204
- * Skips the write and returns `undefined` when the trimmed content is empty or
205
- * identical to what is already on disk.
364
+ * Skips the write when the trimmed content is empty or identical to what is already on disk.
206
365
  * Creates any missing parent directories automatically.
207
- * When `sanity` is `true`, re-reads the file after writing and throws if the
208
- * content does not match.
366
+ * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * await write('./src/Pet.ts', source) // writes and returns trimmed content
371
+ * await write('./src/Pet.ts', source) // null — file unchanged
372
+ * await write('./src/Pet.ts', ' ') // null — empty content skipped
373
+ * ```
209
374
  */
210
375
  async function write(path, data, options = {}) {
211
376
  const trimmed = data.trim();
212
- if (trimmed === "") return void 0;
377
+ if (trimmed === "") return null;
213
378
  const resolved = (0, node_path.resolve)(path);
214
379
  if (typeof Bun !== "undefined") {
215
380
  const file = Bun.file(resolved);
216
- if ((await file.exists() ? await file.text() : null) === trimmed) return void 0;
381
+ if ((await file.exists() ? await file.text() : null) === trimmed) return null;
217
382
  await Bun.write(resolved, trimmed);
218
383
  return trimmed;
219
384
  }
220
385
  try {
221
- if (await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" }) === trimmed) return void 0;
386
+ if (await (0, node_fs_promises.readFile)(resolved, { encoding: "utf-8" }) === trimmed) return null;
222
387
  } catch {}
223
388
  await (0, node_fs_promises.mkdir)((0, node_path.dirname)(resolved), { recursive: true });
224
389
  await (0, node_fs_promises.writeFile)(resolved, trimmed, { encoding: "utf-8" });
@@ -230,6 +395,83 @@ async function write(path, data, options = {}) {
230
395
  return trimmed;
231
396
  }
232
397
  //#endregion
398
+ //#region ../../internals/utils/src/linters.ts
399
+ /**
400
+ * Collects all files under `dir` recursively using Node's built-in fs APIs.
401
+ *
402
+ * Passing explicit file paths to oxlint (instead of a directory) bypasses
403
+ * oxlint's `.gitignore`-aware directory traversal, which would otherwise skip
404
+ * files that are listed in `.gitignore` (e.g. generated output directories).
405
+ */
406
+ function findLintableFiles(dir) {
407
+ try {
408
+ return (0, node_fs.readdirSync)(dir, {
409
+ withFileTypes: true,
410
+ recursive: true
411
+ }).filter((d) => d.isFile()).map((d) => `${d.parentPath}/${d.name}`);
412
+ } catch {
413
+ return [];
414
+ }
415
+ }
416
+ /**
417
+ * CLI command descriptors for each supported linter.
418
+ *
419
+ * Each entry contains the executable `command`, an `args` factory that maps an
420
+ * output path to the correct argument list, and an `errorMessage` shown when
421
+ * the linter is not found.
422
+ */
423
+ const linters = {
424
+ eslint: {
425
+ command: "eslint",
426
+ args: (outputPath) => [outputPath, "--fix"],
427
+ errorMessage: "Eslint not found"
428
+ },
429
+ biome: {
430
+ command: "biome",
431
+ args: (outputPath) => [
432
+ "lint",
433
+ "--fix",
434
+ outputPath
435
+ ],
436
+ errorMessage: "Biome not found"
437
+ },
438
+ oxlint: {
439
+ command: "oxlint",
440
+ args: (outputPath) => ["--fix", ...findLintableFiles(outputPath)],
441
+ errorMessage: "Oxlint not found"
442
+ }
443
+ };
444
+ async function isLinterAvailable(linter) {
445
+ return new Promise((resolve) => {
446
+ const child = (0, node_child_process.spawn)(linter, ["--version"], { stdio: "ignore" });
447
+ child.on("close", (code) => resolve(code === 0));
448
+ child.on("error", () => resolve(false));
449
+ });
450
+ }
451
+ /**
452
+ * Detects the first available linter on the current system.
453
+ *
454
+ * - Checks in preference order: `oxlint`, `biome`, `eslint`.
455
+ * - Returns `null` when none are found.
456
+ *
457
+ * @example
458
+ * ```ts
459
+ * const linter = await detectLinter()
460
+ * if (linter) {
461
+ * console.log(`Using ${linter} for linting`)
462
+ * }
463
+ * ```
464
+ */
465
+ async function detectLinter() {
466
+ const linterNames = new Set([
467
+ "oxlint",
468
+ "biome",
469
+ "eslint"
470
+ ]);
471
+ for (const linter of linterNames) if (await isLinterAvailable(linter)) return linter;
472
+ return null;
473
+ }
474
+ //#endregion
233
475
  //#region src/utils/getSummary.ts
234
476
  function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
235
477
  const duration = formatHrtime(hrStart);
@@ -240,7 +482,7 @@ function getSummary({ failedPlugins, filesCreated, status, hrStart, config, plug
240
482
  pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
241
483
  filesCreated,
242
484
  time: (0, node_util.styleText)("green", duration),
243
- output: node_path.default.isAbsolute(config.root) ? node_path.default.resolve(config.root, config.output.path) : config.root
485
+ output: node_path.default.resolve(config.root, config.output.path)
244
486
  };
245
487
  const labels = {
246
488
  plugins: "Plugins:",
@@ -282,11 +524,11 @@ async function runHook({ id, command, args, commandWithArgs, context, stream = f
282
524
  });
283
525
  if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
284
526
  const result = await proc;
285
- await context.emit("debug", {
527
+ await context.emit("kubb:debug", {
286
528
  date: /* @__PURE__ */ new Date(),
287
529
  logs: [result.stdout.trimEnd()]
288
530
  });
289
- await context.emit("hook:end", {
531
+ await context.emit("kubb:hook:end", {
290
532
  command,
291
533
  args,
292
534
  id,
@@ -295,33 +537,33 @@ async function runHook({ id, command, args, commandWithArgs, context, stream = f
295
537
  });
296
538
  } catch (err) {
297
539
  if (!(err instanceof tinyexec.NonZeroExitError)) {
298
- await context.emit("hook:end", {
540
+ await context.emit("kubb:hook:end", {
299
541
  command,
300
542
  args,
301
543
  id,
302
544
  success: false,
303
545
  error: require_errors.toError(err)
304
546
  });
305
- await context.emit("error", require_errors.toError(err));
547
+ await context.emit("kubb:error", require_errors.toError(err));
306
548
  return;
307
549
  }
308
550
  const stderr = err.output?.stderr ?? "";
309
551
  const stdout = err.output?.stdout ?? "";
310
- await context.emit("debug", {
552
+ await context.emit("kubb:debug", {
311
553
  date: /* @__PURE__ */ new Date(),
312
554
  logs: [stdout, stderr].filter(Boolean)
313
555
  });
314
556
  if (stderr) sink?.onStderr?.(stderr);
315
557
  if (stdout) sink?.onStdout?.(stdout);
316
558
  const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
317
- await context.emit("hook:end", {
559
+ await context.emit("kubb:hook:end", {
318
560
  command,
319
561
  args,
320
562
  id,
321
563
  success: false,
322
564
  error: errorMessage
323
565
  });
324
- await context.emit("error", errorMessage);
566
+ await context.emit("kubb:error", errorMessage);
325
567
  }
326
568
  }
327
569
  //#endregion
@@ -389,7 +631,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
389
631
  state.spinner.stop(text);
390
632
  state.isSpinning = false;
391
633
  }
392
- context.on("info", (message, info = "") => {
634
+ context.on("kubb:info", (message, info = "") => {
393
635
  if (logLevel <= _kubb_core.logLevel.silent) return;
394
636
  const text = getMessage([
395
637
  (0, node_util.styleText)("blue", "ℹ"),
@@ -399,7 +641,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
399
641
  if (state.isSpinning) state.spinner.message(text);
400
642
  else _clack_prompts.log.info(text);
401
643
  });
402
- context.on("success", (message, info = "") => {
644
+ context.on("kubb:success", (message, info = "") => {
403
645
  if (logLevel <= _kubb_core.logLevel.silent) return;
404
646
  const text = getMessage([
405
647
  (0, node_util.styleText)("blue", "✓"),
@@ -409,7 +651,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
409
651
  if (state.isSpinning) stopSpinner(text);
410
652
  else _clack_prompts.log.success(text);
411
653
  });
412
- context.on("warn", (message, info) => {
654
+ context.on("kubb:warn", (message, info) => {
413
655
  if (logLevel < _kubb_core.logLevel.warn) return;
414
656
  const text = getMessage([
415
657
  (0, node_util.styleText)("yellow", "⚠"),
@@ -418,7 +660,7 @@ const clackLogger = (0, _kubb_core.defineLogger)({
418
660
  ].filter(Boolean).join(" "));
419
661
  _clack_prompts.log.warn(text);
420
662
  });
421
- context.on("error", (error) => {
663
+ context.on("kubb:error", (error) => {
422
664
  const caused = require_errors.toCause(error);
423
665
  const text = [(0, node_util.styleText)("red", "✗"), error.message].join(" ");
424
666
  if (state.isSpinning) stopSpinner(getMessage(text));
@@ -433,19 +675,24 @@ const clackLogger = (0, _kubb_core.defineLogger)({
433
675
  }
434
676
  }
435
677
  });
436
- context.on("version:new", (version, latestVersion) => {
678
+ context.on("kubb:version:new", (version, latestVersion) => {
437
679
  if (logLevel <= _kubb_core.logLevel.silent) return;
438
- _clack_prompts.box(`\`v${version}\` → \`v${latestVersion}\`
680
+ try {
681
+ _clack_prompts.box(`\`v${version}\` → \`v${latestVersion}\`
439
682
  Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
440
- width: "auto",
441
- formatBorder: (s) => (0, node_util.styleText)("yellow", s),
442
- rounded: true,
443
- withGuide: false,
444
- contentAlign: "center",
445
- titleAlign: "center"
446
- });
683
+ width: "auto",
684
+ formatBorder: (s) => (0, node_util.styleText)("yellow", s),
685
+ rounded: true,
686
+ withGuide: false,
687
+ contentAlign: "center",
688
+ titleAlign: "center"
689
+ });
690
+ } catch {
691
+ console.log(`Update available for Kubb: v${version} → v${latestVersion}`);
692
+ console.log("Run `npm install -g @kubb/cli` to update");
693
+ }
447
694
  });
448
- context.on("lifecycle:start", async (version) => {
695
+ context.on("kubb:lifecycle:start", async (version) => {
449
696
  console.log(`\n${getIntro({
450
697
  title: "The ultimate toolkit for working with APIs",
451
698
  description: "Ready to start",
@@ -454,24 +701,24 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
454
701
  })}\n`);
455
702
  reset();
456
703
  });
457
- context.on("config:start", () => {
704
+ context.on("kubb:config:start", () => {
458
705
  if (logLevel <= _kubb_core.logLevel.silent) return;
459
706
  const text = getMessage("Configuration started");
460
707
  _clack_prompts.intro(text);
461
708
  startSpinner(getMessage("Configuration loading"));
462
709
  });
463
- context.on("config:end", (_configs) => {
710
+ context.on("kubb:config:end", (_configs) => {
464
711
  if (logLevel <= _kubb_core.logLevel.silent) return;
465
712
  const text = getMessage("Configuration completed");
466
713
  _clack_prompts.outro(text);
467
714
  });
468
- context.on("generation:start", (config) => {
715
+ context.on("kubb:generation:start", (config) => {
469
716
  reset();
470
717
  state.totalPlugins = config.plugins?.length ?? 0;
471
718
  const text = getMessage(["Generation started", config.name ? `for ${(0, node_util.styleText)("dim", config.name)}` : void 0].filter(Boolean).join(" "));
472
719
  _clack_prompts.intro(text);
473
720
  });
474
- context.on("plugin:start", (plugin) => {
721
+ context.on("kubb:plugin:start", (plugin) => {
475
722
  if (logLevel <= _kubb_core.logLevel.silent) return;
476
723
  stopSpinner();
477
724
  const progressBar = _clack_prompts.progress({
@@ -489,7 +736,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
489
736
  interval
490
737
  });
491
738
  });
492
- context.on("plugin:end", (plugin, { duration, success }) => {
739
+ context.on("kubb:plugin:end", (plugin, { duration, success }) => {
493
740
  stopSpinner();
494
741
  const active = state.activeProgress.get(plugin.name);
495
742
  if (!active || logLevel === _kubb_core.logLevel.silent) return;
@@ -502,7 +749,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
502
749
  state.activeProgress.delete(plugin.name);
503
750
  showProgressStep();
504
751
  });
505
- context.on("files:processing:start", (files) => {
752
+ context.on("kubb:files:processing:start", (files) => {
506
753
  if (logLevel <= _kubb_core.logLevel.silent) return;
507
754
  stopSpinner();
508
755
  state.totalFiles = files.length;
@@ -513,11 +760,11 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
513
760
  max: files.length,
514
761
  size: 30
515
762
  });
516
- context.emit("info", text);
763
+ context.emit("kubb:info", text);
517
764
  progressBar.start(getMessage(text));
518
765
  state.activeProgress.set("files", { progressBar });
519
766
  });
520
- context.on("file:processing:update", ({ file, config }) => {
767
+ context.on("kubb:file:processing:update", ({ file, config }) => {
521
768
  if (logLevel <= _kubb_core.logLevel.silent) return;
522
769
  stopSpinner();
523
770
  state.processedFiles++;
@@ -526,7 +773,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
526
773
  if (!active) return;
527
774
  active.progressBar.advance(void 0, text);
528
775
  });
529
- context.on("files:processing:end", () => {
776
+ context.on("kubb:files:processing:end", () => {
530
777
  if (logLevel <= _kubb_core.logLevel.silent) return;
531
778
  stopSpinner();
532
779
  const text = getMessage("Files written successfully");
@@ -536,31 +783,31 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
536
783
  state.activeProgress.delete("files");
537
784
  showProgressStep();
538
785
  });
539
- context.on("generation:end", (config) => {
786
+ context.on("kubb:generation:end", (config) => {
540
787
  const text = getMessage(config.name ? `Generation completed for ${(0, node_util.styleText)("dim", config.name)}` : "Generation completed");
541
788
  _clack_prompts.outro(text);
542
789
  });
543
- context.on("format:start", () => {
790
+ context.on("kubb:format:start", () => {
544
791
  if (logLevel <= _kubb_core.logLevel.silent) return;
545
792
  const text = getMessage("Format started");
546
793
  _clack_prompts.intro(text);
547
794
  });
548
- context.on("format:end", () => {
795
+ context.on("kubb:format:end", () => {
549
796
  if (logLevel <= _kubb_core.logLevel.silent) return;
550
797
  const text = getMessage("Format completed");
551
798
  _clack_prompts.outro(text);
552
799
  });
553
- context.on("lint:start", () => {
800
+ context.on("kubb:lint:start", () => {
554
801
  if (logLevel <= _kubb_core.logLevel.silent) return;
555
802
  const text = getMessage("Lint started");
556
803
  _clack_prompts.intro(text);
557
804
  });
558
- context.on("lint:end", () => {
805
+ context.on("kubb:lint:end", () => {
559
806
  if (logLevel <= _kubb_core.logLevel.silent) return;
560
807
  const text = getMessage("Lint completed");
561
808
  _clack_prompts.outro(text);
562
809
  });
563
- context.on("hook:start", async ({ id, command, args }) => {
810
+ context.on("kubb:hook:start", async ({ id, command, args }) => {
564
811
  const commandWithArgs = formatCommandWithArgs(command, args);
565
812
  const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} started`);
566
813
  if (!id) return;
@@ -595,12 +842,12 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
595
842
  }
596
843
  });
597
844
  });
598
- context.on("hook:end", ({ command, args }) => {
845
+ context.on("kubb:hook:end", ({ command, args }) => {
599
846
  if (logLevel <= _kubb_core.logLevel.silent) return;
600
847
  const text = getMessage(`Hook ${(0, node_util.styleText)("dim", formatCommandWithArgs(command, args))} successfully executed`);
601
848
  _clack_prompts.outro(text);
602
849
  });
603
- context.on("generation:summary", (config, { pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
850
+ context.on("kubb:generation:summary", (config, { pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
604
851
  const summary = getSummary({
605
852
  failedPlugins,
606
853
  filesCreated,
@@ -613,16 +860,20 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
613
860
  summary.unshift("\n");
614
861
  summary.push("\n");
615
862
  const borderColor = status === "success" ? "green" : "red";
616
- _clack_prompts.box(summary.join("\n"), getMessage(title), {
617
- width: "auto",
618
- formatBorder: (s) => (0, node_util.styleText)(borderColor, s),
619
- rounded: true,
620
- withGuide: false,
621
- contentAlign: "left",
622
- titleAlign: "center"
623
- });
863
+ try {
864
+ _clack_prompts.box(summary.join("\n"), getMessage(title), {
865
+ width: "auto",
866
+ formatBorder: (s) => (0, node_util.styleText)(borderColor, s),
867
+ rounded: true,
868
+ withGuide: false,
869
+ contentAlign: "left",
870
+ titleAlign: "center"
871
+ });
872
+ } catch {
873
+ console.log(summary.join("\n"));
874
+ }
624
875
  });
625
- context.on("lifecycle:end", () => {
876
+ context.on("kubb:lifecycle:end", () => {
626
877
  reset();
627
878
  });
628
879
  }
@@ -663,63 +914,63 @@ const fileSystemLogger = (0, _kubb_core.defineLogger)({
663
914
  files[pathName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
664
915
  }
665
916
  }
666
- await Promise.all(Object.entries(files).map(([fileName, logs]) => write(fileName, logs.join("\n\n"))));
917
+ for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n\n"));
667
918
  return Object.keys(files);
668
919
  }
669
- context.on("info", (message, info) => {
920
+ context.on("kubb:info", (message, info) => {
670
921
  state.cachedLogs.add({
671
922
  date: /* @__PURE__ */ new Date(),
672
923
  logs: [`ℹ ${message} ${info}`]
673
924
  });
674
925
  });
675
- context.on("success", (message, info) => {
926
+ context.on("kubb:success", (message, info) => {
676
927
  state.cachedLogs.add({
677
928
  date: /* @__PURE__ */ new Date(),
678
929
  logs: [`✓ ${message} ${info}`]
679
930
  });
680
931
  });
681
- context.on("warn", (message, info) => {
932
+ context.on("kubb:warn", (message, info) => {
682
933
  state.cachedLogs.add({
683
934
  date: /* @__PURE__ */ new Date(),
684
935
  logs: [`⚠ ${message} ${info}`]
685
936
  });
686
937
  });
687
- context.on("error", (error) => {
938
+ context.on("kubb:error", (error) => {
688
939
  state.cachedLogs.add({
689
940
  date: /* @__PURE__ */ new Date(),
690
941
  logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
691
942
  });
692
943
  });
693
- context.on("debug", (message) => {
944
+ context.on("kubb:debug", (message) => {
694
945
  state.cachedLogs.add({
695
946
  date: /* @__PURE__ */ new Date(),
696
947
  logs: message.logs
697
948
  });
698
949
  });
699
- context.on("plugin:start", (plugin) => {
950
+ context.on("kubb:plugin:start", (plugin) => {
700
951
  state.cachedLogs.add({
701
952
  date: /* @__PURE__ */ new Date(),
702
953
  logs: [`Generating ${plugin.name}`]
703
954
  });
704
955
  });
705
- context.on("plugin:end", (plugin, { duration, success }) => {
956
+ context.on("kubb:plugin:end", (plugin, { duration, success }) => {
706
957
  const durationStr = formatMs(duration);
707
958
  state.cachedLogs.add({
708
959
  date: /* @__PURE__ */ new Date(),
709
960
  logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`]
710
961
  });
711
962
  });
712
- context.on("files:processing:start", (files) => {
963
+ context.on("kubb:files:processing:start", (files) => {
713
964
  state.cachedLogs.add({
714
965
  date: /* @__PURE__ */ new Date(),
715
966
  logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)]
716
967
  });
717
968
  });
718
- context.on("generation:end", async (config) => {
969
+ context.on("kubb:generation:end", async (config) => {
719
970
  const writtenFilePaths = await writeLogs(config.name);
720
971
  if (writtenFilePaths.length > 0) {
721
972
  const files = writtenFilePaths.map((f) => (0, node_path.relative)(node_process.default.cwd(), f));
722
- await context.emit("info", "Debug files written to:", files.join(", "));
973
+ await context.emit("kubb:info", "Debug files written to:", files.join(", "));
723
974
  }
724
975
  reset();
725
976
  });
@@ -773,7 +1024,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
773
1024
  function closeGroup(_name) {
774
1025
  console.log("::endgroup::");
775
1026
  }
776
- context.on("info", (message, info = "") => {
1027
+ context.on("kubb:info", (message, info = "") => {
777
1028
  if (logLevel <= _kubb_core.logLevel.silent) return;
778
1029
  const text = getMessage([
779
1030
  (0, node_util.styleText)("blue", "ℹ"),
@@ -782,7 +1033,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
782
1033
  ].join(" "));
783
1034
  console.log(text);
784
1035
  });
785
- context.on("success", (message, info = "") => {
1036
+ context.on("kubb:success", (message, info = "") => {
786
1037
  if (logLevel <= _kubb_core.logLevel.silent) return;
787
1038
  const text = getMessage([
788
1039
  (0, node_util.styleText)("blue", "✓"),
@@ -791,7 +1042,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
791
1042
  ].filter(Boolean).join(" "));
792
1043
  console.log(text);
793
1044
  });
794
- context.on("warn", (message, info = "") => {
1045
+ context.on("kubb:warn", (message, info = "") => {
795
1046
  if (logLevel <= _kubb_core.logLevel.silent) return;
796
1047
  const text = getMessage([
797
1048
  (0, node_util.styleText)("yellow", "⚠"),
@@ -800,7 +1051,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
800
1051
  ].filter(Boolean).join(" "));
801
1052
  console.warn(`::warning::${text}`);
802
1053
  });
803
- context.on("error", (error) => {
1054
+ context.on("kubb:error", (error) => {
804
1055
  const caused = require_errors.toCause(error);
805
1056
  if (logLevel <= _kubb_core.logLevel.silent) return;
806
1057
  const message = error.message || String(error);
@@ -815,37 +1066,37 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
815
1066
  }
816
1067
  }
817
1068
  });
818
- context.on("lifecycle:start", (version) => {
1069
+ context.on("kubb:lifecycle:start", (version) => {
819
1070
  console.log((0, node_util.styleText)("yellow", `Kubb ${version} 🧩`));
820
1071
  reset();
821
1072
  });
822
- context.on("config:start", () => {
1073
+ context.on("kubb:config:start", () => {
823
1074
  if (logLevel <= _kubb_core.logLevel.silent) return;
824
1075
  const text = getMessage("Configuration started");
825
1076
  openGroup("Configuration");
826
1077
  console.log(text);
827
1078
  });
828
- context.on("config:end", (configs) => {
1079
+ context.on("kubb:config:end", (configs) => {
829
1080
  state.currentConfigs = configs;
830
1081
  if (logLevel <= _kubb_core.logLevel.silent) return;
831
1082
  const text = getMessage("Configuration completed");
832
1083
  console.log(text);
833
1084
  closeGroup("Configuration");
834
1085
  });
835
- context.on("generation:start", (config) => {
1086
+ context.on("kubb:generation:start", (config) => {
836
1087
  reset();
837
1088
  state.totalPlugins = config.plugins?.length ?? 0;
838
1089
  const text = config.name ? `Generation for ${(0, node_util.styleText)("bold", config.name)}` : "Generation";
839
1090
  if (state.currentConfigs.length > 1) openGroup(text);
840
1091
  if (state.currentConfigs.length === 1) console.log(getMessage(text));
841
1092
  });
842
- context.on("plugin:start", (plugin) => {
1093
+ context.on("kubb:plugin:start", (plugin) => {
843
1094
  if (logLevel <= _kubb_core.logLevel.silent) return;
844
1095
  const text = getMessage(`Generating ${(0, node_util.styleText)("bold", plugin.name)}`);
845
1096
  if (state.currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
846
1097
  console.log(text);
847
1098
  });
848
- context.on("plugin:end", (plugin, { duration, success }) => {
1099
+ context.on("kubb:plugin:end", (plugin, { duration, success }) => {
849
1100
  if (logLevel <= _kubb_core.logLevel.silent) return;
850
1101
  if (success) state.completedPlugins++;
851
1102
  else state.failedPlugins++;
@@ -856,7 +1107,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
856
1107
  if (state.currentConfigs.length === 1) closeGroup(`Plugin: ${plugin.name}`);
857
1108
  showProgressStep();
858
1109
  });
859
- context.on("files:processing:start", (files) => {
1110
+ context.on("kubb:files:processing:start", (files) => {
860
1111
  if (logLevel <= _kubb_core.logLevel.silent) return;
861
1112
  state.totalFiles = files.length;
862
1113
  state.processedFiles = 0;
@@ -864,46 +1115,46 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
864
1115
  const text = getMessage(`Writing ${files.length} files`);
865
1116
  console.log(text);
866
1117
  });
867
- context.on("files:processing:end", () => {
1118
+ context.on("kubb:files:processing:end", () => {
868
1119
  if (logLevel <= _kubb_core.logLevel.silent) return;
869
1120
  const text = getMessage("Files written successfully");
870
1121
  console.log(text);
871
1122
  if (state.currentConfigs.length === 1) closeGroup("File Generation");
872
1123
  showProgressStep();
873
1124
  });
874
- context.on("file:processing:update", () => {
1125
+ context.on("kubb:file:processing:update", () => {
875
1126
  if (logLevel <= _kubb_core.logLevel.silent) return;
876
1127
  state.processedFiles++;
877
1128
  });
878
- context.on("generation:end", (config) => {
1129
+ context.on("kubb:generation:end", (config) => {
879
1130
  const text = getMessage(config.name ? `${(0, node_util.styleText)("blue", "✓")} Generation completed for ${(0, node_util.styleText)("dim", config.name)}` : `${(0, node_util.styleText)("blue", "✓")} Generation completed`);
880
1131
  console.log(text);
881
1132
  });
882
- context.on("format:start", () => {
1133
+ context.on("kubb:format:start", () => {
883
1134
  if (logLevel <= _kubb_core.logLevel.silent) return;
884
1135
  const text = getMessage("Format started");
885
1136
  if (state.currentConfigs.length === 1) openGroup("Formatting");
886
1137
  console.log(text);
887
1138
  });
888
- context.on("format:end", () => {
1139
+ context.on("kubb:format:end", () => {
889
1140
  if (logLevel <= _kubb_core.logLevel.silent) return;
890
1141
  const text = getMessage("Format completed");
891
1142
  console.log(text);
892
1143
  if (state.currentConfigs.length === 1) closeGroup("Formatting");
893
1144
  });
894
- context.on("lint:start", () => {
1145
+ context.on("kubb:lint:start", () => {
895
1146
  if (logLevel <= _kubb_core.logLevel.silent) return;
896
1147
  const text = getMessage("Lint started");
897
1148
  if (state.currentConfigs.length === 1) openGroup("Linting");
898
1149
  console.log(text);
899
1150
  });
900
- context.on("lint:end", () => {
1151
+ context.on("kubb:lint:end", () => {
901
1152
  if (logLevel <= _kubb_core.logLevel.silent) return;
902
1153
  const text = getMessage("Lint completed");
903
1154
  console.log(text);
904
1155
  if (state.currentConfigs.length === 1) closeGroup("Linting");
905
1156
  });
906
- context.on("hook:start", async ({ id, command, args }) => {
1157
+ context.on("kubb:hook:start", async ({ id, command, args }) => {
907
1158
  const commandWithArgs = formatCommandWithArgs(command, args);
908
1159
  const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} started`);
909
1160
  if (logLevel > _kubb_core.logLevel.silent) {
@@ -923,14 +1174,14 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
923
1174
  }
924
1175
  });
925
1176
  });
926
- context.on("hook:end", ({ command, args }) => {
1177
+ context.on("kubb:hook:end", ({ command, args }) => {
927
1178
  if (logLevel <= _kubb_core.logLevel.silent) return;
928
1179
  const commandWithArgs = formatCommandWithArgs(command, args);
929
1180
  const text = getMessage(`Hook ${(0, node_util.styleText)("dim", commandWithArgs)} completed`);
930
1181
  console.log(text);
931
1182
  if (state.currentConfigs.length === 1) closeGroup(`Hook ${commandWithArgs}`);
932
1183
  });
933
- context.on("generation:summary", (config, { status, hrStart, failedPlugins }) => {
1184
+ context.on("kubb:generation:summary", (config, { status, hrStart, failedPlugins }) => {
934
1185
  const pluginsCount = config.plugins?.length ?? 0;
935
1186
  const successCount = pluginsCount - failedPlugins.size;
936
1187
  const duration = formatHrtime(hrStart);
@@ -938,7 +1189,7 @@ const githubActionsLogger = (0, _kubb_core.defineLogger)({
938
1189
  console.log(status === "success" ? `Kubb Summary: ${(0, node_util.styleText)("blue", "✓")} ${`${successCount} successful`}, ${pluginsCount} total, ${(0, node_util.styleText)("green", duration)}` : `Kubb Summary: ${(0, node_util.styleText)("blue", "✓")} ${`${successCount} successful`}, ✗ ${`${failedPlugins.size} failed`}, ${pluginsCount} total, ${(0, node_util.styleText)("green", duration)}`);
939
1190
  if (state.currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${(0, node_util.styleText)("bold", config.name)}` : "Generation");
940
1191
  });
941
- context.on("lifecycle:end", () => {
1192
+ context.on("kubb:lifecycle:end", () => {
942
1193
  reset();
943
1194
  });
944
1195
  }
@@ -956,7 +1207,7 @@ const plainLogger = (0, _kubb_core.defineLogger)({
956
1207
  function getMessage(message) {
957
1208
  return formatMessage(message, logLevel);
958
1209
  }
959
- context.on("info", (message, info) => {
1210
+ context.on("kubb:info", (message, info) => {
960
1211
  if (logLevel <= _kubb_core.logLevel.silent) return;
961
1212
  const text = getMessage([
962
1213
  "ℹ",
@@ -965,7 +1216,7 @@ const plainLogger = (0, _kubb_core.defineLogger)({
965
1216
  ].join(" "));
966
1217
  console.log(text);
967
1218
  });
968
- context.on("success", (message, info = "") => {
1219
+ context.on("kubb:success", (message, info = "") => {
969
1220
  if (logLevel <= _kubb_core.logLevel.silent) return;
970
1221
  const text = getMessage([
971
1222
  "✓",
@@ -974,7 +1225,7 @@ const plainLogger = (0, _kubb_core.defineLogger)({
974
1225
  ].filter(Boolean).join(" "));
975
1226
  console.log(text);
976
1227
  });
977
- context.on("warn", (message, info) => {
1228
+ context.on("kubb:warn", (message, info) => {
978
1229
  if (logLevel < _kubb_core.logLevel.warn) return;
979
1230
  const text = getMessage([
980
1231
  "⚠",
@@ -983,7 +1234,7 @@ const plainLogger = (0, _kubb_core.defineLogger)({
983
1234
  ].filter(Boolean).join(" "));
984
1235
  console.log(text);
985
1236
  });
986
- context.on("error", (error) => {
1237
+ context.on("kubb:error", (error) => {
987
1238
  const caused = require_errors.toCause(error);
988
1239
  const text = getMessage(["✗", error.message].join(" "));
989
1240
  console.log(text);
@@ -997,74 +1248,74 @@ const plainLogger = (0, _kubb_core.defineLogger)({
997
1248
  }
998
1249
  }
999
1250
  });
1000
- context.on("lifecycle:start", () => {
1251
+ context.on("kubb:lifecycle:start", () => {
1001
1252
  console.log("Kubb CLI 🧩");
1002
1253
  });
1003
- context.on("config:start", () => {
1254
+ context.on("kubb:config:start", () => {
1004
1255
  if (logLevel <= _kubb_core.logLevel.silent) return;
1005
1256
  const text = getMessage("Configuration started");
1006
1257
  console.log(text);
1007
1258
  });
1008
- context.on("config:end", () => {
1259
+ context.on("kubb:config:end", () => {
1009
1260
  if (logLevel <= _kubb_core.logLevel.silent) return;
1010
1261
  const text = getMessage("Configuration completed");
1011
1262
  console.log(text);
1012
1263
  });
1013
- context.on("generation:start", () => {
1264
+ context.on("kubb:generation:start", () => {
1014
1265
  const text = getMessage("Generation started");
1015
1266
  console.log(text);
1016
1267
  });
1017
- context.on("plugin:start", (plugin) => {
1268
+ context.on("kubb:plugin:start", (plugin) => {
1018
1269
  if (logLevel <= _kubb_core.logLevel.silent) return;
1019
1270
  const text = getMessage(`Generating ${plugin.name}`);
1020
1271
  console.log(text);
1021
1272
  });
1022
- context.on("plugin:end", (plugin, { duration, success }) => {
1273
+ context.on("kubb:plugin:end", (plugin, { duration, success }) => {
1023
1274
  if (logLevel <= _kubb_core.logLevel.silent) return;
1024
1275
  const durationStr = formatMs(duration);
1025
1276
  const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`);
1026
1277
  console.log(text);
1027
1278
  });
1028
- context.on("files:processing:start", (files) => {
1279
+ context.on("kubb:files:processing:start", (files) => {
1029
1280
  if (logLevel <= _kubb_core.logLevel.silent) return;
1030
1281
  const text = getMessage(`Writing ${files.length} files`);
1031
1282
  console.log(text);
1032
1283
  });
1033
- context.on("file:processing:update", ({ file, config }) => {
1284
+ context.on("kubb:file:processing:update", ({ file, config }) => {
1034
1285
  if (logLevel <= _kubb_core.logLevel.silent) return;
1035
1286
  const text = getMessage(`Writing ${(0, node_path.relative)(config.root, file.path)}`);
1036
1287
  console.log(text);
1037
1288
  });
1038
- context.on("files:processing:end", () => {
1289
+ context.on("kubb:files:processing:end", () => {
1039
1290
  if (logLevel <= _kubb_core.logLevel.silent) return;
1040
1291
  const text = getMessage("Files written successfully");
1041
1292
  console.log(text);
1042
1293
  });
1043
- context.on("generation:end", (config) => {
1294
+ context.on("kubb:generation:end", (config) => {
1044
1295
  const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
1045
1296
  console.log(text);
1046
1297
  });
1047
- context.on("format:start", () => {
1298
+ context.on("kubb:format:start", () => {
1048
1299
  if (logLevel <= _kubb_core.logLevel.silent) return;
1049
1300
  const text = getMessage("Format started");
1050
1301
  console.log(text);
1051
1302
  });
1052
- context.on("format:end", () => {
1303
+ context.on("kubb:format:end", () => {
1053
1304
  if (logLevel <= _kubb_core.logLevel.silent) return;
1054
1305
  const text = getMessage("Format completed");
1055
1306
  console.log(text);
1056
1307
  });
1057
- context.on("lint:start", () => {
1308
+ context.on("kubb:lint:start", () => {
1058
1309
  if (logLevel <= _kubb_core.logLevel.silent) return;
1059
1310
  const text = getMessage("Lint started");
1060
1311
  console.log(text);
1061
1312
  });
1062
- context.on("lint:end", () => {
1313
+ context.on("kubb:lint:end", () => {
1063
1314
  if (logLevel <= _kubb_core.logLevel.silent) return;
1064
1315
  const text = getMessage("Lint completed");
1065
1316
  console.log(text);
1066
1317
  });
1067
- context.on("hook:start", async ({ id, command, args }) => {
1318
+ context.on("kubb:hook:start", async ({ id, command, args }) => {
1068
1319
  const commandWithArgs = formatCommandWithArgs(command, args);
1069
1320
  const text = getMessage(`Hook ${commandWithArgs} started`);
1070
1321
  if (logLevel > _kubb_core.logLevel.silent) console.log(text);
@@ -1081,12 +1332,12 @@ const plainLogger = (0, _kubb_core.defineLogger)({
1081
1332
  }
1082
1333
  });
1083
1334
  });
1084
- context.on("hook:end", ({ command, args }) => {
1335
+ context.on("kubb:hook:end", ({ command, args }) => {
1085
1336
  if (logLevel <= _kubb_core.logLevel.silent) return;
1086
1337
  const text = getMessage(`Hook ${formatCommandWithArgs(command, args)} completed`);
1087
1338
  console.log(text);
1088
1339
  });
1089
- context.on("generation:summary", (config, { pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
1340
+ context.on("kubb:generation:summary", (config, { pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
1090
1341
  const summary = getSummary({
1091
1342
  failedPlugins,
1092
1343
  filesCreated,
@@ -1159,8 +1410,8 @@ async function setupLogger(context, { logLevel }) {
1159
1410
  }
1160
1411
  //#endregion
1161
1412
  //#region src/utils/executeHooks.ts
1162
- async function executeHooks({ hooks, events }) {
1163
- const commands = Array.isArray(hooks.done) ? hooks.done : [hooks.done].filter(Boolean);
1413
+ async function executeHooks({ configHooks, hooks }) {
1414
+ const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
1164
1415
  for (const command of commands) {
1165
1416
  const [cmd, ...args] = require_shell.tokenize(command);
1166
1417
  if (!cmd) continue;
@@ -1168,16 +1419,16 @@ async function executeHooks({ hooks, events }) {
1168
1419
  const hookEndPromise = new Promise((resolve, reject) => {
1169
1420
  const handler = ({ id, success, error }) => {
1170
1421
  if (id !== hookId) return;
1171
- events.off("hook:end", handler);
1422
+ hooks.off("kubb:hook:end", handler);
1172
1423
  if (!success) {
1173
1424
  reject(error ?? /* @__PURE__ */ new Error(`Hook failed: ${command}`));
1174
1425
  return;
1175
1426
  }
1176
- events.emit("success", `${(0, node_util.styleText)("dim", command)} successfully executed`).then(resolve).catch(reject);
1427
+ hooks.emit("kubb:success", `${(0, node_util.styleText)("dim", command)} successfully executed`).then(resolve).catch(reject);
1177
1428
  };
1178
- events.on("hook:end", handler);
1429
+ hooks.on("kubb:hook:end", handler);
1179
1430
  });
1180
- await events.emit("hook:start", {
1431
+ await hooks.emit("kubb:hook:start", {
1181
1432
  id: hookId,
1182
1433
  command: cmd,
1183
1434
  args
@@ -1186,11 +1437,20 @@ async function executeHooks({ hooks, events }) {
1186
1437
  }
1187
1438
  }
1188
1439
  //#endregion
1440
+ //#region src/utils/getConfig.ts
1441
+ async function getConfigs(config, args) {
1442
+ const resolved = await (typeof config === "function" ? config(args) : config);
1443
+ return (Array.isArray(resolved) ? resolved : [resolved]).map((item) => ({
1444
+ ...item,
1445
+ plugins: item.plugins ?? []
1446
+ }));
1447
+ }
1448
+ //#endregion
1189
1449
  //#region src/utils/getCosmiConfig.ts
1190
1450
  const jiti$1 = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).href, {
1191
1451
  jsx: {
1192
1452
  runtime: "automatic",
1193
- importSource: "@kubb/react-fabric"
1453
+ importSource: "@kubb/renderer-jsx"
1194
1454
  },
1195
1455
  sourceMaps: true,
1196
1456
  interopDefault: true
@@ -1207,10 +1467,14 @@ async function getCosmiConfig(moduleName, config) {
1207
1467
  `.${moduleName}rc.yaml`,
1208
1468
  `.${moduleName}rc.yml`,
1209
1469
  `.${moduleName}rc.ts`,
1470
+ `.${moduleName}rc.mts`,
1471
+ `.${moduleName}rc.cts`,
1210
1472
  `.${moduleName}rc.js`,
1211
1473
  `.${moduleName}rc.mjs`,
1212
1474
  `.${moduleName}rc.cjs`,
1213
1475
  `${moduleName}.config.ts`,
1476
+ `${moduleName}.config.mts`,
1477
+ `${moduleName}.config.cts`,
1214
1478
  `${moduleName}.config.js`,
1215
1479
  `${moduleName}.config.mjs`,
1216
1480
  `${moduleName}.config.cjs`
@@ -1226,7 +1490,11 @@ async function getCosmiConfig(moduleName, config) {
1226
1490
  }),
1227
1491
  ...searchPlaces
1228
1492
  ],
1229
- loaders: { ".ts": tsLoader }
1493
+ loaders: {
1494
+ ".ts": tsLoader,
1495
+ ".mts": tsLoader,
1496
+ ".cts": tsLoader
1497
+ }
1230
1498
  });
1231
1499
  try {
1232
1500
  result = config ? await explorer.load(config) : await explorer.search();
@@ -1254,17 +1522,18 @@ async function startWatcher(path, cb) {
1254
1522
  }
1255
1523
  //#endregion
1256
1524
  //#region src/runners/generate.ts
1257
- async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel, events, onStart, onEnd }) {
1525
+ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel, hooks, onStart, onEnd }) {
1258
1526
  await onStart();
1259
1527
  let resolvedTool = toolValue;
1260
1528
  if (resolvedTool === "auto") {
1261
1529
  const detected = await detect();
1262
- if (!detected) await events.emit("warn", noToolMessage);
1530
+ if (!detected) await hooks.emit("kubb:warn", noToolMessage);
1263
1531
  else {
1264
1532
  resolvedTool = detected;
1265
- await events.emit("info", `Auto-detected ${toolLabel}: ${(0, node_util.styleText)("dim", resolvedTool)}`);
1533
+ await hooks.emit("kubb:info", `Auto-detected ${toolLabel}: ${(0, node_util.styleText)("dim", resolvedTool)}`);
1266
1534
  }
1267
1535
  }
1536
+ let toolError;
1268
1537
  if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
1269
1538
  const toolConfig = toolMap[resolvedTool];
1270
1539
  try {
@@ -1272,73 +1541,58 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1272
1541
  const hookEndPromise = new Promise((resolve, reject) => {
1273
1542
  const handler = ({ id, success, error }) => {
1274
1543
  if (id !== hookId) return;
1275
- events.off("hook:end", handler);
1544
+ hooks.off("kubb:hook:end", handler);
1276
1545
  if (!success) {
1277
1546
  reject(error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
1278
1547
  return;
1279
1548
  }
1280
- events.emit("success", [
1549
+ hooks.emit("kubb:success", [
1281
1550
  `${successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1282
1551
  logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1283
1552
  "successfully"
1284
1553
  ].filter(Boolean).join(" ")).then(resolve).catch(reject);
1285
1554
  };
1286
- events.on("hook:end", handler);
1555
+ hooks.on("kubb:hook:end", handler);
1287
1556
  });
1288
- await events.emit("hook:start", {
1557
+ await hooks.emit("kubb:hook:start", {
1289
1558
  id: hookId,
1290
1559
  command: toolConfig.command,
1291
1560
  args: toolConfig.args(outputPath)
1292
1561
  });
1293
1562
  await hookEndPromise;
1294
1563
  } catch (caughtError) {
1295
- const err = new Error(toolConfig.errorMessage);
1296
- err.cause = caughtError;
1297
- await events.emit("error", err);
1564
+ const err = require_errors.toError(caughtError);
1565
+ await hooks.emit("kubb:error", err);
1566
+ toolError = err;
1298
1567
  }
1299
1568
  }
1300
1569
  await onEnd();
1570
+ if (toolError) throw toolError;
1301
1571
  }
1302
- async function generate({ input, config: userConfig, events, logLevel }) {
1303
- const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0);
1572
+ async function generate(options) {
1573
+ const { input, hooks, logLevel } = options;
1304
1574
  const hrStart = node_process.default.hrtime();
1575
+ const inputPath = input ?? ("path" in options.config.input ? options.config.input.path : void 0);
1305
1576
  const config = {
1306
- ...userConfig,
1307
- root: userConfig.root || node_process.default.cwd(),
1577
+ ...options.config,
1308
1578
  input: inputPath ? {
1309
- ...userConfig.input,
1579
+ ...options.config.input,
1310
1580
  path: inputPath
1311
- } : userConfig.input,
1312
- output: {
1313
- write: true,
1314
- barrelType: "named",
1315
- extension: { ".ts": ".ts" },
1316
- format: "prettier",
1317
- ...userConfig.output
1318
- }
1581
+ } : options.config.input,
1582
+ ...options.config.output
1319
1583
  };
1320
- await events.emit("generation:start", config);
1321
- await events.emit("info", config.name ? `Setup generation ${(0, node_util.styleText)("bold", config.name)}` : "Setup generation", inputPath);
1322
- const { sources, fabric, pluginManager } = await (0, _kubb_core.setup)({
1323
- config,
1324
- events
1325
- });
1326
- await events.emit("info", config.name ? `Build generation ${(0, node_util.styleText)("bold", config.name)}` : "Build generation", inputPath);
1327
- const { files, failedPlugins, pluginTimings, error } = await (0, _kubb_core.safeBuild)({
1328
- config,
1329
- events
1330
- }, {
1331
- pluginManager,
1332
- fabric,
1333
- events,
1334
- sources
1335
- });
1336
- await events.emit("info", "Load summary");
1584
+ const kubb = (0, _kubb_core.createKubb)(config, { hooks });
1585
+ await kubb.setup();
1586
+ await hooks.emit("kubb:generation:start", config);
1587
+ await hooks.emit("kubb:info", config.name ? `Setup generation ${(0, node_util.styleText)("bold", config.name)}` : "Setup generation", inputPath);
1588
+ await hooks.emit("kubb:info", config.name ? `Build generation ${(0, node_util.styleText)("bold", config.name)}` : "Build generation", inputPath);
1589
+ const { files, failedPlugins, pluginTimings, error, driver } = await kubb.safeBuild();
1590
+ await hooks.emit("kubb:info", "Load summary");
1337
1591
  if (failedPlugins.size > 0 || error) {
1338
1592
  const allErrors = [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean);
1339
- for (const err of allErrors) await events.emit("error", err);
1340
- await events.emit("generation:end", config, files, sources);
1341
- await events.emit("generation:summary", config, {
1593
+ for (const err of allErrors) await hooks.emit("kubb:error", err);
1594
+ await hooks.emit("kubb:generation:end", config, files, kubb.sources);
1595
+ await hooks.emit("kubb:generation:summary", config, {
1342
1596
  failedPlugins,
1343
1597
  filesCreated: files.length,
1344
1598
  status: "failed",
@@ -1348,7 +1602,7 @@ async function generate({ input, config: userConfig, events, logLevel }) {
1348
1602
  await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1349
1603
  command: "generate",
1350
1604
  kubbVersion: require_package.version,
1351
- plugins: pluginManager.plugins.map((p) => ({
1605
+ plugins: Array.from(driver.plugins.values(), (p) => ({
1352
1606
  name: p.name,
1353
1607
  options: p.options
1354
1608
  })),
@@ -1358,46 +1612,46 @@ async function generate({ input, config: userConfig, events, logLevel }) {
1358
1612
  }));
1359
1613
  node_process.default.exit(1);
1360
1614
  }
1361
- await events.emit("success", "Generation successfully", inputPath);
1362
- await events.emit("generation:end", config, files, sources);
1615
+ await hooks.emit("kubb:success", "Generation successfully", inputPath);
1616
+ await hooks.emit("kubb:generation:end", config, files, kubb.sources);
1363
1617
  const outputPath = node_path.default.resolve(config.root, config.output.path);
1364
1618
  if (config.output.format) await runToolPass({
1365
1619
  toolValue: config.output.format,
1366
- detect: _kubb_core.detectFormatter,
1367
- toolMap: _kubb_core.formatters,
1620
+ detect: detectFormatter,
1621
+ toolMap: formatters,
1368
1622
  toolLabel: "formatter",
1369
1623
  successPrefix: "Formatting",
1370
- noToolMessage: "No formatter found (biome, prettier, or oxfmt). Skipping formatting.",
1624
+ noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
1371
1625
  configName: config.name,
1372
1626
  outputPath,
1373
1627
  logLevel,
1374
- events,
1375
- onStart: () => events.emit("format:start"),
1376
- onEnd: () => events.emit("format:end")
1628
+ hooks,
1629
+ onStart: () => hooks.emit("kubb:format:start"),
1630
+ onEnd: () => hooks.emit("kubb:format:end")
1377
1631
  });
1378
1632
  if (config.output.lint) await runToolPass({
1379
1633
  toolValue: config.output.lint,
1380
- detect: _kubb_core.detectLinter,
1381
- toolMap: _kubb_core.linters,
1634
+ detect: detectLinter,
1635
+ toolMap: linters,
1382
1636
  toolLabel: "linter",
1383
1637
  successPrefix: "Linting",
1384
- noToolMessage: "No linter found (biome, oxlint, or eslint). Skipping linting.",
1638
+ noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
1385
1639
  configName: config.name,
1386
1640
  outputPath,
1387
1641
  logLevel,
1388
- events,
1389
- onStart: () => events.emit("lint:start"),
1390
- onEnd: () => events.emit("lint:end")
1642
+ hooks,
1643
+ onStart: () => hooks.emit("kubb:lint:start"),
1644
+ onEnd: () => hooks.emit("kubb:lint:end")
1391
1645
  });
1392
1646
  if (config.hooks) {
1393
- await events.emit("hooks:start");
1647
+ await hooks.emit("kubb:hooks:start");
1394
1648
  await executeHooks({
1395
- hooks: config.hooks,
1396
- events
1649
+ configHooks: config.hooks,
1650
+ hooks
1397
1651
  });
1398
- await events.emit("hooks:end");
1652
+ await hooks.emit("kubb:hooks:end");
1399
1653
  }
1400
- await events.emit("generation:summary", config, {
1654
+ await hooks.emit("kubb:generation:summary", config, {
1401
1655
  failedPlugins,
1402
1656
  filesCreated: files.length,
1403
1657
  status: "success",
@@ -1407,7 +1661,7 @@ async function generate({ input, config: userConfig, events, logLevel }) {
1407
1661
  await require_telemetry.sendTelemetry(require_telemetry.buildTelemetryEvent({
1408
1662
  command: "generate",
1409
1663
  kubbVersion: require_package.version,
1410
- plugins: pluginManager.plugins.map((p) => ({
1664
+ plugins: Array.from(driver.plugins.values(), (p) => ({
1411
1665
  name: p.name,
1412
1666
  options: p.options
1413
1667
  })),
@@ -1418,54 +1672,45 @@ async function generate({ input, config: userConfig, events, logLevel }) {
1418
1672
  }
1419
1673
  async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }) {
1420
1674
  const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1421
- const events = new AsyncEventEmitter();
1422
- const promiseManager = new _kubb_core.PromiseManager();
1423
- await setupLogger(events, { logLevel });
1675
+ const hooks = new AsyncEventEmitter();
1676
+ await setupLogger(hooks, { logLevel });
1424
1677
  await require_telemetry.executeIfOnline(async () => {
1425
1678
  try {
1426
1679
  const latestVersion = (await (await fetch(require_constants.KUBB_NPM_PACKAGE_URL)).json()).version;
1427
- if (latestVersion && require_package.version < latestVersion) await events.emit("version:new", require_package.version, latestVersion);
1680
+ if (latestVersion && require_package.version < latestVersion) await hooks.emit("kubb:version:new", require_package.version, latestVersion);
1428
1681
  } catch {}
1429
1682
  });
1430
1683
  try {
1431
1684
  const result = await getCosmiConfig("kubb", configPath);
1432
- const configs = await (0, _kubb_core.getConfigs)(result.config, { input });
1433
- await events.emit("config:start");
1434
- await events.emit("info", "Config loaded", node_path.default.relative(node_process.default.cwd(), result.filepath));
1435
- await events.emit("success", "Config loaded successfully", node_path.default.relative(node_process.default.cwd(), result.filepath));
1436
- await events.emit("config:end", configs);
1437
- await events.emit("lifecycle:start", require_package.version);
1438
- const promises = configs.map((config) => {
1439
- return async () => {
1440
- if ((0, _kubb_core.isInputPath)(config) && watch) {
1441
- await startWatcher([input || config.input.path], async (paths) => {
1442
- events.removeAll();
1443
- await generate({
1444
- input,
1445
- config,
1446
- logLevel,
1447
- events
1448
- });
1449
- _clack_prompts.log.step((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
1450
- });
1451
- return;
1452
- }
1453
- await generate({
1454
- input,
1455
- config,
1456
- logLevel,
1457
- events
1458
- });
1459
- };
1685
+ const configs = await getConfigs(result.config, { input });
1686
+ await hooks.emit("kubb:config:start");
1687
+ await hooks.emit("kubb:info", "Config loaded", node_path.default.relative(node_process.default.cwd(), result.filepath));
1688
+ await hooks.emit("kubb:success", "Config loaded successfully", node_path.default.relative(node_process.default.cwd(), result.filepath));
1689
+ await hooks.emit("kubb:config:end", configs);
1690
+ await hooks.emit("kubb:lifecycle:start", require_package.version);
1691
+ for (const config of configs) if ((0, _kubb_core.isInputPath)(config) && watch) await startWatcher([input || config.input.path], async (paths) => {
1692
+ hooks.removeAll();
1693
+ await generate({
1694
+ input,
1695
+ config,
1696
+ logLevel,
1697
+ hooks
1698
+ });
1699
+ _clack_prompts.log.step((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
1700
+ });
1701
+ else await generate({
1702
+ input,
1703
+ config,
1704
+ logLevel,
1705
+ hooks
1460
1706
  });
1461
- await promiseManager.run("seq", promises);
1462
- await events.emit("lifecycle:end");
1707
+ await hooks.emit("kubb:lifecycle:end");
1463
1708
  } catch (error) {
1464
- await events.emit("error", require_errors.toError(error));
1709
+ await hooks.emit("kubb:error", require_errors.toError(error));
1465
1710
  node_process.default.exit(1);
1466
1711
  }
1467
1712
  }
1468
1713
  //#endregion
1469
1714
  exports.runGenerateCommand = runGenerateCommand;
1470
1715
 
1471
- //# sourceMappingURL=generate-nJaqPdGL.cjs.map
1716
+ //# sourceMappingURL=generate-I-SQLa8R.cjs.map