@kubb/cli 5.1.0 → 5.2.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 (101) hide show
  1. package/README.md +66 -0
  2. package/dist/{Telemetry-Fiymfxez.js → Telemetry-BCTY-Nzq.js} +3 -49
  3. package/dist/Telemetry-BCTY-Nzq.js.map +1 -0
  4. package/dist/{Telemetry-D-Jpt27O.cjs → Telemetry-DKfJQxnC.cjs} +8 -60
  5. package/dist/Telemetry-DKfJQxnC.cjs.map +1 -0
  6. package/dist/constants-CdxpgX3_.cjs +115 -0
  7. package/dist/constants-CdxpgX3_.cjs.map +1 -0
  8. package/dist/constants-DHRspBTo.js +92 -0
  9. package/dist/constants-DHRspBTo.js.map +1 -0
  10. package/dist/env-DHaFBZTX.cjs +82 -0
  11. package/dist/env-DHaFBZTX.cjs.map +1 -0
  12. package/dist/env-DqPKEL59.js +59 -0
  13. package/dist/env-DqPKEL59.js.map +1 -0
  14. package/dist/{errors-CZtH2dKk.cjs → errors-C-wEou02.cjs} +2 -19
  15. package/dist/errors-C-wEou02.cjs.map +1 -0
  16. package/dist/errors-C8yNfV7w.js +20 -0
  17. package/dist/errors-C8yNfV7w.js.map +1 -0
  18. package/dist/{generate-BO_Gv-vi.cjs → generate-Btnbf2_0.cjs} +9 -6
  19. package/dist/generate-Btnbf2_0.cjs.map +1 -0
  20. package/dist/{generate-HzSh9v2l.js → generate-PT8_WDJZ.js} +9 -6
  21. package/dist/generate-PT8_WDJZ.js.map +1 -0
  22. package/dist/index.cjs +14 -9
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +2 -3
  25. package/dist/index.js +15 -10
  26. package/dist/index.js.map +1 -1
  27. package/dist/{init-EJOY4K6y.cjs → init-BwuaIvJr.cjs} +3 -3
  28. package/dist/{init-EJOY4K6y.cjs.map → init-BwuaIvJr.cjs.map} +1 -1
  29. package/dist/{init-BslRoYhh.js → init-dkS7T-wO.js} +3 -3
  30. package/dist/{init-BslRoYhh.js.map → init-dkS7T-wO.js.map} +1 -1
  31. package/dist/{mcp-CtV0d0Dc.js → mcp-B-GxGgVr.js} +8 -10
  32. package/dist/mcp-B-GxGgVr.js.map +1 -0
  33. package/dist/{mcp-BIcX2H1u.cjs → mcp-B3B-rE7W.cjs} +8 -10
  34. package/dist/mcp-B3B-rE7W.cjs.map +1 -0
  35. package/dist/output-B2V2MN_C.cjs +137 -0
  36. package/dist/output-B2V2MN_C.cjs.map +1 -0
  37. package/dist/output-LZvrgF3z.js +89 -0
  38. package/dist/output-LZvrgF3z.js.map +1 -0
  39. package/dist/package-CrOAfe1h.js +6 -0
  40. package/dist/package-CrOAfe1h.js.map +1 -0
  41. package/dist/{package-CnUMuss9.cjs → package-Dzjrfs0O.cjs} +2 -2
  42. package/dist/package-Dzjrfs0O.cjs.map +1 -0
  43. package/dist/{run-DSgLksGj.js → run-BzvsJ0Ek.js} +80 -112
  44. package/dist/run-BzvsJ0Ek.js.map +1 -0
  45. package/dist/run-CHfPmjaA.cjs +283 -0
  46. package/dist/run-CHfPmjaA.cjs.map +1 -0
  47. package/dist/{run-FPqeAEF4.cjs → run-DRBqVXX0.cjs} +93 -125
  48. package/dist/run-DRBqVXX0.cjs.map +1 -0
  49. package/dist/{run-ChKPZlIB.js → run-DReizVV9.js} +15 -4
  50. package/dist/run-DReizVV9.js.map +1 -0
  51. package/dist/run-DUY0lV8l.js +499 -0
  52. package/dist/run-DUY0lV8l.js.map +1 -0
  53. package/dist/run-DXPXPj4B.js +281 -0
  54. package/dist/run-DXPXPj4B.js.map +1 -0
  55. package/dist/{run-DCfdTu52.js → run-DvRhuqUM.js} +11 -4
  56. package/dist/run-DvRhuqUM.js.map +1 -0
  57. package/dist/run-Wkl7oK6Q.cjs +502 -0
  58. package/dist/run-Wkl7oK6Q.cjs.map +1 -0
  59. package/dist/{run-BV2tMjuz.cjs → run-aIkuYiQ6.cjs} +15 -4
  60. package/dist/run-aIkuYiQ6.cjs.map +1 -0
  61. package/dist/{run-Cs5FunVC.cjs → run-y7oTgJI3.cjs} +11 -4
  62. package/dist/run-y7oTgJI3.cjs.map +1 -0
  63. package/dist/studio-DKv2YLJZ.js +77 -0
  64. package/dist/studio-DKv2YLJZ.js.map +1 -0
  65. package/dist/studio-PDMxqFN0.cjs +76 -0
  66. package/dist/studio-PDMxqFN0.cjs.map +1 -0
  67. package/dist/{run-DAGbErY0.cjs → utils-B0SrWoNh.cjs} +303 -323
  68. package/dist/utils-B0SrWoNh.cjs.map +1 -0
  69. package/dist/{run-CLGgnrjg.js → utils-CzoNURwq.js} +274 -364
  70. package/dist/utils-CzoNURwq.js.map +1 -0
  71. package/dist/{validate-BxCwQou-.cjs → validate-BcB0tFQ6.cjs} +8 -13
  72. package/dist/validate-BcB0tFQ6.cjs.map +1 -0
  73. package/dist/{validate-DD2S9ffV.js → validate-QpkCbIFJ.js} +8 -13
  74. package/dist/validate-QpkCbIFJ.js.map +1 -0
  75. package/package.json +14 -9
  76. package/dist/Telemetry-D-Jpt27O.cjs.map +0 -1
  77. package/dist/Telemetry-Fiymfxez.js.map +0 -1
  78. package/dist/errors-CMvLO2NE.js +0 -31
  79. package/dist/errors-CMvLO2NE.js.map +0 -1
  80. package/dist/errors-CZtH2dKk.cjs.map +0 -1
  81. package/dist/generate-BO_Gv-vi.cjs.map +0 -1
  82. package/dist/generate-HzSh9v2l.js.map +0 -1
  83. package/dist/mcp-BIcX2H1u.cjs.map +0 -1
  84. package/dist/mcp-CtV0d0Dc.js.map +0 -1
  85. package/dist/package-CnUMuss9.cjs.map +0 -1
  86. package/dist/package-DiBDd6nT.js +0 -6
  87. package/dist/package-DiBDd6nT.js.map +0 -1
  88. package/dist/run-BV2tMjuz.cjs.map +0 -1
  89. package/dist/run-CLGgnrjg.js.map +0 -1
  90. package/dist/run-ChKPZlIB.js.map +0 -1
  91. package/dist/run-Cs5FunVC.cjs.map +0 -1
  92. package/dist/run-DAGbErY0.cjs.map +0 -1
  93. package/dist/run-DCfdTu52.js.map +0 -1
  94. package/dist/run-DSgLksGj.js.map +0 -1
  95. package/dist/run-FPqeAEF4.cjs.map +0 -1
  96. package/dist/tools-DH1a7ZJH.js +0 -152
  97. package/dist/tools-DH1a7ZJH.js.map +0 -1
  98. package/dist/tools-bwKAf_r-.cjs +0 -175
  99. package/dist/tools-bwKAf_r-.cjs.map +0 -1
  100. package/dist/validate-BxCwQou-.cjs.map +0 -1
  101. package/dist/validate-DD2S9ffV.js.map +0 -1
@@ -1,22 +1,127 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_Telemetry = require("./Telemetry-D-Jpt27O.cjs");
3
- const require_errors = require("./errors-CZtH2dKk.cjs");
4
- const require_package = require("./package-CnUMuss9.cjs");
5
- const require_tools = require("./tools-bwKAf_r-.cjs");
2
+ const require_errors = require("./errors-C-wEou02.cjs");
3
+ const require_Telemetry = require("./Telemetry-DKfJQxnC.cjs");
4
+ const require_env = require("./env-DHaFBZTX.cjs");
6
5
  let node_util = require("node:util");
7
6
  let node_crypto = require("node:crypto");
8
7
  let node_process = require("node:process");
9
8
  node_process = require_rolldown_runtime.__toESM(node_process, 1);
10
9
  let node_path = require("node:path");
11
- node_path = require_rolldown_runtime.__toESM(node_path, 1);
12
- let node_fs = require("node:fs");
10
+ let node_child_process = require("node:child_process");
11
+ let _kubb_core = require("@kubb/core");
13
12
  let _clack_prompts = require("@clack/prompts");
14
13
  _clack_prompts = require_rolldown_runtime.__toESM(_clack_prompts, 1);
15
- let _kubb_core = require("@kubb/core");
16
14
  let jiti = require("jiti");
17
15
  let tinyexec = require("tinyexec");
18
16
  let unconfig = require("unconfig");
19
17
  let verkit = require("verkit");
18
+ //#region ../../internals/utils/src/tools.ts
19
+ /**
20
+ * CLI command descriptors for each supported code formatter.
21
+ */
22
+ const formatters = {
23
+ prettier: {
24
+ command: "prettier",
25
+ args: (outputPath) => [
26
+ "--ignore-unknown",
27
+ "--write",
28
+ outputPath
29
+ ],
30
+ errorMessage: "Prettier not found"
31
+ },
32
+ biome: {
33
+ command: "biome",
34
+ args: (outputPath) => [
35
+ "format",
36
+ "--write",
37
+ outputPath
38
+ ],
39
+ errorMessage: "Biome not found"
40
+ },
41
+ oxfmt: {
42
+ command: "oxfmt",
43
+ args: (outputPath) => [outputPath],
44
+ errorMessage: "Oxfmt not found"
45
+ }
46
+ };
47
+ /**
48
+ * CLI command descriptors for each supported linter.
49
+ */
50
+ const linters = {
51
+ eslint: {
52
+ command: "eslint",
53
+ args: (outputPath) => [outputPath, "--fix"],
54
+ errorMessage: "Eslint not found"
55
+ },
56
+ biome: {
57
+ command: "biome",
58
+ args: (outputPath) => [
59
+ "lint",
60
+ "--fix",
61
+ outputPath
62
+ ],
63
+ errorMessage: "Biome not found"
64
+ },
65
+ oxlint: {
66
+ command: "oxlint",
67
+ args: (outputPath) => [
68
+ "--fix",
69
+ "--no-ignore",
70
+ outputPath
71
+ ],
72
+ errorMessage: "Oxlint not found"
73
+ }
74
+ };
75
+ /**
76
+ * Preference order for `format: 'auto'`, most-preferred first. Spelled out rather than taken from
77
+ * the table's key order, which is arbitrary and would silently change what `auto` picks.
78
+ */
79
+ const FORMATTER_PREFERENCE = [
80
+ "oxfmt",
81
+ "biome",
82
+ "prettier"
83
+ ];
84
+ /**
85
+ * Preference order for `lint: 'auto'`, most-preferred first.
86
+ */
87
+ const LINTER_PREFERENCE = [
88
+ "oxlint",
89
+ "biome",
90
+ "eslint"
91
+ ];
92
+ /**
93
+ * Whether `name` is on PATH and answers `--version` with a zero exit.
94
+ */
95
+ function isToolAvailable(name) {
96
+ return new Promise((resolve) => {
97
+ const child = (0, node_child_process.spawn)(name, ["--version"], { stdio: "ignore" });
98
+ child.on("close", (code) => resolve(code === 0));
99
+ child.on("error", () => resolve(false));
100
+ });
101
+ }
102
+ /**
103
+ * Returns the first installed executable from `candidates`, or `null` when none are found.
104
+ *
105
+ * Not memoized: a long-running host that probes repeatedly should cache the result itself, and a
106
+ * `--watch` build should keep noticing a tool installed mid-session.
107
+ */
108
+ async function detectTool(candidates) {
109
+ for (const candidate of candidates) if (await isToolAvailable(candidate)) return candidate;
110
+ return null;
111
+ }
112
+ /**
113
+ * Tokenizes a shell command string, respecting single and double quotes.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * tokenize('git commit -m "initial commit"')
118
+ * // → ['git', 'commit', '-m', 'initial commit']
119
+ * ```
120
+ */
121
+ function tokenize(command) {
122
+ return (command.match(/[^\s"']+|"([^"]*)"|'([^']*)'/g) ?? []).map((token) => token.replace(/^["']|["']$/g, ""));
123
+ }
124
+ //#endregion
20
125
  //#region ../../internals/utils/src/time.ts
21
126
  /**
22
127
  * Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
@@ -50,7 +155,7 @@ function formatMs(ms) {
50
155
  return `${Math.round(ms)}ms`;
51
156
  }
52
157
  //#endregion
53
- //#region ../../internals/utils/src/colors.ts
158
+ //#region src/loggers/banner.ts
54
159
  /**
55
160
  * Parses a CSS hex color string (`#RGB`) into its RGB channels.
56
161
  * Falls back to `255` for any channel that cannot be parsed.
@@ -161,43 +266,6 @@ function formatMsWithColor(ms) {
161
266
  return (0, node_util.styleText)("red", formatted);
162
267
  }
163
268
  //#endregion
164
- //#region ../../internals/utils/src/promise.ts
165
- /**
166
- * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight
167
- * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.
168
- * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should
169
- * coalesce into a single trailing run.
170
- *
171
- * @example
172
- * ```ts
173
- * const rebuild = createSerialRunner({
174
- * run: () => build(),
175
- * onError: (error) => log.error(error.message),
176
- * })
177
- * watcher.on('change', () => void rebuild())
178
- * ```
179
- */
180
- function createSerialRunner({ run, onError }) {
181
- let running = false;
182
- let dirty = false;
183
- return async () => {
184
- if (running) {
185
- dirty = true;
186
- return;
187
- }
188
- running = true;
189
- do {
190
- dirty = false;
191
- try {
192
- await run();
193
- } catch (error) {
194
- onError(require_errors.toError(error));
195
- }
196
- } while (dirty);
197
- running = false;
198
- };
199
- }
200
- //#endregion
201
269
  //#region src/loggers/clackLogger.ts
202
270
  /**
203
271
  * TTY logger for local development, with spinners and progress bars.
@@ -325,6 +393,46 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
325
393
  secondarySymbol: ""
326
394
  });
327
395
  });
396
+ context.hook("studio:connecting", ({ url }) => {
397
+ if (logLevel <= _kubb_core.logLevel.silent) return;
398
+ state.spinner = _clack_prompts.spinner();
399
+ state.spinner.start(getMessage(`Connecting to ${(0, node_util.styleText)("cyan", url)}`));
400
+ state.isSpinning = true;
401
+ });
402
+ context.hook("studio:connected", ({ url, versions }) => {
403
+ if (logLevel <= _kubb_core.logLevel.silent) return;
404
+ const text = getMessage(`Connected to ${(0, node_util.styleText)("cyan", url)} ${(0, node_util.styleText)("dim", `(${formatVersions(versions)})`)}`);
405
+ if (state.isSpinning) {
406
+ stopSpinner(text);
407
+ return;
408
+ }
409
+ _clack_prompts.log.success(text);
410
+ });
411
+ context.hook("studio:disconnected", ({ reason }) => {
412
+ if (logLevel < _kubb_core.logLevel.warn) return;
413
+ stopSpinner();
414
+ _clack_prompts.log.warn(getMessage(`Kubb Studio ended the session (${reason})`));
415
+ });
416
+ context.hook("studio:command:start", ({ command }) => {
417
+ if (logLevel <= _kubb_core.logLevel.silent) return;
418
+ _clack_prompts.log.info(getMessage(`Kubb Studio asked to ${(0, node_util.styleText)("bold", command)}`));
419
+ });
420
+ context.hook("studio:command:end", ({ command, info }) => {
421
+ if (logLevel <= _kubb_core.logLevel.silent) return;
422
+ _clack_prompts.log.success(getMessage(`Finished ${command}${info ? ` ${(0, node_util.styleText)("dim", `(${info})`)}` : ""}`));
423
+ });
424
+ context.hook("studio:warn", ({ message }) => {
425
+ if (logLevel < _kubb_core.logLevel.warn) return;
426
+ _clack_prompts.log.warn(getMessage(message));
427
+ });
428
+ context.hook("studio:error", ({ error }) => {
429
+ const text = getMessage([(0, node_util.styleText)("red", "✗"), error.message].join(" "));
430
+ if (state.isSpinning) {
431
+ stopSpinner(text);
432
+ return;
433
+ }
434
+ _clack_prompts.log.error(text);
435
+ });
328
436
  context.hook("kubb:lifecycle:start", async ({ version }) => {
329
437
  console.log(`\n${getIntro({
330
438
  title: "The meta framework for code generation",
@@ -519,6 +627,33 @@ const plainLogger = {
519
627
  if (logLevel <= _kubb_core.logLevel.silent && diagnostic.severity !== "error") return;
520
628
  console.log(getMessage(_kubb_core.Diagnostics.formatLines(diagnostic).join("\n")));
521
629
  });
630
+ context.hook("studio:connecting", ({ url }) => {
631
+ if (logLevel <= _kubb_core.logLevel.silent) return;
632
+ console.log(getMessage(`Connecting to ${url}`));
633
+ });
634
+ context.hook("studio:connected", ({ url, versions }) => {
635
+ if (logLevel <= _kubb_core.logLevel.silent) return;
636
+ console.log(getMessage(`✓ Connected to ${url} (${formatVersions(versions)})`));
637
+ });
638
+ context.hook("studio:disconnected", ({ reason }) => {
639
+ if (logLevel < _kubb_core.logLevel.warn) return;
640
+ console.log(getMessage(`⚠ Kubb Studio ended the session (${reason})`));
641
+ });
642
+ context.hook("studio:command:start", ({ command }) => {
643
+ if (logLevel <= _kubb_core.logLevel.silent) return;
644
+ console.log(getMessage(`Kubb Studio asked to ${command}`));
645
+ });
646
+ context.hook("studio:command:end", ({ command, info }) => {
647
+ if (logLevel <= _kubb_core.logLevel.silent) return;
648
+ console.log(getMessage(`✓ Finished ${command}${info ? ` (${info})` : ""}`));
649
+ });
650
+ context.hook("studio:warn", ({ message }) => {
651
+ if (logLevel < _kubb_core.logLevel.warn) return;
652
+ console.log(getMessage(`⚠ ${message}`));
653
+ });
654
+ context.hook("studio:error", ({ error }) => {
655
+ console.log(getMessage(`✗ ${error.message}`));
656
+ });
522
657
  context.hook("kubb:lifecycle:start", ({ version }) => {
523
658
  console.log(`Kubb CLI v${version}`);
524
659
  });
@@ -610,12 +745,29 @@ function formatMessage(message, logLevel) {
610
745
  return message;
611
746
  }
612
747
  /**
748
+ * Renders the versions from a `studio:connected` event as one parenthetical. The runtime is listed
749
+ * only when it differs from the host, and Studio's only when it sent one.
750
+ */
751
+ function formatVersions({ studio, kubb, agent }) {
752
+ return [
753
+ `v${agent}`,
754
+ kubb !== agent ? `runtime v${kubb}` : void 0,
755
+ studio ? `Studio v${studio}` : void 0
756
+ ].filter(Boolean).join(", ");
757
+ }
758
+ /**
759
+ * Extracts the `.cause` of an `Error` as an `Error`, or `undefined` when absent or not an `Error`.
760
+ */
761
+ function toCause(error) {
762
+ return error.cause instanceof Error ? error.cause : void 0;
763
+ }
764
+ /**
613
765
  * First stack frames for verbose error output, including an optional `cause` chain.
614
766
  */
615
767
  function formatErrorFrames(error) {
616
768
  if (!error.stack) return null;
617
769
  const frames = error.stack.split("\n").slice(1, 4).map((frame) => frame.trim());
618
- const caused = require_errors.toCause(error);
770
+ const caused = toCause(error);
619
771
  if (!caused?.stack) return { frames };
620
772
  return {
621
773
  frames,
@@ -731,7 +883,7 @@ async function setupReporters(context, { logLevel, reporters }) {
731
883
  for (const reporter of reporters) {
732
884
  if (reporter.name === "cli") {
733
885
  if (hasJson) continue;
734
- await (require_Telemetry.canUseTTY() && !require_Telemetry.getAgentName() ? clackLogger : plainLogger).install(context, { logLevel });
886
+ await (require_env.canUseTTY() && !require_env.getAgentName() ? clackLogger : plainLogger).install(context, { logLevel });
735
887
  }
736
888
  installReporter(context, reporter, ctx);
737
889
  }
@@ -860,18 +1012,6 @@ function isNewerVersion(current, latest) {
860
1012
  return (0, verkit.isGreater)((0, verkit.truncate)(latest, "patch"), (0, verkit.truncate)(current, "patch"));
861
1013
  }
862
1014
  /**
863
- * Tokenizes a shell command string, respecting single and double quotes.
864
- *
865
- * @example
866
- * ```ts
867
- * tokenize('git commit -m "initial commit"')
868
- * // → ['git', 'commit', '-m', 'initial commit']
869
- * ```
870
- */
871
- function tokenize(command) {
872
- return (command.match(/[^\s"']+|"([^"]*)"|'([^']*)'/g) ?? []).map((token) => token.replace(/^["']|["']$/g, ""));
873
- }
874
- /**
875
1015
  * Runs the `output.postGenerate` commands of a Kubb config in sequence and returns each command's
876
1016
  * outcome, so the caller can turn failures into diagnostics.
877
1017
  */
@@ -952,6 +1092,41 @@ async function runHook({ id, command, name, args, commandWithArgs, hooks }) {
952
1092
  }
953
1093
  }
954
1094
  /**
1095
+ * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight
1096
+ * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.
1097
+ * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should
1098
+ * coalesce into a single trailing run.
1099
+ *
1100
+ * @example
1101
+ * ```ts
1102
+ * const rebuild = createSerialRunner({
1103
+ * run: () => build(),
1104
+ * onError: (error) => log.error(error.message),
1105
+ * })
1106
+ * watcher.on('change', () => void rebuild())
1107
+ * ```
1108
+ */
1109
+ function createSerialRunner({ run, onError }) {
1110
+ let running = false;
1111
+ let dirty = false;
1112
+ return async () => {
1113
+ if (running) {
1114
+ dirty = true;
1115
+ return;
1116
+ }
1117
+ running = true;
1118
+ do {
1119
+ dirty = false;
1120
+ try {
1121
+ await run();
1122
+ } catch (error) {
1123
+ onError(require_errors.toError(error));
1124
+ }
1125
+ } while (dirty);
1126
+ running = false;
1127
+ };
1128
+ }
1129
+ /**
955
1130
  * Starts a file watcher on the given paths and calls `cb` on any change.
956
1131
  * Ignores `.git` and `node_modules` directories. Event bursts (an editor save emits several)
957
1132
  * are debounced into one build, and builds never overlap: changes during a build queue exactly
@@ -988,272 +1163,77 @@ async function startWatcher(path, cb, log = {
988
1163
  });
989
1164
  }
990
1165
  //#endregion
991
- //#region src/runners/generate/run.ts
992
- /**
993
- * Runs one formatter or linter pass over the output directory. Returns the failure instead of
994
- * throwing, so the caller can turn it into a coded diagnostic. Failures never render here:
995
- * the caller emits them through `Diagnostics.emit`, like every other diagnostic.
996
- */
997
- async function runToolPass({ toolValue, tool, outputPath, logLevel, hooks, onStart, onEnd }) {
998
- await onStart();
999
- let resolvedTool = toolValue;
1000
- if (resolvedTool === "auto") {
1001
- const detected = await tool.detect();
1002
- if (!detected) await hooks.callHook("kubb:warn", { message: tool.noToolMessage });
1003
- else {
1004
- resolvedTool = detected;
1005
- await hooks.callHook("kubb:info", { message: `Auto-detected ${tool.label}: ${(0, node_util.styleText)("dim", resolvedTool)}` });
1006
- }
1166
+ Object.defineProperty(exports, "FORMATTER_PREFERENCE", {
1167
+ enumerable: true,
1168
+ get: function() {
1169
+ return FORMATTER_PREFERENCE;
1007
1170
  }
1008
- let toolError = null;
1009
- if (resolvedTool && resolvedTool !== "auto" && resolvedTool in tool.map && (0, node_fs.existsSync)(outputPath)) {
1010
- const toolConfig = tool.map[resolvedTool];
1011
- const successMessage = [
1012
- `${tool.successPrefix} with ${(0, node_util.styleText)("dim", resolvedTool)}`,
1013
- logLevel >= _kubb_core.logLevel.info ? `on ${(0, node_util.styleText)("dim", outputPath)}` : void 0,
1014
- "successfully"
1015
- ].filter(Boolean).join(" ");
1016
- try {
1017
- const hookId = (0, node_crypto.randomUUID)();
1018
- const hookArgs = toolConfig.args(outputPath);
1019
- const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
1020
- await hooks.callHook("kubb:hook:start", {
1021
- id: hookId,
1022
- command: toolConfig.command,
1023
- args: hookArgs
1024
- });
1025
- const result = await runHook({
1026
- id: hookId,
1027
- command: toolConfig.command,
1028
- args: hookArgs,
1029
- commandWithArgs,
1030
- hooks
1031
- });
1032
- if (result.success) await hooks.callHook("kubb:success", { message: successMessage });
1033
- else toolError = result.error ?? new Error(toolConfig.errorMessage);
1034
- } catch (caughtError) {
1035
- toolError = require_errors.toError(caughtError);
1036
- }
1171
+ });
1172
+ Object.defineProperty(exports, "LINTER_PREFERENCE", {
1173
+ enumerable: true,
1174
+ get: function() {
1175
+ return LINTER_PREFERENCE;
1037
1176
  }
1038
- await onEnd();
1039
- return toolError;
1040
- }
1041
- async function generate(options) {
1042
- const { input, hooks, logLevel, dryRun = false } = options;
1043
- const hrStart = node_process.default.hrtime();
1044
- const inputPath = input ?? (typeof options.config.input === "string" ? options.config.input : void 0);
1045
- const config = {
1046
- ...options.config,
1047
- input: input ?? options.config.input,
1048
- storage: dryRun ? (0, _kubb_core.memoryStorage)() : options.config.storage
1049
- };
1050
- const processOutput = async ({ config: resolvedConfig, outputPath }) => {
1051
- if (dryRun) return [];
1052
- const outputDiagnostics = [];
1053
- const reportOutputFailure = async (code, label, error) => {
1054
- const diagnostic = outputDiagnostic(code, label, error);
1055
- outputDiagnostics.push(diagnostic);
1056
- await _kubb_core.Diagnostics.emit(hooks, diagnostic);
1057
- };
1058
- const toolPasses = [{
1059
- value: resolvedConfig.output.format,
1060
- code: _kubb_core.Diagnostics.code.formatFailed,
1061
- tool: {
1062
- label: "formatter",
1063
- map: require_tools.formatters,
1064
- detect: () => require_tools.detectTool([
1065
- "oxfmt",
1066
- "biome",
1067
- "prettier"
1068
- ]),
1069
- successPrefix: "Formatting",
1070
- noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting."
1071
- },
1072
- onStart: () => hooks.callHook("kubb:format:start"),
1073
- onEnd: () => hooks.callHook("kubb:format:end")
1074
- }, {
1075
- value: resolvedConfig.output.lint,
1076
- code: _kubb_core.Diagnostics.code.lintFailed,
1077
- tool: {
1078
- label: "linter",
1079
- map: require_tools.linters,
1080
- detect: () => require_tools.detectTool([
1081
- "oxlint",
1082
- "biome",
1083
- "eslint"
1084
- ]),
1085
- successPrefix: "Linting",
1086
- noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting."
1087
- },
1088
- onStart: () => hooks.callHook("kubb:lint:start"),
1089
- onEnd: () => hooks.callHook("kubb:lint:end")
1090
- }];
1091
- for (const pass of toolPasses) {
1092
- if (!pass.value) continue;
1093
- const error = await runToolPass({
1094
- toolValue: pass.value,
1095
- tool: pass.tool,
1096
- onStart: pass.onStart,
1097
- onEnd: pass.onEnd,
1098
- outputPath,
1099
- logLevel,
1100
- hooks
1101
- });
1102
- if (error) await reportOutputFailure(pass.code, pass.tool.label, error);
1103
- }
1104
- if (resolvedConfig.output.postGenerate?.length) {
1105
- await hooks.callHook("kubb:hooks:start");
1106
- const hookResults = await runPostGenerate({
1107
- commands: resolvedConfig.output.postGenerate,
1108
- hooks
1109
- });
1110
- for (const hookResult of hookResults) {
1111
- if (hookResult.success) continue;
1112
- await reportOutputFailure(_kubb_core.Diagnostics.code.postGenerateFailed, "Post-generate command", hookResult.error ?? /* @__PURE__ */ new Error("Post-generate command failed"));
1113
- }
1114
- await hooks.callHook("kubb:hooks:end");
1115
- }
1116
- return outputDiagnostics;
1117
- };
1118
- hooks.hook("kubb:generation:end", ({ status }) => {
1119
- if (status === "success") return hooks.callHook("kubb:success", {
1120
- message: "Generation succeeded",
1121
- info: inputPath
1122
- });
1123
- });
1124
- const kubb = (0, _kubb_core.createKubb)(config, { hooks });
1125
- const result = await kubb.generate({ processOutput });
1126
- if (dryRun) await hooks.callHook("kubb:info", {
1127
- message: "Dry run: no files were written",
1128
- info: `${result.files.length} file(s) would be generated`
1129
- });
1130
- const telemetryPlugins = Array.from(kubb.driver.plugins.values(), (p) => ({
1131
- name: p.name,
1132
- options: p.options
1133
- }));
1134
- await require_Telemetry.sendTelemetry(require_Telemetry.buildTelemetryEvent({
1135
- command: "generate",
1136
- kubbVersion: require_package.version,
1137
- plugins: telemetryPlugins,
1138
- hrStart,
1139
- filesCreated: result.files.length,
1140
- status: result.success ? "success" : "failed"
1141
- }));
1142
- return result.success;
1143
- }
1144
- /**
1145
- * Builds a coded diagnostic for an output-phase failure (formatter, linter, or `done` hook).
1146
- */
1147
- function outputDiagnostic(code, label, caughtError) {
1148
- const error = require_errors.toError(caughtError);
1149
- return {
1150
- code,
1151
- severity: "error",
1152
- message: `${label} failed: ${error.message}`,
1153
- help: "Check that the tool is installed and that the command and its config are correct.",
1154
- location: { kind: "config" },
1155
- cause: error
1156
- };
1157
- }
1158
- async function checkForUpdate(hooks) {
1159
- try {
1160
- const data = await (await fetch(require_Telemetry.KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(require_Telemetry.UPDATE_CHECK_TIMEOUT_MS) })).json();
1161
- if (data.version && isNewerVersion(require_package.version, data.version)) await _kubb_core.Diagnostics.emit(hooks, _kubb_core.Diagnostics.update({
1162
- currentVersion: require_package.version,
1163
- latestVersion: data.version
1164
- }));
1165
- } catch {}
1166
- }
1167
- /**
1168
- * Runs the full Kubb generation lifecycle for the given CLI options.
1169
- * Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),
1170
- * checks for a newer version, and calls `generate` for each config entry.
1171
- */
1172
- async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }) {
1173
- const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
1174
- const hooks = new _kubb_core.Hookable();
1175
- let configs;
1176
- let resolvedConfigPath;
1177
- try {
1178
- const loaded = await getConfigs({
1179
- configPath,
1180
- input,
1181
- watch,
1182
- logLevel: logLevelKey
1183
- });
1184
- configs = loaded.configs;
1185
- resolvedConfigPath = loaded.configPath;
1186
- } catch (error) {
1187
- await setupReporters(hooks, {
1188
- logLevel,
1189
- reporters: [_kubb_core.cliReporter]
1190
- });
1191
- await hooks.callHook("kubb:error", { error: require_errors.toError(error) });
1192
- node_process.default.exit(1);
1177
+ });
1178
+ Object.defineProperty(exports, "detectTool", {
1179
+ enumerable: true,
1180
+ get: function() {
1181
+ return detectTool;
1193
1182
  }
1194
- const requestedNames = cliReporters?.length ? cliReporters : ["cli"];
1195
- await setupReporters(hooks, {
1196
- logLevel,
1197
- reporters: selectReporters(configs[0]?.reporters ?? [], requestedNames)
1198
- });
1199
- await hooks.callHook("kubb:lifecycle:start", { version: require_package.version });
1200
- await checkForUpdate(hooks);
1201
- try {
1202
- const relativeConfigPath = node_path.default.relative(node_process.default.cwd(), resolvedConfigPath);
1203
- await hooks.callHook("kubb:info", {
1204
- message: "Config loaded",
1205
- info: relativeConfigPath
1206
- });
1207
- await hooks.callHook("kubb:success", {
1208
- message: "Config loaded successfully",
1209
- info: relativeConfigPath
1210
- });
1211
- let anyFailed = false;
1212
- for (const config of configs) {
1213
- const effectiveInput = input ?? config.input;
1214
- const watchPath = typeof effectiveInput === "string" && (0, _kubb_core.getInputKind)(effectiveInput) === "file" ? effectiveInput : void 0;
1215
- if (watchPath && watch) {
1216
- const watchedPaths = [watchPath];
1217
- const build = async (paths) => {
1218
- await generate({
1219
- input,
1220
- config,
1221
- logLevel,
1222
- hooks,
1223
- dryRun
1224
- });
1225
- _clack_prompts.log.step((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
1226
- };
1227
- try {
1228
- await build(watchedPaths);
1229
- } catch (buildError) {
1230
- await hooks.callHook("kubb:error", { error: require_errors.toError(buildError) });
1231
- }
1232
- await startWatcher(watchedPaths, build, {
1233
- info: (msg) => _clack_prompts.log.info(msg),
1234
- error: (msg) => _clack_prompts.log.error(msg)
1235
- });
1236
- } else try {
1237
- if (!await generate({
1238
- input,
1239
- config,
1240
- logLevel,
1241
- hooks,
1242
- dryRun
1243
- })) anyFailed = true;
1244
- } catch (configError) {
1245
- await hooks.callHook("kubb:error", { error: require_errors.toError(configError) });
1246
- anyFailed = true;
1247
- }
1248
- }
1249
- await hooks.callHook("kubb:lifecycle:end");
1250
- if (anyFailed) node_process.default.exit(1);
1251
- } catch (error) {
1252
- await hooks.callHook("kubb:error", { error: require_errors.toError(error) });
1253
- node_process.default.exit(1);
1183
+ });
1184
+ Object.defineProperty(exports, "formatters", {
1185
+ enumerable: true,
1186
+ get: function() {
1187
+ return formatters;
1254
1188
  }
1255
- }
1256
- //#endregion
1257
- exports.run = run;
1189
+ });
1190
+ Object.defineProperty(exports, "getConfigs", {
1191
+ enumerable: true,
1192
+ get: function() {
1193
+ return getConfigs;
1194
+ }
1195
+ });
1196
+ Object.defineProperty(exports, "isNewerVersion", {
1197
+ enumerable: true,
1198
+ get: function() {
1199
+ return isNewerVersion;
1200
+ }
1201
+ });
1202
+ Object.defineProperty(exports, "linters", {
1203
+ enumerable: true,
1204
+ get: function() {
1205
+ return linters;
1206
+ }
1207
+ });
1208
+ Object.defineProperty(exports, "runHook", {
1209
+ enumerable: true,
1210
+ get: function() {
1211
+ return runHook;
1212
+ }
1213
+ });
1214
+ Object.defineProperty(exports, "runPostGenerate", {
1215
+ enumerable: true,
1216
+ get: function() {
1217
+ return runPostGenerate;
1218
+ }
1219
+ });
1220
+ Object.defineProperty(exports, "selectReporters", {
1221
+ enumerable: true,
1222
+ get: function() {
1223
+ return selectReporters;
1224
+ }
1225
+ });
1226
+ Object.defineProperty(exports, "setupReporters", {
1227
+ enumerable: true,
1228
+ get: function() {
1229
+ return setupReporters;
1230
+ }
1231
+ });
1232
+ Object.defineProperty(exports, "startWatcher", {
1233
+ enumerable: true,
1234
+ get: function() {
1235
+ return startWatcher;
1236
+ }
1237
+ });
1258
1238
 
1259
- //# sourceMappingURL=run-DAGbErY0.cjs.map
1239
+ //# sourceMappingURL=utils-B0SrWoNh.cjs.map