@kubb/cli 5.5.6 → 5.6.0

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 (146) hide show
  1. package/dist/{Telemetry-CMXOVUKB.js → Telemetry-RBcAjNxj.js} +18 -43
  2. package/dist/Telemetry-RBcAjNxj.js.map +1 -0
  3. package/dist/{Telemetry-DDHXBdEz.cjs → Telemetry-bGdFBaGt.cjs} +27 -89
  4. package/dist/Telemetry-bGdFBaGt.cjs.map +1 -0
  5. package/dist/agent-BPIqnEl2.js +59 -0
  6. package/dist/agent-BPIqnEl2.js.map +1 -0
  7. package/dist/agent-DElUuYuy.cjs +120 -0
  8. package/dist/agent-DElUuYuy.cjs.map +1 -0
  9. package/dist/{background-DxlRE9O5.js → background-0PMj56FJ.js} +6 -5
  10. package/dist/background-0PMj56FJ.js.map +1 -0
  11. package/dist/background-BqS01QDb.js +2 -0
  12. package/dist/{background-Bbcc2TdN.cjs → background-R0T_7Szu.cjs} +8 -7
  13. package/dist/background-R0T_7Szu.cjs.map +1 -0
  14. package/dist/commands-BAgGrcvc.js +65 -0
  15. package/dist/commands-BAgGrcvc.js.map +1 -0
  16. package/dist/commands-Si-RFAS6.cjs +71 -0
  17. package/dist/commands-Si-RFAS6.cjs.map +1 -0
  18. package/dist/config-8Xl4yZmw.js +146 -0
  19. package/dist/config-8Xl4yZmw.js.map +1 -0
  20. package/dist/config-ByfJSj3q.cjs +164 -0
  21. package/dist/config-ByfJSj3q.cjs.map +1 -0
  22. package/dist/constants-CdxpgX3_.cjs.map +1 -1
  23. package/dist/constants-DHRspBTo.js.map +1 -1
  24. package/dist/{errors-C-wEou02.cjs → errors-CMbMAwyW.cjs} +2 -2
  25. package/dist/{errors-C-wEou02.cjs.map → errors-CMbMAwyW.cjs.map} +1 -1
  26. package/dist/index.cjs +431 -22
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.js +429 -20
  29. package/dist/index.js.map +1 -1
  30. package/dist/output-B6Ondw0g.js +776 -0
  31. package/dist/output-B6Ondw0g.js.map +1 -0
  32. package/dist/output-i3s5c4Xu.cjs +878 -0
  33. package/dist/output-i3s5c4Xu.cjs.map +1 -0
  34. package/dist/run-3I2NPeXG.cjs +31 -0
  35. package/dist/run-3I2NPeXG.cjs.map +1 -0
  36. package/dist/{run-C-jBKNbI.cjs → run-BkLJ5mXn.cjs} +22 -43
  37. package/dist/run-BkLJ5mXn.cjs.map +1 -0
  38. package/dist/run-CZlkqkDc.js +30 -0
  39. package/dist/run-CZlkqkDc.js.map +1 -0
  40. package/dist/run-CmNDNEjR.js +346 -0
  41. package/dist/run-CmNDNEjR.js.map +1 -0
  42. package/dist/{run-BdTwxLCW.js → run-D5AeacqK.js} +9 -23
  43. package/dist/run-D5AeacqK.js.map +1 -0
  44. package/dist/{run-y6LRyWdS.cjs → run-D8Wz_17X.cjs} +41 -60
  45. package/dist/run-D8Wz_17X.cjs.map +1 -0
  46. package/dist/{run-Dn8HVjnM.js → run-DQoKTiGk.js} +23 -44
  47. package/dist/run-DQoKTiGk.js.map +1 -0
  48. package/dist/{run-BDaZPU-1.js → run-Dgph0WYk.js} +25 -49
  49. package/dist/run-Dgph0WYk.js.map +1 -0
  50. package/dist/run-t8nm7zcT.cjs +348 -0
  51. package/dist/run-t8nm7zcT.cjs.map +1 -0
  52. package/dist/{run-CZz_GbE4.cjs → run-yvuot2N9.cjs} +12 -26
  53. package/dist/run-yvuot2N9.cjs.map +1 -0
  54. package/dist/{snapshot-B5mc4gpC.js → snapshot-CkHXR0Nl.js} +5 -5
  55. package/dist/snapshot-CkHXR0Nl.js.map +1 -0
  56. package/dist/{snapshot-DnCxZfmM.cjs → snapshot-D4nKbwkw.cjs} +9 -9
  57. package/dist/snapshot-D4nKbwkw.cjs.map +1 -0
  58. package/dist/studioWorker.js +2 -2
  59. package/package.json +7 -7
  60. package/dist/Telemetry-CMXOVUKB.js.map +0 -1
  61. package/dist/Telemetry-DDHXBdEz.cjs.map +0 -1
  62. package/dist/agent-DiB4CRre.cjs +0 -38
  63. package/dist/agent-DiB4CRre.cjs.map +0 -1
  64. package/dist/agent-yA5vrXJB.js +0 -26
  65. package/dist/agent-yA5vrXJB.js.map +0 -1
  66. package/dist/background-Bbcc2TdN.cjs.map +0 -1
  67. package/dist/background-CFNncNYT.js +0 -2
  68. package/dist/background-DxlRE9O5.js.map +0 -1
  69. package/dist/connect-C9tTngda.js +0 -11
  70. package/dist/connect-C9tTngda.js.map +0 -1
  71. package/dist/connect-CJ7BhOcs.cjs +0 -11
  72. package/dist/connect-CJ7BhOcs.cjs.map +0 -1
  73. package/dist/generate-BUqZ_7GB.cjs +0 -92
  74. package/dist/generate-BUqZ_7GB.cjs.map +0 -1
  75. package/dist/generate-q2m01zRd.js +0 -92
  76. package/dist/generate-q2m01zRd.js.map +0 -1
  77. package/dist/gunshiDryRun-DdKJuVn1.js +0 -2
  78. package/dist/init-Ckpwkfvz.cjs +0 -58
  79. package/dist/init-Ckpwkfvz.cjs.map +0 -1
  80. package/dist/init-DukE9Uw4.js +0 -58
  81. package/dist/init-DukE9Uw4.js.map +0 -1
  82. package/dist/login-Bc19oiFE.cjs +0 -11
  83. package/dist/login-Bc19oiFE.cjs.map +0 -1
  84. package/dist/login-Do3nns0B.js +0 -11
  85. package/dist/login-Do3nns0B.js.map +0 -1
  86. package/dist/logout-BvHFvCeI.cjs +0 -16
  87. package/dist/logout-BvHFvCeI.cjs.map +0 -1
  88. package/dist/logout-COxoIMum.js +0 -16
  89. package/dist/logout-COxoIMum.js.map +0 -1
  90. package/dist/mcp-B-GxGgVr.js +0 -19
  91. package/dist/mcp-B-GxGgVr.js.map +0 -1
  92. package/dist/mcp-B3B-rE7W.cjs +0 -18
  93. package/dist/mcp-B3B-rE7W.cjs.map +0 -1
  94. package/dist/output-CVLosNZq.cjs +0 -411
  95. package/dist/output-CVLosNZq.cjs.map +0 -1
  96. package/dist/output-FDo-db-w.js +0 -321
  97. package/dist/output-FDo-db-w.js.map +0 -1
  98. package/dist/package-Ci2fcoOV.js +0 -6
  99. package/dist/package-Ci2fcoOV.js.map +0 -1
  100. package/dist/package-Do9rJ7D3.cjs +0 -11
  101. package/dist/package-Do9rJ7D3.cjs.map +0 -1
  102. package/dist/rolldown-runtime-qbf5tadS.cjs +0 -38
  103. package/dist/run-BDaZPU-1.js.map +0 -1
  104. package/dist/run-BdTwxLCW.js.map +0 -1
  105. package/dist/run-C-jBKNbI.cjs.map +0 -1
  106. package/dist/run-CAcQlhub.js +0 -295
  107. package/dist/run-CAcQlhub.js.map +0 -1
  108. package/dist/run-CSoFhDyK.cjs +0 -297
  109. package/dist/run-CSoFhDyK.cjs.map +0 -1
  110. package/dist/run-CZz_GbE4.cjs.map +0 -1
  111. package/dist/run-CaEbo-te.js +0 -40
  112. package/dist/run-CaEbo-te.js.map +0 -1
  113. package/dist/run-CihzLZmR.cjs +0 -41
  114. package/dist/run-CihzLZmR.cjs.map +0 -1
  115. package/dist/run-Dn8HVjnM.js.map +0 -1
  116. package/dist/run-y6LRyWdS.cjs.map +0 -1
  117. package/dist/shared-Cl-OLpNh.cjs +0 -81
  118. package/dist/shared-Cl-OLpNh.cjs.map +0 -1
  119. package/dist/shared-DaHA7QFQ.js +0 -58
  120. package/dist/shared-DaHA7QFQ.js.map +0 -1
  121. package/dist/snapshot-B5mc4gpC.js.map +0 -1
  122. package/dist/snapshot-DnCxZfmM.cjs.map +0 -1
  123. package/dist/start-B-GXO8tS.cjs +0 -12
  124. package/dist/start-B-GXO8tS.cjs.map +0 -1
  125. package/dist/start-Dbfx_8zG.js +0 -12
  126. package/dist/start-Dbfx_8zG.js.map +0 -1
  127. package/dist/status-DDajNc8w.js +0 -17
  128. package/dist/status-DDajNc8w.js.map +0 -1
  129. package/dist/status-DusS7DfO.cjs +0 -17
  130. package/dist/status-DusS7DfO.cjs.map +0 -1
  131. package/dist/stop-C5t7Yx0t.js +0 -11
  132. package/dist/stop-C5t7Yx0t.js.map +0 -1
  133. package/dist/stop-zmM3A0Re.cjs +0 -11
  134. package/dist/stop-zmM3A0Re.cjs.map +0 -1
  135. package/dist/studio--IOOl_VB.js +0 -174
  136. package/dist/studio--IOOl_VB.js.map +0 -1
  137. package/dist/studio-CJ2XhtRd.cjs +0 -174
  138. package/dist/studio-CJ2XhtRd.cjs.map +0 -1
  139. package/dist/utils-C3HZOWL_.js +0 -1107
  140. package/dist/utils-C3HZOWL_.js.map +0 -1
  141. package/dist/utils-ClRbJfxu.cjs +0 -1210
  142. package/dist/utils-ClRbJfxu.cjs.map +0 -1
  143. package/dist/validate-BcB0tFQ6.cjs +0 -19
  144. package/dist/validate-BcB0tFQ6.cjs.map +0 -1
  145. package/dist/validate-QpkCbIFJ.js +0 -20
  146. package/dist/validate-QpkCbIFJ.js.map +0 -1
@@ -0,0 +1,878 @@
1
+ const require_agent = require("./agent-DElUuYuy.cjs");
2
+ let node_util = require("node:util");
3
+ let node_process = require("node:process");
4
+ node_process = require_agent.__toESM(node_process, 1);
5
+ let node_path = require("node:path");
6
+ let _kubb_core = require("@kubb/core");
7
+ let _clack_prompts = require("@clack/prompts");
8
+ _clack_prompts = require_agent.__toESM(_clack_prompts, 1);
9
+ //#region src/loggers/banner.ts
10
+ /**
11
+ * Parses a CSS hex color string (`#RGB`) into its RGB channels.
12
+ * Falls back to `255` for any channel that cannot be parsed.
13
+ */
14
+ function parseHex(color) {
15
+ const int = Number.parseInt(color.replace("#", ""), 16);
16
+ return Number.isNaN(int) ? {
17
+ r: 255,
18
+ g: 255,
19
+ b: 255
20
+ } : {
21
+ r: int >> 16 & 255,
22
+ g: int >> 8 & 255,
23
+ b: int & 255
24
+ };
25
+ }
26
+ /**
27
+ * Returns a function that wraps a string in a 24-bit ANSI true-color escape sequence
28
+ * for the given hex color.
29
+ */
30
+ function hex(color) {
31
+ const { r, g, b } = parseHex(color);
32
+ return (text) => `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
33
+ }
34
+ function gradient(colorStops, text) {
35
+ const chars = text.split("");
36
+ return chars.map((char, i) => {
37
+ const t = chars.length <= 1 ? 0 : i / (chars.length - 1);
38
+ const seg = Math.min(Math.floor(t * (colorStops.length - 1)), colorStops.length - 2);
39
+ const lt = t * (colorStops.length - 1) - seg;
40
+ const from = parseHex(colorStops[seg]);
41
+ const to = parseHex(colorStops[seg + 1]);
42
+ 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`;
43
+ }).join("");
44
+ }
45
+ /**
46
+ * ANSI color functions for each part of the Kubb mascot illustration.
47
+ */
48
+ const palette = {
49
+ /**
50
+ * Top cap of the skittle.
51
+ */
52
+ lid: hex("#F55A17"),
53
+ /**
54
+ * Upper wood body.
55
+ */
56
+ woodTop: hex("#F5A217"),
57
+ /**
58
+ * Middle wood body.
59
+ */
60
+ woodMid: hex("#F58517"),
61
+ /**
62
+ * Base wood body.
63
+ */
64
+ woodBase: hex("#B45309"),
65
+ /**
66
+ * Eye whites.
67
+ */
68
+ eye: hex("#FFFFFF"),
69
+ /**
70
+ * Highlight accent.
71
+ */
72
+ highlight: hex("#adadc6"),
73
+ /**
74
+ * Cheek blush.
75
+ */
76
+ blush: hex("#FDA4AF")
77
+ };
78
+ /**
79
+ * Generates the Kubb mascot welcome banner as an ANSI-colored string.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * console.log(getIntro({ title: 'kubb.config.ts', description: 'generating…', version: '5.0.0', areEyesOpen: true }))
84
+ * ```
85
+ */
86
+ function getIntro({ title, description, version, areEyesOpen }) {
87
+ const kubbVersion = gradient([
88
+ "#F58517",
89
+ "#F5A217",
90
+ "#F55A17"
91
+ ], `KUBB v${version}`);
92
+ const eyeTop = areEyesOpen ? palette.eye("█▀█") : palette.eye("───");
93
+ const eyeBottom = areEyesOpen ? palette.eye("▀▀▀") : palette.eye("───");
94
+ return [
95
+ ` ${palette.lid("▄▄▄▄▄▄▄▄▄▄▄▄▄")}`,
96
+ ` ${palette.woodTop("█ ")}${palette.highlight("▄▄")}${palette.woodTop(" ")}${palette.highlight("▄▄")}${palette.woodTop(" █")} ${kubbVersion}`,
97
+ ` ${palette.woodMid("█ ")}${eyeTop}${palette.woodMid(" ")}${eyeTop}${palette.woodMid(" █")} ${(0, node_util.styleText)("gray", title)}`,
98
+ ` ${palette.woodMid("█ ")}${eyeBottom}${palette.woodMid(" ")}${palette.blush("◡")}${palette.woodMid(" ")}${eyeBottom}${palette.woodMid(" █")} ${(0, node_util.styleText)("yellow", "➜")} ${(0, node_util.styleText)("white", description)}`,
99
+ ` ${palette.woodBase("▀▀▀▀▀▀▀▀▀▀▀▀▀")}`
100
+ ].join("\n");
101
+ }
102
+ /**
103
+ * Formats a millisecond duration with a threshold-based ANSI color.
104
+ * `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * formatMsWithColor(200) // '\x1b[32m200ms\x1b[39m'
109
+ * formatMsWithColor(800) // '\x1b[33m800ms\x1b[39m'
110
+ * formatMsWithColor(1500) // '\x1b[31m1.50s\x1b[39m'
111
+ * ```
112
+ */
113
+ function formatMsWithColor(ms) {
114
+ const formatted = require_agent.formatMs(ms);
115
+ if (ms <= 500) return (0, node_util.styleText)("green", formatted);
116
+ if (ms <= 1e3) return (0, node_util.styleText)("yellow", formatted);
117
+ return (0, node_util.styleText)("red", formatted);
118
+ }
119
+ //#endregion
120
+ //#region src/loggers/createLogger.ts
121
+ /** Display path for a config's input: the string form, or its `path` field when the input is an object. */
122
+ function getInputPath(config) {
123
+ const { input } = config;
124
+ if (typeof input === "string") return input;
125
+ return typeof input?.path === "string" ? input.path : void 0;
126
+ }
127
+ /** Counts a noun, so a message never reads `1 files`. */
128
+ function pluralize(count, noun) {
129
+ return `${count} ${count === 1 ? noun : `${noun}s`}`;
130
+ }
131
+ /** Prefixes a `[HH:MM:SS]` timestamp at verbose and above. */
132
+ function formatMessage(message, logLevel) {
133
+ if (logLevel >= _kubb_core.logLevel.verbose) {
134
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
135
+ hour12: false,
136
+ hour: "2-digit",
137
+ minute: "2-digit",
138
+ second: "2-digit"
139
+ });
140
+ return `${(0, node_util.styleText)("dim", `[${timestamp}]`)} ${message}`;
141
+ }
142
+ return message;
143
+ }
144
+ /** Renders a `studio:connected` event's versions: the runtime only when it differs from the host, Studio's only when it sent one. */
145
+ function formatVersions({ studio, kubb, agent }) {
146
+ return [
147
+ `v${agent}`,
148
+ kubb !== agent ? `runtime v${kubb}` : void 0,
149
+ studio ? `Studio v${studio}` : void 0
150
+ ].filter(Boolean).join(", ");
151
+ }
152
+ /** The first three frames of a stack, without the message line. */
153
+ function topFrames(stack) {
154
+ return stack.split("\n").slice(1, 4).map((frame) => frame.trim());
155
+ }
156
+ /** First stack frames for verbose error output, including an optional `cause` chain. */
157
+ function formatErrorFrames(error) {
158
+ if (!error.stack) return null;
159
+ const frames = topFrames(error.stack);
160
+ const caused = error.cause instanceof Error ? error.cause : void 0;
161
+ if (!caused?.stack) return { frames };
162
+ return {
163
+ frames,
164
+ cause: {
165
+ header: `└─ caused by ${caused.message}`,
166
+ frames: topFrames(caused.stack)
167
+ }
168
+ };
169
+ }
170
+ /** The progress summary line the clack logger shows, `null` when there is nothing to display. */
171
+ function buildProgressLine(state) {
172
+ const parts = [];
173
+ const duration = require_agent.formatMs(require_agent.getElapsedMs(state.hrStart));
174
+ if (state.totalPlugins > 0) {
175
+ const pluginStr = state.failedPlugins > 0 ? `Plugins ${(0, node_util.styleText)("green", state.completedPlugins.toString())}/${state.totalPlugins} ${(0, node_util.styleText)("red", `(${state.failedPlugins} failed)`)}` : `Plugins ${(0, node_util.styleText)("green", state.completedPlugins.toString())}/${state.totalPlugins}`;
176
+ parts.push(pluginStr);
177
+ }
178
+ if (state.totalFiles > 0) parts.push(`Files ${(0, node_util.styleText)("green", state.processedFiles.toString())}/${state.totalFiles}`);
179
+ if (parts.length === 0) return null;
180
+ parts.push(`${(0, node_util.styleText)("green", duration)} elapsed`);
181
+ return parts.join((0, node_util.styleText)("dim", " | "));
182
+ }
183
+ function createProgressCounters() {
184
+ return {
185
+ totalPlugins: 0,
186
+ completedPlugins: 0,
187
+ failedPlugins: 0,
188
+ totalFiles: 0,
189
+ processedFiles: 0,
190
+ hrStart: node_process.default.hrtime()
191
+ };
192
+ }
193
+ /**
194
+ * The three output phases, in the order the generate runner runs them.
195
+ */
196
+ const PHASES = {
197
+ format: {
198
+ running: "Formatting",
199
+ success: "Formatted",
200
+ failure: "Formatting failed"
201
+ },
202
+ lint: {
203
+ running: "Linting",
204
+ success: "Linted",
205
+ failure: "Linting failed"
206
+ },
207
+ hooks: {
208
+ running: "Running post-generate hooks",
209
+ success: "Post-generate hooks completed",
210
+ failure: "Post-generate hooks failed",
211
+ showHookResults: true
212
+ }
213
+ };
214
+ /**
215
+ * Drops the blank lines a subprocess leaves at either end of its output, so its block does not open
216
+ * or close on an empty row.
217
+ */
218
+ function trimBlankEdges(lines) {
219
+ const start = lines.findIndex((line) => line.trim());
220
+ if (start === -1) return [];
221
+ return lines.slice(start, lines.findLastIndex((line) => line.trim()) + 1);
222
+ }
223
+ /**
224
+ * Wires a {@link LoggerWriter} onto the run's hooks. This owns what a run says and in what order:
225
+ * one group per config, a step over the plugin work, a progress bar for the writes, one step per
226
+ * output phase, then the summary and the group's closing result. The writer only decides how each
227
+ * line looks, so every logger reports the same run the same way.
228
+ *
229
+ * @example
230
+ * ```ts
231
+ * export const plainLogger = createLogger(writer)
232
+ * ```
233
+ */
234
+ function createLogger(writer) {
235
+ return function install(context, { logLevel }) {
236
+ const silent = logLevel <= _kubb_core.logLevel.silent;
237
+ const state = {
238
+ ...createProgressCounters(),
239
+ spinner: null,
240
+ progress: null,
241
+ hooks: /* @__PURE__ */ new Map(),
242
+ /**
243
+ * Plugin results held back while the generation step owns the line.
244
+ */
245
+ pluginLines: [],
246
+ phase: null,
247
+ groupOpen: false
248
+ };
249
+ function text(message) {
250
+ return formatMessage(message, logLevel);
251
+ }
252
+ function startSpinner(message) {
253
+ if (silent) return;
254
+ state.spinner = writer.spinner();
255
+ state.spinner.start(text(message));
256
+ }
257
+ function stopSpinner(message, status = "success") {
258
+ const spinner = state.spinner;
259
+ if (!spinner) return;
260
+ state.spinner = null;
261
+ if (message === void 0) {
262
+ spinner.clear();
263
+ return;
264
+ }
265
+ if (status === "failed") {
266
+ spinner.error(text(message));
267
+ return;
268
+ }
269
+ spinner.stop(text(message));
270
+ }
271
+ function stopProgress(message) {
272
+ const progress = state.progress;
273
+ if (!progress) return;
274
+ state.progress = null;
275
+ progress.stop(message === void 0 ? "" : text(message));
276
+ }
277
+ function startPhase({ running, success, failure, showHookResults = false }) {
278
+ state.phase = {
279
+ successLabel: success,
280
+ failureLabel: failure,
281
+ showHookResults,
282
+ failed: false,
283
+ hrStart: node_process.default.hrtime(),
284
+ lines: [],
285
+ output: []
286
+ };
287
+ startSpinner(running);
288
+ }
289
+ function endPhase() {
290
+ const phase = state.phase;
291
+ state.phase = null;
292
+ if (!phase || silent) return;
293
+ const duration = formatMsWithColor(require_agent.getElapsedMs(phase.hrStart));
294
+ stopSpinner(phase.failed ? `${phase.failureLabel} after ${duration}` : `${phase.successLabel} in ${duration}`, phase.failed ? "failed" : "success");
295
+ if (phase.lines.length) writer.block(phase.lines);
296
+ writeOutput(phase.output);
297
+ }
298
+ function writeOutput(lines) {
299
+ const output = trimBlankEdges(lines);
300
+ if (output.length) writer.raw(output);
301
+ }
302
+ function closeGroup(status) {
303
+ if (!state.groupOpen) return;
304
+ state.groupOpen = false;
305
+ stopSpinner();
306
+ stopProgress();
307
+ writer.groupEnd(status === "failed" ? (0, node_util.styleText)("red", "✗ Generation failed") : (0, node_util.styleText)("green", "✓ Generation succeeded"));
308
+ }
309
+ function reset() {
310
+ stopSpinner();
311
+ stopProgress();
312
+ Object.assign(state, createProgressCounters());
313
+ state.hooks.clear();
314
+ state.pluginLines = [];
315
+ state.phase = null;
316
+ state.groupOpen = false;
317
+ }
318
+ function formatLine(symbol, message, info) {
319
+ return text([
320
+ symbol,
321
+ message,
322
+ info && (0, node_util.styleText)("dim", info)
323
+ ].filter(Boolean).join(" "));
324
+ }
325
+ context.hook("kubb:warn", ({ message, info }) => {
326
+ if (logLevel < _kubb_core.logLevel.warn) return;
327
+ writer.warn(formatLine((0, node_util.styleText)("yellow", "⚠"), message, logLevel >= _kubb_core.logLevel.info ? info : void 0));
328
+ });
329
+ context.hook("kubb:error", ({ error }) => {
330
+ if (state.phase) state.phase.failed = true;
331
+ if (state.spinner) stopSpinner(error.message, "failed");
332
+ else writer.error(text(error.message));
333
+ const frames = logLevel >= _kubb_core.logLevel.verbose ? formatErrorFrames(error) : null;
334
+ if (!frames) return;
335
+ writer.block(frames.frames.map((frame) => text((0, node_util.styleText)("dim", frame))));
336
+ if (frames.cause) writer.block([(0, node_util.styleText)("dim", frames.cause.header), ...frames.cause.frames.map((frame) => text(` ${(0, node_util.styleText)("dim", frame)}`))]);
337
+ });
338
+ context.hook("kubb:diagnostic", ({ diagnostic }) => {
339
+ if (silent && diagnostic.severity !== "error") return;
340
+ stopSpinner();
341
+ stopProgress();
342
+ if (_kubb_core.Diagnostics.isUpdate(diagnostic)) {
343
+ writer.update([`\`v${diagnostic.currentVersion}\` → \`v${diagnostic.latestVersion}\``, "Run `npm install -g @kubb/cli` to update"], "Update available for `Kubb`");
344
+ return;
345
+ }
346
+ const { headline, details } = _kubb_core.Diagnostics.format(diagnostic);
347
+ writer.diagnostic([headline, ...details]);
348
+ });
349
+ context.hook("studio:connecting", ({ url }) => {
350
+ startSpinner(`Connecting to ${(0, node_util.styleText)("cyan", url)}`);
351
+ });
352
+ context.hook("studio:disconnected", ({ reason }) => {
353
+ if (logLevel < _kubb_core.logLevel.warn) return;
354
+ stopSpinner();
355
+ writer.warn(text(`⚠ Kubb Studio ended the session (${reason})`));
356
+ });
357
+ context.hook("studio:warn", ({ message, permission }) => {
358
+ if (logLevel < _kubb_core.logLevel.warn) return;
359
+ const remedy = permission ? `; pass --${permission.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`)} to allow it` : "";
360
+ writer.warn(text(`⚠ ${message}${remedy}`));
361
+ });
362
+ context.hook("studio:error", ({ error }) => {
363
+ if (state.spinner) {
364
+ stopSpinner(error.message, "failed");
365
+ return;
366
+ }
367
+ writer.error(text(error.message));
368
+ });
369
+ context.hook("kubb:lifecycle:start", () => {
370
+ reset();
371
+ });
372
+ context.hook("kubb:generation:start", ({ config }) => {
373
+ closeGroup("failed");
374
+ reset();
375
+ state.totalPlugins = config.plugins?.length ?? 0;
376
+ if (silent) return;
377
+ const inputPath = getInputPath(config);
378
+ writer.group(text([(0, node_util.styleText)("bold", config.name ?? "kubb"), inputPath ? (0, node_util.styleText)("dim", inputPath) : void 0].filter(Boolean).join(" ")));
379
+ state.groupOpen = true;
380
+ startSpinner("Generating");
381
+ });
382
+ context.hook("kubb:format:start", () => startPhase(PHASES.format));
383
+ context.hook("kubb:format:end", endPhase);
384
+ context.hook("kubb:lint:start", () => startPhase(PHASES.lint));
385
+ context.hook("kubb:lint:end", endPhase);
386
+ context.hook("kubb:hooks:start", () => startPhase(PHASES.hooks));
387
+ context.hook("kubb:hooks:end", endPhase);
388
+ context.hook("kubb:hook:end", (ctx) => {
389
+ const { id, command, name, args, success, error } = ctx;
390
+ if (!id) return;
391
+ if (!success && state.phase) state.phase.failed = true;
392
+ if (silent) {
393
+ if (!ctx.success) {
394
+ if (ctx.stdout) console.log(ctx.stdout);
395
+ if (ctx.stderr) console.error(ctx.stderr);
396
+ }
397
+ return;
398
+ }
399
+ const active = state.hooks.get(id);
400
+ if (!active) return;
401
+ state.hooks.delete(id);
402
+ const label = (0, node_util.styleText)("dim", name ?? (args?.length ? `${command} ${args.join(" ")}` : command));
403
+ const reason = error?.message ? ` (${error.message})` : "";
404
+ const result = success ? `${(0, node_util.styleText)("green", "✓")} ${label} in ${formatMsWithColor(require_agent.getElapsedMs(active.hrStart))}` : `${(0, node_util.styleText)("red", "✗")} ${label} failed${reason}`;
405
+ const phase = state.phase;
406
+ if (phase) {
407
+ if (phase.showHookResults || !success) phase.lines.push(result);
408
+ phase.output.push(...active.lines);
409
+ return;
410
+ }
411
+ stopSpinner();
412
+ writer.step(text(result));
413
+ writeOutput(active.lines);
414
+ });
415
+ context.hook("kubb:generation:end", () => {
416
+ stopSpinner();
417
+ stopProgress();
418
+ });
419
+ context.hook("kubb:lifecycle:end", () => {
420
+ closeGroup("failed");
421
+ reset();
422
+ });
423
+ if (!silent) {
424
+ context.hook("kubb:info", ({ message, info }) => {
425
+ const line = formatLine((0, node_util.styleText)("blue", "ℹ"), message, info);
426
+ if (state.phase) {
427
+ state.phase.lines.push(line);
428
+ return;
429
+ }
430
+ if (state.spinner) {
431
+ state.spinner.message(line);
432
+ return;
433
+ }
434
+ writer.info(line);
435
+ });
436
+ context.hook("kubb:success", ({ message, info }) => {
437
+ const line = formatLine((0, node_util.styleText)("green", "✓"), message, logLevel >= _kubb_core.logLevel.info ? info : void 0);
438
+ if (state.spinner) {
439
+ state.spinner.message(line);
440
+ return;
441
+ }
442
+ writer.success(line);
443
+ });
444
+ context.hook("studio:connected", ({ url, versions }) => {
445
+ const line = `Connected to ${(0, node_util.styleText)("cyan", url)} ${(0, node_util.styleText)("dim", `(${formatVersions(versions)})`)}`;
446
+ if (state.spinner) {
447
+ stopSpinner(line);
448
+ return;
449
+ }
450
+ writer.success(text(`✓ ${line}`));
451
+ });
452
+ context.hook("studio:ready", () => {
453
+ startSpinner("✓ Ready to receive jobs");
454
+ });
455
+ context.hook("studio:command:start", ({ command }) => {
456
+ stopSpinner();
457
+ writer.info(text(`Kubb Studio asked to ${(0, node_util.styleText)("bold", command)}`));
458
+ });
459
+ context.hook("studio:command:end", ({ command, info }) => {
460
+ writer.success(text(`✓ Finished ${command}${info ? ` ${(0, node_util.styleText)("dim", `(${info})`)}` : ""}`));
461
+ startSpinner("✓ Ready to receive jobs");
462
+ });
463
+ context.hook("studio:reconnecting", ({ delayMs }) => {
464
+ stopSpinner();
465
+ writer.info(text((0, node_util.styleText)("dim", `Retrying connection to Kubb Studio in ${require_agent.formatMs(delayMs)}`)));
466
+ });
467
+ context.hook("kubb:plugin:start", ({ plugin }) => {
468
+ state.spinner?.message(text(`Generating ${(0, node_util.styleText)("dim", plugin.name)}`));
469
+ });
470
+ context.hook("kubb:plugin:end", ({ plugin, duration, success }) => {
471
+ if (success) state.completedPlugins++;
472
+ if (!success) state.failedPlugins++;
473
+ state.pluginLines.push(text(`${plugin.name} ${success ? "completed" : "failed"} in ${formatMsWithColor(duration)}`));
474
+ });
475
+ context.hook("kubb:plugins:end", () => {
476
+ const failed = state.failedPlugins > 0;
477
+ stopSpinner(buildProgressLine(state) ?? "No plugins ran", failed ? "failed" : "success");
478
+ if (state.pluginLines.length) {
479
+ writer.block(state.pluginLines);
480
+ state.pluginLines = [];
481
+ }
482
+ });
483
+ context.hook("kubb:files:processing:start", ({ files }) => {
484
+ stopSpinner();
485
+ state.totalFiles = files.length;
486
+ state.processedFiles = 0;
487
+ state.progress = writer.progress(files.length);
488
+ state.progress.start(text(`Writing ${pluralize(files.length, "file")}`));
489
+ });
490
+ context.hook("kubb:files:processing:update", ({ files }) => {
491
+ for (const { file, config } of files) {
492
+ state.processedFiles++;
493
+ state.progress?.advance(`Writing ${(0, node_path.relative)(config.root, file.path)}`);
494
+ }
495
+ });
496
+ context.hook("kubb:files:processing:end", () => {
497
+ stopProgress(`Wrote ${pluralize(state.processedFiles, "file")}`);
498
+ });
499
+ context.hook("kubb:hook:start", ({ id }) => {
500
+ if (!id) return;
501
+ state.hooks.set(id, {
502
+ hrStart: node_process.default.hrtime(),
503
+ lines: []
504
+ });
505
+ });
506
+ context.hook("kubb:hook:line", ({ id, line }) => {
507
+ const active = state.hooks.get(id);
508
+ if (!active) return;
509
+ if (state.phase) {
510
+ active.lines.push(line);
511
+ return;
512
+ }
513
+ writer.raw([line]);
514
+ });
515
+ }
516
+ return { renderSummary(lines, { status }) {
517
+ if (silent || !state.groupOpen) return;
518
+ closeGroup(status);
519
+ writer.diagnostic([...lines]);
520
+ } };
521
+ };
522
+ }
523
+ //#endregion
524
+ //#region src/utils/env.ts
525
+ /**
526
+ * Returns `true` when the process has an interactive TTY with a valid terminal
527
+ * width and is not running in CI.
528
+ *
529
+ * Some IDE-embedded terminals report `isTTY = true` but set `columns` to `0`,
530
+ * which breaks clack's box-drawing helpers (they call `String.prototype.repeat`
531
+ * with a negative count and throw a `RangeError`). A positive column count is
532
+ * required before the TTY counts as usable.
533
+ *
534
+ * @example
535
+ * ```ts
536
+ * if (canUseTTY()) {
537
+ * renderProgressBar()
538
+ * }
539
+ * ```
540
+ */
541
+ function canUseTTY() {
542
+ return process.stdout.isTTY && (process.stdout.columns ?? 0) > 0 && !require_agent.isCIEnvironment();
543
+ }
544
+ /**
545
+ * Returns `true` when output can carry spinners and clack's gutter: an interactive TTY that no AI
546
+ * coding agent is reading. Cursor-movement escapes are hard for an agent to parse even over a
547
+ * pseudo-TTY, so it gets the plain writer.
548
+ */
549
+ function isRichOutput() {
550
+ return canUseTTY() && !require_agent.getAgentName();
551
+ }
552
+ //#endregion
553
+ //#region src/loggers/clackLogger.ts
554
+ /**
555
+ * Draws with clack: a gutter bar per group, animated steps, and a progress bar for the writes.
556
+ */
557
+ const clackWriter = {
558
+ group: (title) => _clack_prompts.intro(title),
559
+ groupEnd: (text) => _clack_prompts.outro(text),
560
+ step: (text) => _clack_prompts.log.step(text, { spacing: 0 }),
561
+ info: (text) => _clack_prompts.log.info(text),
562
+ success: (text) => _clack_prompts.log.success(text),
563
+ warn: (text) => _clack_prompts.log.warn(text),
564
+ error: (text) => _clack_prompts.log.error(text),
565
+ block: (lines) => _clack_prompts.log.message(lines, { spacing: 0 }),
566
+ raw: (lines) => console.log((0, node_util.styleText)("dim", lines.join("\n"))),
567
+ diagnostic: (lines) => _clack_prompts.log.message(lines, {
568
+ symbol: "",
569
+ secondarySymbol: ""
570
+ }),
571
+ update: (lines, title) => _clack_prompts.box(lines.join("\n"), title, {
572
+ width: "auto",
573
+ formatBorder: (border) => (0, node_util.styleText)("yellow", border),
574
+ rounded: true,
575
+ withGuide: false,
576
+ contentAlign: "center",
577
+ titleAlign: "center"
578
+ }),
579
+ spinner() {
580
+ const spinner = _clack_prompts.spinner();
581
+ return {
582
+ start: (text) => spinner.start(text),
583
+ message: (text) => spinner.message(text),
584
+ clear: () => spinner.clear(),
585
+ stop: (text) => spinner.stop(text),
586
+ error: (text) => spinner.error(text)
587
+ };
588
+ },
589
+ progress(max) {
590
+ const bar = _clack_prompts.progress({
591
+ style: "block",
592
+ max,
593
+ size: 30
594
+ });
595
+ return {
596
+ start: (text) => bar.start(text),
597
+ advance: (text) => bar.advance(1, text),
598
+ stop: (text) => bar.stop(text)
599
+ };
600
+ }
601
+ };
602
+ /**
603
+ * TTY logger for local development, with animated steps and progress bars.
604
+ */
605
+ const clackLogger = createLogger(clackWriter);
606
+ //#endregion
607
+ //#region src/loggers/plainLogger.ts
608
+ /**
609
+ * Prefixes that stand in for the symbols clack draws, so plain output reads the same way.
610
+ */
611
+ const SYMBOLS = {
612
+ info: "ℹ",
613
+ warn: "⚠",
614
+ error: "✗",
615
+ step: "◇"
616
+ };
617
+ /** Draws with one `write` call per line. Nothing animates, so a step prints at start and end. */
618
+ function createWriter(write) {
619
+ return {
620
+ group: write,
621
+ groupEnd: write,
622
+ step: (text) => write(`${SYMBOLS.step} ${text}`),
623
+ info: write,
624
+ success: write,
625
+ warn: write,
626
+ error: (text) => write(`${SYMBOLS.error} ${text}`),
627
+ block: (lines) => write(lines.join("\n")),
628
+ raw: (lines) => write(lines.join("\n")),
629
+ diagnostic: (lines) => write(lines.join("\n")),
630
+ update: (lines, title) => write([title, ...lines].join("\n")),
631
+ spinner: () => ({
632
+ start: write,
633
+ message: write,
634
+ clear: () => {},
635
+ stop: (text) => text && write(text),
636
+ error: (text) => write(`${SYMBOLS.error} ${text}`)
637
+ }),
638
+ progress: () => ({
639
+ start: write,
640
+ advance: write,
641
+ stop: (text) => text && write(text)
642
+ })
643
+ };
644
+ }
645
+ /** The plain logger writing through `write`, e.g. `console.error` so stdout carries only JSON. */
646
+ function createPlainLogger(write) {
647
+ return createLogger(createWriter(write));
648
+ }
649
+ /** Draws on the console, for non-TTY environments and for an AI coding agent reading the output. */
650
+ const plainWriter = createWriter((line) => console.log(line));
651
+ /**
652
+ * Console adapter for non-TTY environments, and for an AI coding agent reading the output. Reports
653
+ * the same run in the same order as `clackLogger`, without the animation.
654
+ */
655
+ const plainLogger = createLogger(plainWriter);
656
+ //#endregion
657
+ //#region src/loggers/output.ts
658
+ const SPONSOR_TIPS = [
659
+ "Your sponsorship keeps Kubb codegen, plugins, and docs maintained",
660
+ "Sponsor faster generators and better Kubb Studio workflows",
661
+ "Help keep Kubb free for TypeScript teams building APIs",
662
+ "Support React Query, Zod, Faker, and MSW integrations",
663
+ "Back open-source tools that turn OpenAPI into TypeScript",
664
+ "Sponsor fixes, releases, and new plugins for your API workflow",
665
+ "Help Kubb stay independent and focused on developer tools"
666
+ ];
667
+ const SPONSOR_LINKS = [
668
+ "https://github.com/sponsors/stijnvanhulle",
669
+ "https://opencollective.com/kubb",
670
+ "https://kubb.dev/sponsors"
671
+ ];
672
+ /** The writer the loggers draw with on this terminal, so a command's own lines look like its run. */
673
+ function writer() {
674
+ return isRichOutput() ? clackWriter : plainWriter;
675
+ }
676
+ function nextTip() {
677
+ return `${SPONSOR_TIPS[Math.floor(Math.random() * SPONSOR_TIPS.length)]}: ${SPONSOR_LINKS[Math.floor(Math.random() * SPONSOR_LINKS.length)]}`;
678
+ }
679
+ function formatTip(tip) {
680
+ return (0, node_util.styleText)("magenta", " Tip ") + (0, node_util.styleText)("yellow", tip);
681
+ }
682
+ /**
683
+ * Prints one random tip outside every group. Rich terminals get the styled variant;
684
+ * plain/CI output gets a stable text-only line so the tip is still visible as final output.
685
+ */
686
+ function logTip() {
687
+ const tip = nextTip();
688
+ if (!isRichOutput()) {
689
+ console.log(`Tip: ${tip}`);
690
+ return;
691
+ }
692
+ console.log(`${(0, node_util.styleText)("magenta", "✦")}${formatTip(tip)}`);
693
+ }
694
+ function write(level, message) {
695
+ if (isRichOutput()) {
696
+ _clack_prompts.log[level](message);
697
+ return;
698
+ }
699
+ console.log(`${SYMBOLS[level]} ${message}`);
700
+ }
701
+ /**
702
+ * Opens a command's output with its title.
703
+ */
704
+ function logIntro({ title, warning, block = true }) {
705
+ if (block && isRichOutput()) {
706
+ if (title) _clack_prompts.intro(title);
707
+ if (warning) _clack_prompts.log.warn(warning);
708
+ return;
709
+ }
710
+ if (title) console.log(title);
711
+ if (warning) console.warn(warning);
712
+ if (title || warning) console.log();
713
+ }
714
+ /**
715
+ * Closes the block {@link logIntro} opened. The closing gutter is not a written line, so plain
716
+ * output prints the text on its own.
717
+ */
718
+ function logOutro(text) {
719
+ writer().groupEnd(text);
720
+ }
721
+ /**
722
+ * Prints one empty line between two groups, without clack's gutter bar, since the bar belongs to a
723
+ * group and a spacer sits outside every one.
724
+ */
725
+ function logSpacer() {
726
+ console.log("");
727
+ }
728
+ /**
729
+ * Opens the command with the Kubb mascot and version, or a single version line where the terminal
730
+ * cannot draw it.
731
+ */
732
+ function logBanner(version) {
733
+ if (isRichOutput()) {
734
+ console.log(`\n${getIntro({
735
+ title: "Turn your API spec into type-safe code",
736
+ description: "Ready to start",
737
+ version,
738
+ areEyesOpen: true
739
+ })}\n`);
740
+ return;
741
+ }
742
+ console.log(`Kubb CLI v${version}`);
743
+ }
744
+ /** Prints lines as one block, without a symbol in front of them. Not the writer's block, which drops clack's spacing around it. */
745
+ function logBlock(lines) {
746
+ if (isRichOutput()) {
747
+ _clack_prompts.log.message(lines);
748
+ return;
749
+ }
750
+ console.log([lines].flat().join("\n"));
751
+ }
752
+ function logInfo(message) {
753
+ write("info", message);
754
+ }
755
+ function logWarn(message) {
756
+ write("warn", message);
757
+ }
758
+ function logError(message) {
759
+ write("error", message);
760
+ }
761
+ /**
762
+ * Reports a step the command is taking, rather than something it found.
763
+ */
764
+ function logStep(message) {
765
+ write("step", message);
766
+ }
767
+ /**
768
+ * A progress spinner, or a writer that prints each message it is given when the terminal cannot
769
+ * animate one. Callers drive both the same way, including the failure state.
770
+ */
771
+ function createSpinner() {
772
+ return writer().spinner();
773
+ }
774
+ //#endregion
775
+ Object.defineProperty(exports, "canUseTTY", {
776
+ enumerable: true,
777
+ get: function() {
778
+ return canUseTTY;
779
+ }
780
+ });
781
+ Object.defineProperty(exports, "clackLogger", {
782
+ enumerable: true,
783
+ get: function() {
784
+ return clackLogger;
785
+ }
786
+ });
787
+ Object.defineProperty(exports, "createPlainLogger", {
788
+ enumerable: true,
789
+ get: function() {
790
+ return createPlainLogger;
791
+ }
792
+ });
793
+ Object.defineProperty(exports, "createSpinner", {
794
+ enumerable: true,
795
+ get: function() {
796
+ return createSpinner;
797
+ }
798
+ });
799
+ Object.defineProperty(exports, "isRichOutput", {
800
+ enumerable: true,
801
+ get: function() {
802
+ return isRichOutput;
803
+ }
804
+ });
805
+ Object.defineProperty(exports, "logBanner", {
806
+ enumerable: true,
807
+ get: function() {
808
+ return logBanner;
809
+ }
810
+ });
811
+ Object.defineProperty(exports, "logBlock", {
812
+ enumerable: true,
813
+ get: function() {
814
+ return logBlock;
815
+ }
816
+ });
817
+ Object.defineProperty(exports, "logError", {
818
+ enumerable: true,
819
+ get: function() {
820
+ return logError;
821
+ }
822
+ });
823
+ Object.defineProperty(exports, "logInfo", {
824
+ enumerable: true,
825
+ get: function() {
826
+ return logInfo;
827
+ }
828
+ });
829
+ Object.defineProperty(exports, "logIntro", {
830
+ enumerable: true,
831
+ get: function() {
832
+ return logIntro;
833
+ }
834
+ });
835
+ Object.defineProperty(exports, "logOutro", {
836
+ enumerable: true,
837
+ get: function() {
838
+ return logOutro;
839
+ }
840
+ });
841
+ Object.defineProperty(exports, "logSpacer", {
842
+ enumerable: true,
843
+ get: function() {
844
+ return logSpacer;
845
+ }
846
+ });
847
+ Object.defineProperty(exports, "logStep", {
848
+ enumerable: true,
849
+ get: function() {
850
+ return logStep;
851
+ }
852
+ });
853
+ Object.defineProperty(exports, "logTip", {
854
+ enumerable: true,
855
+ get: function() {
856
+ return logTip;
857
+ }
858
+ });
859
+ Object.defineProperty(exports, "logWarn", {
860
+ enumerable: true,
861
+ get: function() {
862
+ return logWarn;
863
+ }
864
+ });
865
+ Object.defineProperty(exports, "plainLogger", {
866
+ enumerable: true,
867
+ get: function() {
868
+ return plainLogger;
869
+ }
870
+ });
871
+ Object.defineProperty(exports, "pluralize", {
872
+ enumerable: true,
873
+ get: function() {
874
+ return pluralize;
875
+ }
876
+ });
877
+
878
+ //# sourceMappingURL=output-i3s5c4Xu.cjs.map