@kubb/cli 5.0.0-alpha.3 → 5.0.0-alpha.31

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 (99) hide show
  1. package/dist/{agent-EkZmkNy6.cjs → agent-BB0QeA15.cjs} +5 -5
  2. package/dist/{agent-EkZmkNy6.cjs.map → agent-BB0QeA15.cjs.map} +1 -1
  3. package/dist/{agent-C0bAlvWn.js → agent-BVZM_vFr.js} +5 -5
  4. package/dist/{agent-C0bAlvWn.js.map → agent-BVZM_vFr.js.map} +1 -1
  5. package/dist/{agent-L50VNhXv.js → agent-DTyw-mt7.js} +4 -4
  6. package/dist/{agent-L50VNhXv.js.map → agent-DTyw-mt7.js.map} +1 -1
  7. package/dist/{agent-C6o_6GSJ.cjs → agent-DpzeyN1s.cjs} +4 -4
  8. package/dist/{agent-C6o_6GSJ.cjs.map → agent-DpzeyN1s.cjs.map} +1 -1
  9. package/dist/{constants-BTUap0zs.cjs → constants-D0XHAHeZ.cjs} +78 -8
  10. package/dist/constants-D0XHAHeZ.cjs.map +1 -0
  11. package/dist/{constants-CM3dJzjK.js → constants-DJM9zCXm.js} +73 -9
  12. package/dist/constants-DJM9zCXm.js.map +1 -0
  13. package/dist/define-Bdn8j5VM.cjs +54 -0
  14. package/dist/define-Bdn8j5VM.cjs.map +1 -0
  15. package/dist/define-Ctii4bel.js +43 -0
  16. package/dist/define-Ctii4bel.js.map +1 -0
  17. package/dist/{errors-DBW0N9w4.cjs → errors-CLCjoSg0.cjs} +22 -6
  18. package/dist/errors-CLCjoSg0.cjs.map +1 -0
  19. package/dist/errors-CjPmyZHy.js +43 -0
  20. package/dist/errors-CjPmyZHy.js.map +1 -0
  21. package/dist/{generate-vf3X_h_u.js → generate-BG0VC_Ui.js} +203 -110
  22. package/dist/generate-BG0VC_Ui.js.map +1 -0
  23. package/dist/{generate-C0Lnz3VU.cjs → generate-Bsie7eRa.cjs} +202 -109
  24. package/dist/generate-Bsie7eRa.cjs.map +1 -0
  25. package/dist/{generate-B1et6yyL.cjs → generate-CJimoNEf.cjs} +3 -3
  26. package/dist/{generate-B1et6yyL.cjs.map → generate-CJimoNEf.cjs.map} +1 -1
  27. package/dist/{generate-DnmnwWSE.js → generate-CUi9CASV.js} +3 -3
  28. package/dist/{generate-DnmnwWSE.js.map → generate-CUi9CASV.js.map} +1 -1
  29. package/dist/index.cjs +49 -21
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +49 -21
  33. package/dist/index.js.map +1 -1
  34. package/dist/{init-CMu6JTPI.js → init-BR3GdRMJ.js} +4 -4
  35. package/dist/{init-CMu6JTPI.js.map → init-BR3GdRMJ.js.map} +1 -1
  36. package/dist/{init-hmolV6B4.cjs → init-BlriFVH6.cjs} +19 -4
  37. package/dist/init-BlriFVH6.cjs.map +1 -0
  38. package/dist/{init-BvVLmKcJ.cjs → init-CgARwpTl.cjs} +4 -4
  39. package/dist/{init-BvVLmKcJ.cjs.map → init-CgARwpTl.cjs.map} +1 -1
  40. package/dist/{init-C-InrmSY.js → init-Y1TNCdzh.js} +19 -4
  41. package/dist/init-Y1TNCdzh.js.map +1 -0
  42. package/dist/{mcp-DPU081OK.cjs → mcp-ChTFDc4I.cjs} +4 -4
  43. package/dist/{mcp-DPU081OK.cjs.map → mcp-ChTFDc4I.cjs.map} +1 -1
  44. package/dist/{mcp-D2SHEg_d.js → mcp-CxuctqmK.js} +3 -3
  45. package/dist/{mcp-D2SHEg_d.js.map → mcp-CxuctqmK.js.map} +1 -1
  46. package/dist/{mcp-ChHFPRzD.cjs → mcp-jMZ56bqT.cjs} +3 -3
  47. package/dist/{mcp-ChHFPRzD.cjs.map → mcp-jMZ56bqT.cjs.map} +1 -1
  48. package/dist/{mcp-BwXRVY1N.js → mcp-r-ZJNccL.js} +4 -4
  49. package/dist/{mcp-BwXRVY1N.js.map → mcp-r-ZJNccL.js.map} +1 -1
  50. package/dist/package-A_drmC2H.js +6 -0
  51. package/dist/package-A_drmC2H.js.map +1 -0
  52. package/dist/{package-BsZ_vsP1.cjs → package-NYSJaof-.cjs} +2 -2
  53. package/dist/package-NYSJaof-.cjs.map +1 -0
  54. package/dist/{shell-7HPrTCJ5.cjs → shell-475fQKaX.cjs} +8 -3
  55. package/dist/shell-475fQKaX.cjs.map +1 -0
  56. package/dist/{shell-DqqWsHCD.js → shell-DLzN4fRo.js} +8 -3
  57. package/dist/shell-DLzN4fRo.js.map +1 -0
  58. package/dist/{telemetry-DxiR7clS.js → telemetry-CBISr5w4.js} +48 -6
  59. package/dist/telemetry-CBISr5w4.js.map +1 -0
  60. package/dist/{telemetry-Cn9X1I5B.cjs → telemetry-YO-uwAbf.cjs} +48 -6
  61. package/dist/telemetry-YO-uwAbf.cjs.map +1 -0
  62. package/dist/{validate-Bbrn3Q-A.cjs → validate-B-LfVNlS.cjs} +3 -3
  63. package/dist/{validate-Bbrn3Q-A.cjs.map → validate-B-LfVNlS.cjs.map} +1 -1
  64. package/dist/{validate-BSaNWrhu.cjs → validate-BTUmWQOM.cjs} +4 -4
  65. package/dist/{validate-BSaNWrhu.cjs.map → validate-BTUmWQOM.cjs.map} +1 -1
  66. package/dist/{validate-l8vLmwKA.js → validate-CIS8nJdd.js} +3 -3
  67. package/dist/{validate-l8vLmwKA.js.map → validate-CIS8nJdd.js.map} +1 -1
  68. package/dist/{validate--6d6ZZTO.js → validate-CyJP7vy1.js} +4 -4
  69. package/dist/{validate--6d6ZZTO.js.map → validate-CyJP7vy1.js.map} +1 -1
  70. package/package.json +6 -6
  71. package/src/constants.ts +57 -10
  72. package/src/index.ts +10 -12
  73. package/src/loggers/clackLogger.ts +30 -22
  74. package/src/loggers/fileSystemLogger.ts +3 -1
  75. package/src/runners/generate.ts +37 -44
  76. package/src/types.ts +11 -0
  77. package/src/utils/flags.ts +10 -0
  78. package/src/utils/getCosmiConfig.ts +6 -0
  79. package/dist/constants-BTUap0zs.cjs.map +0 -1
  80. package/dist/constants-CM3dJzjK.js.map +0 -1
  81. package/dist/define--M_JMcDC.js +0 -25
  82. package/dist/define--M_JMcDC.js.map +0 -1
  83. package/dist/define-D6Kfm7-Z.cjs +0 -36
  84. package/dist/define-D6Kfm7-Z.cjs.map +0 -1
  85. package/dist/errors-6mF_WKxg.js +0 -27
  86. package/dist/errors-6mF_WKxg.js.map +0 -1
  87. package/dist/errors-DBW0N9w4.cjs.map +0 -1
  88. package/dist/generate-C0Lnz3VU.cjs.map +0 -1
  89. package/dist/generate-vf3X_h_u.js.map +0 -1
  90. package/dist/init-C-InrmSY.js.map +0 -1
  91. package/dist/init-hmolV6B4.cjs.map +0 -1
  92. package/dist/package-BsZ_vsP1.cjs.map +0 -1
  93. package/dist/package-iZbDdtad.js +0 -6
  94. package/dist/package-iZbDdtad.js.map +0 -1
  95. package/dist/shell-7HPrTCJ5.cjs.map +0 -1
  96. package/dist/shell-DqqWsHCD.js.map +0 -1
  97. package/dist/telemetry-Cn9X1I5B.cjs.map +0 -1
  98. package/dist/telemetry-DxiR7clS.js.map +0 -1
  99. package/src/utils/getIntro.ts +0 -1
@@ -0,0 +1,43 @@
1
+ import "./chunk--u3MIqq1.js";
2
+ //#region ../../internals/utils/src/errors.ts
3
+ /**
4
+ * Coerces an unknown thrown value to an `Error` instance.
5
+ * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * try { ... } catch(err) {
10
+ * throw new BuildError('Build failed', { cause: toError(err), errors: [] })
11
+ * }
12
+ * ```
13
+ */
14
+ function toError(value) {
15
+ return value instanceof Error ? value : new Error(String(value));
16
+ }
17
+ /**
18
+ * Extracts a human-readable message from any thrown value.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * getErrorMessage(new Error('oops')) // 'oops'
23
+ * getErrorMessage('plain string') // 'plain string'
24
+ * ```
25
+ */
26
+ function getErrorMessage(value) {
27
+ return value instanceof Error ? value.message : String(value);
28
+ }
29
+ /**
30
+ * Extracts the `.cause` of an `Error` as an `Error`, or `undefined` when absent or not an `Error`.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const cause = toCause(buildError) // Error | undefined
35
+ * ```
36
+ */
37
+ function toCause(error) {
38
+ return error.cause instanceof Error ? error.cause : void 0;
39
+ }
40
+ //#endregion
41
+ export { toCause as n, toError as r, getErrorMessage as t };
42
+
43
+ //# sourceMappingURL=errors-CjPmyZHy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-CjPmyZHy.js","names":[],"sources":["../../../internals/utils/src/errors.ts"],"sourcesContent":["/** Thrown when a plugin's configuration or input fails validation.\n *\n * @example\n * ```ts\n * throw new ValidationPluginError('Invalid config: \"output.path\" is required')\n * ```\n */\nexport class ValidationPluginError extends Error {}\n\n/**\n * Thrown when one or more errors occur during a Kubb build.\n * Carries the full list of underlying errors on `errors`.\n *\n * @example\n * ```ts\n * throw new BuildError('Build failed', { errors: [err1, err2] })\n * ```\n */\nexport class BuildError extends Error {\n errors: Array<Error>\n\n constructor(message: string, options: { cause?: Error; errors: Array<Error> }) {\n super(message, { cause: options.cause })\n this.name = 'BuildError'\n this.errors = options.errors\n }\n}\n\n/**\n * Coerces an unknown thrown value to an `Error` instance.\n * Returns the value as-is when it is already an `Error`; otherwise wraps it with `String(value)`.\n *\n * @example\n * ```ts\n * try { ... } catch(err) {\n * throw new BuildError('Build failed', { cause: toError(err), errors: [] })\n * }\n * ```\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value))\n}\n\n/**\n * Extracts a human-readable message from any thrown value.\n *\n * @example\n * ```ts\n * getErrorMessage(new Error('oops')) // 'oops'\n * getErrorMessage('plain string') // 'plain string'\n * ```\n */\nexport function getErrorMessage(value: unknown): string {\n return value instanceof Error ? value.message : String(value)\n}\n\n/**\n * Extracts the `.cause` of an `Error` as an `Error`, or `undefined` when absent or not an `Error`.\n *\n * @example\n * ```ts\n * const cause = toCause(buildError) // Error | undefined\n * ```\n */\nexport function toCause(error: Error): Error | undefined {\n return error.cause instanceof Error ? error.cause : undefined\n}\n"],"mappings":";;;;;;;;;;;;;AAuCA,SAAgB,QAAQ,OAAuB;AAC7C,QAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;;;;;;;;;;;AAYlE,SAAgB,gBAAgB,OAAwB;AACtD,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;;;;;;;;;AAW/D,SAAgB,QAAQ,OAAiC;AACvD,QAAO,MAAM,iBAAiB,QAAQ,MAAM,QAAQ,KAAA"}
@@ -1,9 +1,9 @@
1
1
  import "./chunk--u3MIqq1.js";
2
- import { n as toCause, r as toError } from "./errors-6mF_WKxg.js";
3
- import { a as canUseTTY, i as executeIfOnline, o as isGitHubActions, r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-DxiR7clS.js";
4
- import { n as tokenize } from "./shell-DqqWsHCD.js";
5
- import { t as version } from "./package-iZbDdtad.js";
6
- import { i as WATCHER_IGNORED_PATHS, r as SUMMARY_SEPARATOR, t as KUBB_NPM_PACKAGE_URL } from "./constants-CM3dJzjK.js";
2
+ import { n as toCause, r as toError } from "./errors-CjPmyZHy.js";
3
+ import { a as canUseTTY, i as executeIfOnline, o as isGitHubActions, r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-CBISr5w4.js";
4
+ import { n as tokenize } from "./shell-DLzN4fRo.js";
5
+ import { t as version } from "./package-A_drmC2H.js";
6
+ import { a as WATCHER_IGNORED_PATHS, i as SUMMARY_SEPARATOR, t as KUBB_NPM_PACKAGE_URL } from "./constants-DJM9zCXm.js";
7
7
  import { styleText } from "node:util";
8
8
  import { EventEmitter } from "node:events";
9
9
  import { createHash } from "node:crypto";
@@ -12,19 +12,26 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
12
12
  import path, { dirname, relative, resolve } from "node:path";
13
13
  import process$1 from "node:process";
14
14
  import * as clack from "@clack/prompts";
15
- import { PromiseManager, defineLogger, detectFormatter, detectLinter, formatters, getConfigs, isInputPath, linters, logLevel, safeBuild, setup } from "@kubb/core";
15
+ import { defineLogger, detectFormatter, detectLinter, formatters, getConfigs, isInputPath, linters, logLevel, safeBuild, setup } from "@kubb/core";
16
16
  import { NonZeroExitError, x } from "tinyexec";
17
17
  import { Writable } from "node:stream";
18
18
  import { cosmiconfig } from "cosmiconfig";
19
19
  import { createJiti } from "jiti";
20
20
  //#region ../../internals/utils/src/asyncEventEmitter.ts
21
21
  /**
22
- * A typed EventEmitter that awaits all async listeners before resolving.
22
+ * Typed `EventEmitter` that awaits all async listeners before resolving.
23
23
  * Wraps Node's `EventEmitter` with full TypeScript event-map inference.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
28
+ * emitter.on('build', async (name) => { console.log(name) })
29
+ * await emitter.emit('build', 'petstore') // all listeners awaited
30
+ * ```
24
31
  */
25
32
  var AsyncEventEmitter = class {
26
33
  /**
27
- * `maxListener` controls the maximum number of listeners per event before Node emits a memory-leak warning.
34
+ * Maximum number of listeners per event before Node emits a memory-leak warning.
28
35
  * @default 10
29
36
  */
30
37
  constructor(maxListener = 10) {
@@ -32,31 +39,48 @@ var AsyncEventEmitter = class {
32
39
  }
33
40
  #emitter = new EventEmitter();
34
41
  /**
35
- * Emits an event and awaits all registered listeners in parallel.
42
+ * Emits `eventName` and awaits all registered listeners sequentially.
36
43
  * Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * await emitter.emit('build', 'petstore')
48
+ * ```
37
49
  */
38
50
  async emit(eventName, ...eventArgs) {
39
51
  const listeners = this.#emitter.listeners(eventName);
40
52
  if (listeners.length === 0) return;
41
- await Promise.all(listeners.map(async (listener) => {
53
+ for (const listener of listeners) try {
54
+ await listener(...eventArgs);
55
+ } catch (err) {
56
+ let serializedArgs;
42
57
  try {
43
- return await listener(...eventArgs);
44
- } catch (err) {
45
- let serializedArgs;
46
- try {
47
- serializedArgs = JSON.stringify(eventArgs);
48
- } catch {
49
- serializedArgs = String(eventArgs);
50
- }
51
- throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
58
+ serializedArgs = JSON.stringify(eventArgs);
59
+ } catch {
60
+ serializedArgs = String(eventArgs);
52
61
  }
53
- }));
62
+ throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
63
+ }
54
64
  }
55
- /** Registers a persistent listener for the given event. */
65
+ /**
66
+ * Registers a persistent listener for `eventName`.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * emitter.on('build', async (name) => { console.log(name) })
71
+ * ```
72
+ */
56
73
  on(eventName, handler) {
57
74
  this.#emitter.on(eventName, handler);
58
75
  }
59
- /** Registers a one-shot listener that removes itself after the first invocation. */
76
+ /**
77
+ * Registers a one-shot listener that removes itself after the first invocation.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * emitter.onOnce('build', async (name) => { console.log(name) })
82
+ * ```
83
+ */
60
84
  onOnce(eventName, handler) {
61
85
  const wrapper = (...args) => {
62
86
  this.off(eventName, wrapper);
@@ -64,11 +88,25 @@ var AsyncEventEmitter = class {
64
88
  };
65
89
  this.on(eventName, wrapper);
66
90
  }
67
- /** Removes a previously registered listener. */
91
+ /**
92
+ * Removes a previously registered listener.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * emitter.off('build', handler)
97
+ * ```
98
+ */
68
99
  off(eventName, handler) {
69
100
  this.#emitter.off(eventName, handler);
70
101
  }
71
- /** Removes all listeners from every event channel. */
102
+ /**
103
+ * Removes all listeners from every event channel.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * emitter.removeAll()
108
+ * ```
109
+ */
72
110
  removeAll() {
73
111
  this.#emitter.removeAllListeners();
74
112
  }
@@ -76,8 +114,15 @@ var AsyncEventEmitter = class {
76
114
  //#endregion
77
115
  //#region ../../internals/utils/src/time.ts
78
116
  /**
79
- * Calculates elapsed time in milliseconds from a high-resolution start time.
80
- * Rounds to 2 decimal places to provide sub-millisecond precision without noise.
117
+ * Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
118
+ * Rounds to 2 decimal places for sub-millisecond precision without noise.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const start = process.hrtime()
123
+ * doWork()
124
+ * getElapsedMs(start) // 42.35
125
+ * ```
81
126
  */
82
127
  function getElapsedMs(hrStart) {
83
128
  const [seconds, nanoseconds] = process.hrtime(hrStart);
@@ -85,8 +130,14 @@ function getElapsedMs(hrStart) {
85
130
  return Math.round(ms * 100) / 100;
86
131
  }
87
132
  /**
88
- * Converts a millisecond duration into a human-readable string.
89
- * Adjusts units (ms, s, m s) based on the magnitude of the duration.
133
+ * Converts a millisecond duration into a human-readable string (`ms`, `s`, or `m s`).
134
+ *
135
+ * @example
136
+ * ```ts
137
+ * formatMs(250) // '250ms'
138
+ * formatMs(1500) // '1.50s'
139
+ * formatMs(90000) // '1m 30.0s'
140
+ * ```
90
141
  */
91
142
  function formatMs(ms) {
92
143
  if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
@@ -94,7 +145,14 @@ function formatMs(ms) {
94
145
  return `${Math.round(ms)}ms`;
95
146
  }
96
147
  /**
97
- * Convenience helper: formats the elapsed time since `hrStart` in one step.
148
+ * Formats the elapsed time since `hrStart` as a human-readable string.
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const start = process.hrtime()
153
+ * doWork()
154
+ * formatHrtime(start) // '1.50s'
155
+ * ```
98
156
  */
99
157
  function formatHrtime(hrStart) {
100
158
  return formatMs(getElapsedMs(hrStart));
@@ -136,7 +194,9 @@ function gradient(colorStops, text) {
136
194
  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`;
137
195
  }).join("");
138
196
  }
139
- /** ANSI color functions for each part of the Kubb mascot illustration. */
197
+ /**
198
+ * ANSI color functions for each part of the Kubb mascot illustration.
199
+ */
140
200
  const palette = {
141
201
  lid: hex("#F55A17"),
142
202
  woodTop: hex("#F5A217"),
@@ -147,7 +207,12 @@ const palette = {
147
207
  blush: hex("#FDA4AF")
148
208
  };
149
209
  /**
150
- * Generates the Kubb mascot welcome banner.
210
+ * Generates the Kubb mascot welcome banner as an ANSI-colored string.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * console.log(getIntro({ title: 'kubb.config.ts', description: 'generating…', version: '5.0.0', areEyesOpen: true }))
215
+ * ```
151
216
  */
152
217
  function getIntro({ title, description, version, areEyesOpen }) {
153
218
  const kubbVersion = gradient([
@@ -165,7 +230,13 @@ function getIntro({ title, description, version, areEyesOpen }) {
165
230
  ${palette.woodBase("▀▀▀▀▀▀▀▀▀▀▀▀▀")}
166
231
  `;
167
232
  }
168
- /** ANSI color names available for terminal output. */
233
+ /** ANSI color names available for deterministic terminal coloring.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * const color = randomColors[2] // 'green'
238
+ * ```
239
+ */
169
240
  const randomColors = [
170
241
  "black",
171
242
  "red",
@@ -178,15 +249,27 @@ const randomColors = [
178
249
  "gray"
179
250
  ];
180
251
  /**
181
- * Returns the text wrapped in a deterministic ANSI color derived from the text's SHA-256 hash.
252
+ * Wraps `text` in a deterministic ANSI color derived from the text's SHA-256 hash.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * randomCliColor('petstore') // '\x1b[33m' + 'petstore' + '\x1b[39m' (always the same color for 'petstore')
257
+ * ```
182
258
  */
183
259
  function randomCliColor(text) {
184
260
  if (!text) return "";
185
261
  return styleText(randomColors[createHash("sha256").update(text).digest().readUInt32BE(0) % randomColors.length] ?? "white", text);
186
262
  }
187
263
  /**
188
- * Formats a millisecond duration with an ANSI color based on thresholds:
189
- * green 500 ms · yellow 1 000 ms · red > 1 000 ms
264
+ * Formats a millisecond duration with a threshold-based ANSI color.
265
+ * `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * formatMsWithColor(200) // '\x1b[32m200ms\x1b[39m'
270
+ * formatMsWithColor(800) // '\x1b[33m800ms\x1b[39m'
271
+ * formatMsWithColor(1500) // '\x1b[31m1.50s\x1b[39m'
272
+ * ```
190
273
  */
191
274
  function formatMsWithColor(ms) {
192
275
  const formatted = formatMs(ms);
@@ -198,24 +281,29 @@ function formatMsWithColor(ms) {
198
281
  //#region ../../internals/utils/src/fs.ts
199
282
  /**
200
283
  * Writes `data` to `path`, trimming leading/trailing whitespace before saving.
201
- * Skips the write and returns `undefined` when the trimmed content is empty or
202
- * identical to what is already on disk.
284
+ * Skips the write when the trimmed content is empty or identical to what is already on disk.
203
285
  * Creates any missing parent directories automatically.
204
- * When `sanity` is `true`, re-reads the file after writing and throws if the
205
- * content does not match.
286
+ * When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * await write('./src/Pet.ts', source) // writes and returns trimmed content
291
+ * await write('./src/Pet.ts', source) // null — file unchanged
292
+ * await write('./src/Pet.ts', ' ') // null — empty content skipped
293
+ * ```
206
294
  */
207
295
  async function write(path, data, options = {}) {
208
296
  const trimmed = data.trim();
209
- if (trimmed === "") return void 0;
297
+ if (trimmed === "") return null;
210
298
  const resolved = resolve(path);
211
299
  if (typeof Bun !== "undefined") {
212
300
  const file = Bun.file(resolved);
213
- if ((await file.exists() ? await file.text() : null) === trimmed) return void 0;
301
+ if ((await file.exists() ? await file.text() : null) === trimmed) return null;
214
302
  await Bun.write(resolved, trimmed);
215
303
  return trimmed;
216
304
  }
217
305
  try {
218
- if (await readFile(resolved, { encoding: "utf-8" }) === trimmed) return void 0;
306
+ if (await readFile(resolved, { encoding: "utf-8" }) === trimmed) return null;
219
307
  } catch {}
220
308
  await mkdir(dirname(resolved), { recursive: true });
221
309
  await writeFile(resolved, trimmed, { encoding: "utf-8" });
@@ -432,15 +520,20 @@ const clackLogger = defineLogger({
432
520
  });
433
521
  context.on("version:new", (version, latestVersion) => {
434
522
  if (logLevel$8 <= logLevel.silent) return;
435
- clack.box(`\`v${version}\` → \`v${latestVersion}\`
523
+ try {
524
+ clack.box(`\`v${version}\` → \`v${latestVersion}\`
436
525
  Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
437
- width: "auto",
438
- formatBorder: (s) => styleText("yellow", s),
439
- rounded: true,
440
- withGuide: false,
441
- contentAlign: "center",
442
- titleAlign: "center"
443
- });
526
+ width: "auto",
527
+ formatBorder: (s) => styleText("yellow", s),
528
+ rounded: true,
529
+ withGuide: false,
530
+ contentAlign: "center",
531
+ titleAlign: "center"
532
+ });
533
+ } catch {
534
+ console.log(`Update available for Kubb: v${version} → v${latestVersion}`);
535
+ console.log("Run `npm install -g @kubb/cli` to update");
536
+ }
444
537
  });
445
538
  context.on("lifecycle:start", async (version) => {
446
539
  console.log(`\n${getIntro({
@@ -610,14 +703,18 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
610
703
  summary.unshift("\n");
611
704
  summary.push("\n");
612
705
  const borderColor = status === "success" ? "green" : "red";
613
- clack.box(summary.join("\n"), getMessage(title), {
614
- width: "auto",
615
- formatBorder: (s) => styleText(borderColor, s),
616
- rounded: true,
617
- withGuide: false,
618
- contentAlign: "left",
619
- titleAlign: "center"
620
- });
706
+ try {
707
+ clack.box(summary.join("\n"), getMessage(title), {
708
+ width: "auto",
709
+ formatBorder: (s) => styleText(borderColor, s),
710
+ rounded: true,
711
+ withGuide: false,
712
+ contentAlign: "left",
713
+ titleAlign: "center"
714
+ });
715
+ } catch {
716
+ console.log(summary.join("\n"));
717
+ }
621
718
  });
622
719
  context.on("lifecycle:end", () => {
623
720
  reset();
@@ -660,7 +757,7 @@ const fileSystemLogger = defineLogger({
660
757
  files[pathName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
661
758
  }
662
759
  }
663
- await Promise.all(Object.entries(files).map(([fileName, logs]) => write(fileName, logs.join("\n\n"))));
760
+ for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n\n"));
664
761
  return Object.keys(files);
665
762
  }
666
763
  context.on("info", (message, info) => {
@@ -1204,10 +1301,14 @@ async function getCosmiConfig(moduleName, config) {
1204
1301
  `.${moduleName}rc.yaml`,
1205
1302
  `.${moduleName}rc.yml`,
1206
1303
  `.${moduleName}rc.ts`,
1304
+ `.${moduleName}rc.mts`,
1305
+ `.${moduleName}rc.cts`,
1207
1306
  `.${moduleName}rc.js`,
1208
1307
  `.${moduleName}rc.mjs`,
1209
1308
  `.${moduleName}rc.cjs`,
1210
1309
  `${moduleName}.config.ts`,
1310
+ `${moduleName}.config.mts`,
1311
+ `${moduleName}.config.cts`,
1211
1312
  `${moduleName}.config.js`,
1212
1313
  `${moduleName}.config.mjs`,
1213
1314
  `${moduleName}.config.cjs`
@@ -1223,7 +1324,11 @@ async function getCosmiConfig(moduleName, config) {
1223
1324
  }),
1224
1325
  ...searchPlaces
1225
1326
  ],
1226
- loaders: { ".ts": tsLoader }
1327
+ loaders: {
1328
+ ".ts": tsLoader,
1329
+ ".mts": tsLoader,
1330
+ ".cts": tsLoader
1331
+ }
1227
1332
  });
1228
1333
  try {
1229
1334
  result = config ? await explorer.load(config) : await explorer.search();
@@ -1262,6 +1367,7 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1262
1367
  await events.emit("info", `Auto-detected ${toolLabel}: ${styleText("dim", resolvedTool)}`);
1263
1368
  }
1264
1369
  }
1370
+ let toolError;
1265
1371
  if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
1266
1372
  const toolConfig = toolMap[resolvedTool];
1267
1373
  try {
@@ -1292,43 +1398,39 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
1292
1398
  const err = new Error(toolConfig.errorMessage);
1293
1399
  err.cause = caughtError;
1294
1400
  await events.emit("error", err);
1401
+ toolError = err;
1295
1402
  }
1296
1403
  }
1297
1404
  await onEnd();
1405
+ if (toolError) throw toolError;
1298
1406
  }
1299
- async function generate({ input, config: userConfig, events, logLevel: logLevel$2 }) {
1300
- const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0);
1407
+ async function generate(options) {
1408
+ const { input, events, logLevel: logLevel$2 } = options;
1301
1409
  const hrStart = process$1.hrtime();
1302
- const config = {
1303
- ...userConfig,
1304
- root: userConfig.root || process$1.cwd(),
1305
- input: inputPath ? {
1306
- ...userConfig.input,
1307
- path: inputPath
1308
- } : userConfig.input,
1309
- output: {
1310
- write: true,
1311
- barrelType: "named",
1312
- extension: { ".ts": ".ts" },
1313
- format: "prettier",
1314
- ...userConfig.output
1315
- }
1316
- };
1317
- await events.emit("generation:start", config);
1318
- await events.emit("info", config.name ? `Setup generation ${styleText("bold", config.name)}` : "Setup generation", inputPath);
1319
- const { sources, fabric, pluginManager } = await setup({
1320
- config,
1410
+ const inputPath = input ?? ("path" in options.config.input ? options.config.input.path : void 0);
1411
+ const { sources, fabric, driver, config } = await setup({
1412
+ config: {
1413
+ ...options.config,
1414
+ input: inputPath ? {
1415
+ ...options.config.input,
1416
+ path: inputPath
1417
+ } : options.config.input,
1418
+ ...options.config.output
1419
+ },
1321
1420
  events
1322
1421
  });
1422
+ await events.emit("generation:start", config);
1423
+ await events.emit("info", config.name ? `Setup generation ${styleText("bold", config.name)}` : "Setup generation", inputPath);
1323
1424
  await events.emit("info", config.name ? `Build generation ${styleText("bold", config.name)}` : "Build generation", inputPath);
1324
1425
  const { files, failedPlugins, pluginTimings, error } = await safeBuild({
1325
1426
  config,
1326
1427
  events
1327
1428
  }, {
1328
- pluginManager,
1429
+ driver,
1329
1430
  fabric,
1330
1431
  events,
1331
- sources
1432
+ sources,
1433
+ config
1332
1434
  });
1333
1435
  await events.emit("info", "Load summary");
1334
1436
  if (failedPlugins.size > 0 || error) {
@@ -1345,7 +1447,7 @@ async function generate({ input, config: userConfig, events, logLevel: logLevel$
1345
1447
  await sendTelemetry(buildTelemetryEvent({
1346
1448
  command: "generate",
1347
1449
  kubbVersion: version,
1348
- plugins: pluginManager.plugins.map((p) => ({
1450
+ plugins: Array.from(driver.plugins.values(), (p) => ({
1349
1451
  name: p.name,
1350
1452
  options: p.options
1351
1453
  })),
@@ -1404,7 +1506,7 @@ async function generate({ input, config: userConfig, events, logLevel: logLevel$
1404
1506
  await sendTelemetry(buildTelemetryEvent({
1405
1507
  command: "generate",
1406
1508
  kubbVersion: version,
1407
- plugins: pluginManager.plugins.map((p) => ({
1509
+ plugins: Array.from(driver.plugins.values(), (p) => ({
1408
1510
  name: p.name,
1409
1511
  options: p.options
1410
1512
  })),
@@ -1416,7 +1518,6 @@ async function generate({ input, config: userConfig, events, logLevel: logLevel$
1416
1518
  async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }) {
1417
1519
  const logLevel$3 = logLevel[logLevelKey] ?? logLevel.info;
1418
1520
  const events = new AsyncEventEmitter();
1419
- const promiseManager = new PromiseManager();
1420
1521
  await setupLogger(events, { logLevel: logLevel$3 });
1421
1522
  await executeIfOnline(async () => {
1422
1523
  try {
@@ -1432,30 +1533,22 @@ async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, wa
1432
1533
  await events.emit("success", "Config loaded successfully", path.relative(process$1.cwd(), result.filepath));
1433
1534
  await events.emit("config:end", configs);
1434
1535
  await events.emit("lifecycle:start", version);
1435
- const promises = configs.map((config) => {
1436
- return async () => {
1437
- if (isInputPath(config) && watch) {
1438
- await startWatcher([input || config.input.path], async (paths) => {
1439
- events.removeAll();
1440
- await generate({
1441
- input,
1442
- config,
1443
- logLevel: logLevel$3,
1444
- events
1445
- });
1446
- clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
1447
- });
1448
- return;
1449
- }
1450
- await generate({
1451
- input,
1452
- config,
1453
- logLevel: logLevel$3,
1454
- events
1455
- });
1456
- };
1536
+ for (const config of configs) if (isInputPath(config) && watch) await startWatcher([input || config.input.path], async (paths) => {
1537
+ events.removeAll();
1538
+ await generate({
1539
+ input,
1540
+ config,
1541
+ logLevel: logLevel$3,
1542
+ events
1543
+ });
1544
+ clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
1545
+ });
1546
+ else await generate({
1547
+ input,
1548
+ config,
1549
+ logLevel: logLevel$3,
1550
+ events
1457
1551
  });
1458
- await promiseManager.run("seq", promises);
1459
1552
  await events.emit("lifecycle:end");
1460
1553
  } catch (error) {
1461
1554
  await events.emit("error", toError(error));
@@ -1465,4 +1558,4 @@ async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, wa
1465
1558
  //#endregion
1466
1559
  export { runGenerateCommand };
1467
1560
 
1468
- //# sourceMappingURL=generate-vf3X_h_u.js.map
1561
+ //# sourceMappingURL=generate-BG0VC_Ui.js.map