@kubb/cli 4.11.3 → 4.12.1

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 (52) hide show
  1. package/dist/generate-BfIvo80v.js +1249 -0
  2. package/dist/generate-BfIvo80v.js.map +1 -0
  3. package/dist/generate-BoZaeXSl.cjs +1256 -0
  4. package/dist/generate-BoZaeXSl.cjs.map +1 -0
  5. package/dist/index.cjs +9 -35
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +7 -30
  8. package/dist/index.js.map +1 -1
  9. package/dist/{mcp-BIRDY8xn.js → mcp-LLlOFV3c.js} +5 -6
  10. package/dist/mcp-LLlOFV3c.js.map +1 -0
  11. package/dist/{mcp-BQjDRDXR.cjs → mcp-N1IVyiXf.cjs} +5 -7
  12. package/dist/mcp-N1IVyiXf.cjs.map +1 -0
  13. package/dist/package-B1rQiz1w.js +6 -0
  14. package/dist/package-B1rQiz1w.js.map +1 -0
  15. package/dist/package-CngLazMY.cjs +12 -0
  16. package/dist/package-CngLazMY.cjs.map +1 -0
  17. package/dist/{validate-0i6Q9eIy.js → validate-BptoQ-63.js} +5 -6
  18. package/dist/validate-BptoQ-63.js.map +1 -0
  19. package/dist/{validate-6F-VPZR7.cjs → validate-Dn6hZ7Z4.cjs} +5 -7
  20. package/dist/validate-Dn6hZ7Z4.cjs.map +1 -0
  21. package/package.json +7 -7
  22. package/src/commands/generate.ts +52 -65
  23. package/src/commands/mcp.ts +4 -5
  24. package/src/commands/validate.ts +4 -5
  25. package/src/index.ts +8 -23
  26. package/src/loggers/clackLogger.ts +433 -0
  27. package/src/loggers/envDetection.ts +28 -0
  28. package/src/loggers/fileSystemLogger.ts +79 -0
  29. package/src/loggers/githubActionsLogger.ts +310 -0
  30. package/src/loggers/index.ts +5 -0
  31. package/src/loggers/plainLogger.ts +274 -0
  32. package/src/loggers/types.ts +1 -0
  33. package/src/loggers/utils.ts +43 -0
  34. package/src/runners/generate.ts +196 -208
  35. package/src/utils/Writables.ts +12 -8
  36. package/src/utils/executeHooks.ts +11 -18
  37. package/src/utils/getCosmiConfig.ts +6 -1
  38. package/src/utils/getSummary.ts +20 -42
  39. package/src/utils/randomColour.ts +26 -0
  40. package/src/utils/watcher.ts +2 -4
  41. package/dist/generate-CYBFB3tU.js +0 -221
  42. package/dist/generate-CYBFB3tU.js.map +0 -1
  43. package/dist/generate-CpBJ2Y-n.js +0 -342
  44. package/dist/generate-CpBJ2Y-n.js.map +0 -1
  45. package/dist/generate-DpHvARzf.cjs +0 -345
  46. package/dist/generate-DpHvARzf.cjs.map +0 -1
  47. package/dist/generate-KUqCSnZp.cjs +0 -225
  48. package/dist/generate-KUqCSnZp.cjs.map +0 -1
  49. package/dist/mcp-BIRDY8xn.js.map +0 -1
  50. package/dist/mcp-BQjDRDXR.cjs.map +0 -1
  51. package/dist/validate-0i6Q9eIy.js.map +0 -1
  52. package/dist/validate-6F-VPZR7.cjs.map +0 -1
@@ -0,0 +1,1249 @@
1
+ import { t as version } from "./package-B1rQiz1w.js";
2
+ import { defineCommand, showUsage } from "citty";
3
+ import path, { relative, resolve } from "node:path";
4
+ import * as process$2 from "node:process";
5
+ import process$1 from "node:process";
6
+ import * as clack from "@clack/prompts";
7
+ import { LogLevel, PromiseManager, defineLogger, isInputPath, safeBuild, setup } from "@kubb/core";
8
+ import { AsyncEventEmitter, isPromise } from "@kubb/core/utils";
9
+ import getLatestVersion from "latest-version";
10
+ import pc from "picocolors";
11
+ import { lt } from "semver";
12
+ import { execa } from "execa";
13
+ import gradientString from "gradient-string";
14
+ import seedrandom from "seedrandom";
15
+ import { Writable } from "node:stream";
16
+ import { write } from "@kubb/core/fs";
17
+ import { parseArgsStringToArgv } from "string-argv";
18
+ import { cosmiconfig } from "cosmiconfig";
19
+ import { createJiti } from "jiti";
20
+
21
+ //#region src/utils/parseHrtimeToSeconds.ts
22
+ function parseHrtimeToSeconds(hrtime) {
23
+ return (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
24
+ }
25
+
26
+ //#endregion
27
+ //#region src/utils/randomColour.ts
28
+ function randomColour(text) {
29
+ if (!text) return "white";
30
+ const defaultColours = [
31
+ "black",
32
+ "red",
33
+ "green",
34
+ "yellow",
35
+ "blue",
36
+ "red",
37
+ "green",
38
+ "magenta",
39
+ "cyan",
40
+ "gray"
41
+ ];
42
+ const random = seedrandom(text);
43
+ return defaultColours.at(Math.floor(random() * defaultColours.length)) || "white";
44
+ }
45
+ function randomCliColour(text) {
46
+ if (!text) return "";
47
+ const fn = pc[randomColour(text)];
48
+ return fn ? fn(text) : text;
49
+ }
50
+
51
+ //#endregion
52
+ //#region src/utils/getSummary.ts
53
+ function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
54
+ const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrStart));
55
+ const pluginsCount = config.plugins?.length || 0;
56
+ const successCount = pluginsCount - failedPlugins.size;
57
+ const meta = {
58
+ plugins: status === "success" ? `${pc.green(`${successCount} successful`)}, ${pluginsCount} total` : `${pc.green(`${successCount} successful`)}, ${pc.red(`${failedPlugins.size} failed`)}, ${pluginsCount} total`,
59
+ pluginsFailed: status === "failed" ? [...failedPlugins]?.map(({ plugin }) => randomCliColour(plugin.name))?.join(", ") : void 0,
60
+ filesCreated,
61
+ time: `${elapsedSeconds}s`,
62
+ output: path.isAbsolute(config.root) ? path.resolve(config.root, config.output.path) : config.root
63
+ };
64
+ const labels = {
65
+ plugins: "Plugins:",
66
+ failed: "Failed:",
67
+ generated: "Generated:",
68
+ pluginTimings: "Plugin Timings:",
69
+ output: "Output:"
70
+ };
71
+ const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
72
+ const summaryLines = [];
73
+ summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
74
+ if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
75
+ summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
76
+ if (pluginTimings && pluginTimings.size > 0) {
77
+ const TIME_SCALE_DIVISOR = 100;
78
+ const MAX_BAR_LENGTH = 10;
79
+ const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
80
+ if (sortedTimings.length > 0) {
81
+ summaryLines.push(`${labels.pluginTimings}`);
82
+ sortedTimings.forEach(([name, time]) => {
83
+ const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
84
+ const barLength = Math.min(Math.ceil(time / TIME_SCALE_DIVISOR), MAX_BAR_LENGTH);
85
+ const bar = pc.dim("█".repeat(barLength));
86
+ summaryLines.push(`${pc.dim("•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
87
+ });
88
+ }
89
+ }
90
+ summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
91
+ return summaryLines;
92
+ }
93
+
94
+ //#endregion
95
+ //#region src/utils/Writables.ts
96
+ var ClackWritable = class extends Writable {
97
+ taskLog;
98
+ constructor(taskLog, opts) {
99
+ super(opts);
100
+ this.taskLog = taskLog;
101
+ }
102
+ _write(chunk, _encoding, callback) {
103
+ this.taskLog.message(`${pc.dim(chunk?.toString())}`);
104
+ callback();
105
+ }
106
+ };
107
+
108
+ //#endregion
109
+ //#region src/loggers/clackLogger.ts
110
+ /**
111
+ * Clack adapter for local TTY environments
112
+ * Provides a beautiful CLI UI with flat structure inspired by Claude's CLI patterns
113
+ */
114
+ const clackLogger = defineLogger({
115
+ name: "clack",
116
+ install(context, options) {
117
+ const logLevel = options?.logLevel || LogLevel.info;
118
+ const activeProgress = /* @__PURE__ */ new Map();
119
+ const spinner = clack.spinner();
120
+ let isSpinning = false;
121
+ function getMessage(message) {
122
+ if (logLevel >= LogLevel.verbose) {
123
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
124
+ hour12: false,
125
+ hour: "2-digit",
126
+ minute: "2-digit",
127
+ second: "2-digit"
128
+ });
129
+ return [pc.dim(`[${timestamp}]`), message].join(" ");
130
+ }
131
+ return message;
132
+ }
133
+ function startSpinner(text) {
134
+ spinner.start(text);
135
+ isSpinning = true;
136
+ }
137
+ function stopSpinner(text) {
138
+ spinner.stop(text);
139
+ isSpinning = false;
140
+ }
141
+ context.on("info", (message, info = "") => {
142
+ if (logLevel <= LogLevel.silent) return;
143
+ const text = getMessage([
144
+ pc.blue("ℹ"),
145
+ message,
146
+ pc.dim(info)
147
+ ].join(" "));
148
+ if (isSpinning) spinner.message(text);
149
+ else clack.log.info(text);
150
+ });
151
+ context.on("success", (message, info = "") => {
152
+ if (logLevel <= LogLevel.silent) return;
153
+ const text = getMessage([
154
+ pc.blue("✓"),
155
+ message,
156
+ logLevel >= LogLevel.info ? pc.dim(info) : void 0
157
+ ].filter(Boolean).join(" "));
158
+ if (isSpinning) stopSpinner(text);
159
+ else clack.log.success(text);
160
+ });
161
+ context.on("warn", (message, info) => {
162
+ if (logLevel < LogLevel.warn) return;
163
+ const text = getMessage([
164
+ pc.yellow("⚠"),
165
+ message,
166
+ logLevel >= LogLevel.info ? pc.dim(info) : void 0
167
+ ].filter(Boolean).join(" "));
168
+ clack.log.warn(text);
169
+ });
170
+ context.on("error", (error) => {
171
+ const caused = error.cause;
172
+ const text = [pc.red("✗"), error.message].join(" ");
173
+ if (isSpinning) stopSpinner(getMessage(text));
174
+ else clack.log.error(getMessage(text));
175
+ if (logLevel >= LogLevel.debug && error.stack) {
176
+ const frames = error.stack.split("\n").slice(1, 4);
177
+ for (const frame of frames) clack.log.message(getMessage(pc.dim(frame.trim())));
178
+ if (caused?.stack) {
179
+ clack.log.message(pc.dim(`└─ caused by ${caused.message}`));
180
+ const frames$1 = caused.stack.split("\n").slice(1, 4);
181
+ for (const frame of frames$1) clack.log.message(getMessage(` ${pc.dim(frame.trim())}`));
182
+ }
183
+ }
184
+ });
185
+ context.on("version:new", (version$1, latestVersion) => {
186
+ if (logLevel <= LogLevel.silent) return;
187
+ clack.box(`\`v${version$1}\` → \`v${latestVersion}\`
188
+ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
189
+ width: "auto",
190
+ formatBorder: pc.yellow,
191
+ rounded: true,
192
+ withGuide: false,
193
+ contentAlign: "center",
194
+ titleAlign: "center"
195
+ });
196
+ });
197
+ context.on("lifecycle:start", (version$1) => {
198
+ console.log(gradientString([
199
+ "#F58517",
200
+ "#F5A217",
201
+ "#F55A17"
202
+ ])(`Kubb ${version$1} 🧩`));
203
+ });
204
+ context.on("config:start", () => {
205
+ if (logLevel <= LogLevel.silent) return;
206
+ const text = getMessage("Configuration started");
207
+ clack.intro(text);
208
+ startSpinner(getMessage("Configuration loading"));
209
+ });
210
+ context.on("config:end", () => {
211
+ if (logLevel <= LogLevel.silent) return;
212
+ const text = getMessage("Configuration completed");
213
+ clack.outro(text);
214
+ });
215
+ context.on("generation:start", (config) => {
216
+ const text = getMessage(["Generation started", config.name ? `for ${pc.dim(config.name)}` : void 0].filter(Boolean).join(" "));
217
+ clack.intro(text);
218
+ });
219
+ context.on("plugin:start", (plugin) => {
220
+ if (logLevel <= LogLevel.silent) return;
221
+ stopSpinner();
222
+ const progressBar = clack.progress({
223
+ style: "block",
224
+ max: 100,
225
+ size: 30
226
+ });
227
+ const text = getMessage(`Generating ${pc.bold(plugin.name)}`);
228
+ progressBar.start(text);
229
+ const interval = setInterval(() => {
230
+ progressBar.advance();
231
+ }, 50);
232
+ activeProgress.set(plugin.name, {
233
+ progressBar,
234
+ interval
235
+ });
236
+ });
237
+ context.on("plugin:end", (plugin, duration) => {
238
+ stopSpinner();
239
+ const active = activeProgress.get(plugin.name);
240
+ if (!active || logLevel === LogLevel.silent) return;
241
+ clearInterval(active.interval);
242
+ const durationStr = duration >= 1e3 ? `${(duration / 1e3).toFixed(2)}s` : `${duration}ms`;
243
+ const text = getMessage(`${pc.bold(plugin.name)} completed in ${pc.green(durationStr)}`);
244
+ active.progressBar.stop(text);
245
+ activeProgress.delete(plugin.name);
246
+ });
247
+ context.on("files:processing:start", (files) => {
248
+ if (logLevel <= LogLevel.silent) return;
249
+ stopSpinner();
250
+ const text = getMessage(`Writing ${files.length} files`);
251
+ const progressBar = clack.progress({
252
+ style: "block",
253
+ max: files.length,
254
+ size: 30
255
+ });
256
+ context.emit("info", text);
257
+ progressBar.start(text);
258
+ activeProgress.set("files", { progressBar });
259
+ });
260
+ context.on("file:processing:update", ({ file, config }) => {
261
+ if (logLevel <= LogLevel.silent) return;
262
+ stopSpinner();
263
+ const text = `Writing ${relative(config.root, file.path)}`;
264
+ const active = activeProgress.get("files");
265
+ if (!active) return;
266
+ active.progressBar.advance(void 0, text);
267
+ });
268
+ context.on("files:processing:end", () => {
269
+ if (logLevel <= LogLevel.silent) return;
270
+ stopSpinner();
271
+ const text = getMessage("Files written successfully");
272
+ const active = activeProgress.get("files");
273
+ if (!active) return;
274
+ active.progressBar.stop(text);
275
+ activeProgress.delete("files");
276
+ });
277
+ context.on("generation:end", (config) => {
278
+ const text = getMessage(config.name ? `Generation completed for ${pc.dim(config.name)}` : "Generation completed");
279
+ clack.outro(text);
280
+ });
281
+ context.on("hook:execute", async ({ command: command$1, args }, cb) => {
282
+ if (logLevel <= LogLevel.silent) {
283
+ try {
284
+ const result = await execa(command$1, args, {
285
+ detached: true,
286
+ stripFinalNewline: true
287
+ });
288
+ await context.emit("debug", {
289
+ date: /* @__PURE__ */ new Date(),
290
+ logs: [result.stdout]
291
+ });
292
+ cb();
293
+ } catch (err) {
294
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
295
+ error.cause = err;
296
+ await context.emit("debug", {
297
+ date: /* @__PURE__ */ new Date(),
298
+ logs: [err.stdout]
299
+ });
300
+ await context.emit("error", error);
301
+ }
302
+ return;
303
+ }
304
+ const writable = new ClackWritable(clack.taskLog({ title: getMessage(["Executing hook", logLevel >= LogLevel.info ? pc.dim(`${command$1} ${args?.join(" ")}`) : void 0].filter(Boolean).join(" ")) }));
305
+ try {
306
+ const result = await execa(command$1, args, {
307
+ detached: true,
308
+ stdout: ["pipe", writable],
309
+ stripFinalNewline: true
310
+ });
311
+ await context.emit("debug", {
312
+ date: /* @__PURE__ */ new Date(),
313
+ logs: [result.stdout]
314
+ });
315
+ cb();
316
+ } catch (err) {
317
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
318
+ error.cause = err;
319
+ await context.emit("debug", {
320
+ date: /* @__PURE__ */ new Date(),
321
+ logs: [err.stdout]
322
+ });
323
+ await context.emit("error", error);
324
+ }
325
+ });
326
+ context.on("format:start", () => {
327
+ if (logLevel <= LogLevel.silent) return;
328
+ const text = getMessage("Format started");
329
+ clack.intro(text);
330
+ });
331
+ context.on("format:end", () => {
332
+ if (logLevel <= LogLevel.silent) return;
333
+ const text = getMessage("Format completed");
334
+ clack.outro(text);
335
+ });
336
+ context.on("lint:start", () => {
337
+ if (logLevel <= LogLevel.silent) return;
338
+ const text = getMessage("Lint started");
339
+ clack.intro(text);
340
+ });
341
+ context.on("lint:end", () => {
342
+ if (logLevel <= LogLevel.silent) return;
343
+ const text = getMessage("Lint completed");
344
+ clack.outro(text);
345
+ });
346
+ context.on("hook:start", (command$1) => {
347
+ if (logLevel <= LogLevel.silent) return;
348
+ const text = getMessage(`Hook ${pc.dim(command$1)} started`);
349
+ clack.intro(text);
350
+ });
351
+ context.on("hook:end", (command$1) => {
352
+ if (logLevel <= LogLevel.silent) return;
353
+ const text = getMessage(`Hook ${pc.dim(command$1)} completed`);
354
+ clack.outro(text);
355
+ });
356
+ context.on("generation:summary", (config, { pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
357
+ const summary = getSummary({
358
+ failedPlugins,
359
+ filesCreated,
360
+ config,
361
+ status,
362
+ hrStart,
363
+ pluginTimings: logLevel >= LogLevel.verbose ? pluginTimings : void 0
364
+ });
365
+ const title = config.name || "";
366
+ summary.unshift("\n");
367
+ summary.push("\n");
368
+ if (status === "success") {
369
+ clack.box(summary.join("\n"), getMessage(title), {
370
+ width: "auto",
371
+ formatBorder: pc.green,
372
+ rounded: true,
373
+ withGuide: false,
374
+ contentAlign: "left",
375
+ titleAlign: "center"
376
+ });
377
+ return;
378
+ }
379
+ clack.box(summary.join("\n"), getMessage(title), {
380
+ width: "auto",
381
+ formatBorder: pc.red,
382
+ rounded: true,
383
+ withGuide: false,
384
+ contentAlign: "left",
385
+ titleAlign: "center"
386
+ });
387
+ });
388
+ context.on("lifecycle:end", () => {
389
+ for (const [_key, active] of activeProgress) {
390
+ if (active.interval) clearInterval(active.interval);
391
+ active.progressBar?.stop();
392
+ }
393
+ activeProgress.clear();
394
+ });
395
+ }
396
+ });
397
+
398
+ //#endregion
399
+ //#region src/loggers/envDetection.ts
400
+ /**
401
+ * Check if running in GitHub Actions environment
402
+ */
403
+ function isGitHubActions() {
404
+ return !!process.env.GITHUB_ACTIONS;
405
+ }
406
+ /**
407
+ * Check if running in any CI environment
408
+ */
409
+ function isCIEnvironment() {
410
+ return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.TRAVIS || process.env.JENKINS_URL || process.env.BUILDKITE);
411
+ }
412
+ /**
413
+ * Check if TTY is available for interactive output
414
+ */
415
+ function canUseTTY() {
416
+ return !!process.stdout.isTTY && !isCIEnvironment();
417
+ }
418
+
419
+ //#endregion
420
+ //#region src/loggers/fileSystemLogger.ts
421
+ /**
422
+ * FileSystem logger for debug log persistence
423
+ * Captures debug and verbose events and writes them to files in .kubb directory
424
+ *
425
+ * Note: Logs are written on lifecycle:end or process exit. If the process crashes
426
+ * before these events, some cached logs may be lost.
427
+ */
428
+ const fileSystemLogger = defineLogger({
429
+ name: "filesystem",
430
+ install(context) {
431
+ const cachedLogs = /* @__PURE__ */ new Set();
432
+ const startDate = Date.now();
433
+ async function writeLogs() {
434
+ if (cachedLogs.size === 0) return;
435
+ const files = {};
436
+ for (const log of cachedLogs) {
437
+ const fileName = resolve(process.cwd(), ".kubb", log.fileName || `kubb-${startDate}.log`);
438
+ if (!files[fileName]) files[fileName] = [];
439
+ if (log.logs.length > 0) {
440
+ const timestamp = log.date.toLocaleString();
441
+ files[fileName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
442
+ }
443
+ }
444
+ await Promise.all(Object.entries(files).map(async ([fileName, logs]) => {
445
+ return write(fileName, logs.join("\n\n"));
446
+ }));
447
+ cachedLogs.clear();
448
+ }
449
+ context.on("debug", (message) => {
450
+ cachedLogs.add({
451
+ date: /* @__PURE__ */ new Date(),
452
+ logs: message.logs,
453
+ fileName: void 0
454
+ });
455
+ });
456
+ context.on("lifecycle:end", async () => {
457
+ await writeLogs();
458
+ });
459
+ const exitHandler = () => {
460
+ if (cachedLogs.size > 0) writeLogs().catch(() => {});
461
+ };
462
+ process.once("exit", exitHandler);
463
+ process.once("SIGINT", exitHandler);
464
+ process.once("SIGTERM", exitHandler);
465
+ }
466
+ });
467
+
468
+ //#endregion
469
+ //#region src/loggers/githubActionsLogger.ts
470
+ /**
471
+ * GitHub Actions adapter for CI environments
472
+ * Uses ::group:: and ::endgroup:: annotations for collapsible sections
473
+ */
474
+ const githubActionsLogger = defineLogger({
475
+ name: "github-actions",
476
+ install(context, options) {
477
+ const logLevel = options?.logLevel || LogLevel.info;
478
+ let currentConfigs = [];
479
+ function getMessage(message) {
480
+ if (logLevel >= LogLevel.verbose) {
481
+ const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
482
+ hour12: false,
483
+ hour: "2-digit",
484
+ minute: "2-digit",
485
+ second: "2-digit"
486
+ });
487
+ return [pc.dim(`[${timestamp}]`), message].join(" ");
488
+ }
489
+ return message;
490
+ }
491
+ function openGroup(name) {
492
+ console.log(`::group::${name}`);
493
+ }
494
+ function closeGroup(_name) {
495
+ console.log("::endgroup::");
496
+ }
497
+ context.on("info", (message, info = "") => {
498
+ if (logLevel <= LogLevel.silent) return;
499
+ const text = getMessage([
500
+ pc.blue("ℹ"),
501
+ message,
502
+ pc.dim(info)
503
+ ].join(" "));
504
+ console.log(text);
505
+ });
506
+ context.on("success", (message, info = "") => {
507
+ if (logLevel <= LogLevel.silent) return;
508
+ const text = getMessage([
509
+ pc.blue("✓"),
510
+ message,
511
+ logLevel >= LogLevel.info ? pc.dim(info) : void 0
512
+ ].filter(Boolean).join(" "));
513
+ console.log(text);
514
+ });
515
+ context.on("warn", (message, info = "") => {
516
+ if (logLevel <= LogLevel.silent) return;
517
+ const text = getMessage([
518
+ pc.yellow("⚠"),
519
+ message,
520
+ logLevel >= LogLevel.info ? pc.dim(info) : void 0
521
+ ].filter(Boolean).join(" "));
522
+ console.warn(`::warning::${text}`);
523
+ });
524
+ context.on("error", (error) => {
525
+ if (logLevel <= LogLevel.silent) return;
526
+ const message = error.message || String(error);
527
+ console.error(`::error::${message}`);
528
+ });
529
+ context.on("lifecycle:start", (version$1) => {
530
+ console.log(pc.yellow(`Kubb ${version$1} 🧩`));
531
+ });
532
+ context.on("config:start", () => {
533
+ if (logLevel <= LogLevel.silent) return;
534
+ const text = getMessage("Configuration started");
535
+ openGroup("Configuration");
536
+ console.log(text);
537
+ });
538
+ context.on("config:end", (configs) => {
539
+ currentConfigs = configs;
540
+ if (logLevel <= LogLevel.silent) return;
541
+ const text = getMessage("Configuration completed");
542
+ console.log(text);
543
+ closeGroup("Configuration");
544
+ });
545
+ context.on("generation:start", (config) => {
546
+ const text = config.name ? `Generation for ${pc.bold(config.name)}` : "Generation";
547
+ if (currentConfigs.length > 1) openGroup(text);
548
+ if (currentConfigs.length === 1) console.log(getMessage(text));
549
+ });
550
+ context.on("plugin:start", (plugin) => {
551
+ if (logLevel <= LogLevel.silent) return;
552
+ const text = getMessage(`Generating ${pc.bold(plugin.name)}`);
553
+ if (currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
554
+ console.log(text);
555
+ });
556
+ context.on("plugin:end", (plugin, duration) => {
557
+ if (logLevel <= LogLevel.silent) return;
558
+ const durationStr = duration >= 1e3 ? `${(duration / 1e3).toFixed(2)}s` : `${duration}ms`;
559
+ const text = getMessage(`${pc.bold(plugin.name)} completed in ${pc.green(durationStr)}`);
560
+ console.log(text);
561
+ if (currentConfigs.length > 1) console.log(" ");
562
+ if (currentConfigs.length === 1) closeGroup(`Plugin: ${plugin.name}`);
563
+ });
564
+ context.on("files:processing:start", (files) => {
565
+ if (logLevel <= LogLevel.silent) return;
566
+ if (currentConfigs.length === 1) openGroup("File Generation");
567
+ const text = getMessage(`Writing ${files.length} files`);
568
+ console.log(text);
569
+ });
570
+ context.on("files:processing:end", () => {
571
+ if (logLevel <= LogLevel.silent) return;
572
+ const text = getMessage("Files written successfully");
573
+ console.log(text);
574
+ if (currentConfigs.length === 1) closeGroup("File Generation");
575
+ });
576
+ context.on("generation:end", (config) => {
577
+ const text = getMessage(config.name ? `${pc.blue("✓")} Generation completed for ${pc.dim(config.name)}` : `${pc.blue("✓")} Generation completed`);
578
+ console.log(text);
579
+ });
580
+ context.on("hook:execute", async ({ command: command$1, args }, cb) => {
581
+ try {
582
+ const result = await execa(command$1, args, {
583
+ detached: true,
584
+ stripFinalNewline: true
585
+ });
586
+ await context.emit("debug", {
587
+ date: /* @__PURE__ */ new Date(),
588
+ logs: [result.stdout]
589
+ });
590
+ console.log(result.stdout);
591
+ cb();
592
+ } catch (err) {
593
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
594
+ error.cause = err;
595
+ await context.emit("debug", {
596
+ date: /* @__PURE__ */ new Date(),
597
+ logs: [err.stdout]
598
+ });
599
+ await context.emit("error", error);
600
+ }
601
+ });
602
+ context.on("format:start", () => {
603
+ if (logLevel <= LogLevel.silent) return;
604
+ const text = getMessage("Format started");
605
+ if (currentConfigs.length === 1) openGroup("Formatting");
606
+ console.log(text);
607
+ });
608
+ context.on("format:end", () => {
609
+ if (logLevel <= LogLevel.silent) return;
610
+ const text = getMessage("Format completed");
611
+ console.log(text);
612
+ if (currentConfigs.length === 1) closeGroup("Formatting");
613
+ });
614
+ context.on("lint:start", () => {
615
+ if (logLevel <= LogLevel.silent) return;
616
+ const text = getMessage("Lint started");
617
+ if (currentConfigs.length === 1) openGroup("Linting");
618
+ console.log(text);
619
+ });
620
+ context.on("lint:end", () => {
621
+ if (logLevel <= LogLevel.silent) return;
622
+ const text = getMessage("Lint completed");
623
+ console.log(text);
624
+ if (currentConfigs.length === 1) closeGroup("Linting");
625
+ });
626
+ context.on("hook:start", (command$1) => {
627
+ if (logLevel <= LogLevel.silent) return;
628
+ const text = getMessage(`Hook ${pc.dim(command$1)} started`);
629
+ if (currentConfigs.length === 1) openGroup(`Hook ${command$1}`);
630
+ console.log(text);
631
+ });
632
+ context.on("hook:end", (command$1) => {
633
+ if (logLevel <= LogLevel.silent) return;
634
+ const text = getMessage(`Hook ${pc.dim(command$1)} completed`);
635
+ console.log(text);
636
+ if (currentConfigs.length === 1) closeGroup(`Hook ${command$1}`);
637
+ });
638
+ context.on("generation:summary", (config, { status, failedPlugins }) => {
639
+ const pluginsCount = config.plugins?.length || 0;
640
+ const successCount = pluginsCount - failedPlugins.size;
641
+ if (currentConfigs.length > 1) console.log(" ");
642
+ console.log(status === "success" ? `Kubb Summary: ${pc.blue("✓")} ${`${successCount} successful`}, ${pluginsCount} total` : `Kubb Summary: ${pc.blue("✓")} ${`${successCount} successful`}, ✗ ${`${failedPlugins.size} failed`}, ${pluginsCount} total`);
643
+ if (currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${pc.bold(config.name)}` : "Generation");
644
+ });
645
+ }
646
+ });
647
+
648
+ //#endregion
649
+ //#region src/loggers/plainLogger.ts
650
+ /**
651
+ * Plain console adapter for non-TTY environments
652
+ * Simple console.log output with indentation
653
+ */
654
+ const plainLogger = defineLogger({
655
+ name: "plain",
656
+ install(context, options) {
657
+ const logLevel = options?.logLevel || 3;
658
+ function getMessage(message) {
659
+ if (logLevel >= LogLevel.verbose) return [`[${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
660
+ hour12: false,
661
+ hour: "2-digit",
662
+ minute: "2-digit",
663
+ second: "2-digit"
664
+ })}]`, message].join(" ");
665
+ return message;
666
+ }
667
+ context.on("info", (message, info) => {
668
+ if (logLevel <= LogLevel.silent) return;
669
+ const text = getMessage([
670
+ "ℹ",
671
+ message,
672
+ info
673
+ ].join(" "));
674
+ console.log(text);
675
+ });
676
+ context.on("success", (message, info = "") => {
677
+ if (logLevel <= LogLevel.silent) return;
678
+ const text = getMessage([
679
+ "✓",
680
+ message,
681
+ logLevel >= LogLevel.info ? info : void 0
682
+ ].filter(Boolean).join(" "));
683
+ console.log(text);
684
+ });
685
+ context.on("warn", (message, info) => {
686
+ if (logLevel < LogLevel.warn) return;
687
+ const text = getMessage([
688
+ "⚠",
689
+ message,
690
+ logLevel >= LogLevel.info ? info : void 0
691
+ ].filter(Boolean).join(" "));
692
+ console.log(text);
693
+ });
694
+ context.on("error", (error) => {
695
+ const caused = error.cause;
696
+ const text = getMessage(["✗", error.message].join(" "));
697
+ console.log(text);
698
+ if (logLevel >= LogLevel.debug && error.stack) {
699
+ const frames = error.stack.split("\n").slice(1, 4);
700
+ for (const frame of frames) console.log(getMessage(frame.trim()));
701
+ if (caused?.stack) {
702
+ console.log(`└─ caused by ${caused.message}`);
703
+ const frames$1 = caused.stack.split("\n").slice(1, 4);
704
+ for (const frame of frames$1) console.log(getMessage(` ${frame.trim()}`));
705
+ }
706
+ }
707
+ });
708
+ context.on("lifecycle:start", () => {
709
+ console.log("Kubb CLI 🧩");
710
+ });
711
+ context.on("config:start", () => {
712
+ if (logLevel <= LogLevel.silent) return;
713
+ const text = getMessage("Configuration started");
714
+ console.log(text);
715
+ });
716
+ context.on("config:end", () => {
717
+ if (logLevel <= LogLevel.silent) return;
718
+ const text = getMessage("Configuration completed");
719
+ console.log(text);
720
+ });
721
+ context.on("generation:start", () => {
722
+ const text = getMessage("Configuration started");
723
+ console.log(text);
724
+ });
725
+ context.on("plugin:start", (plugin) => {
726
+ if (logLevel <= LogLevel.silent) return;
727
+ const text = getMessage(`Generating ${plugin.name}`);
728
+ console.log(text);
729
+ });
730
+ context.on("plugin:end", (plugin, duration) => {
731
+ if (logLevel <= LogLevel.silent) return;
732
+ const durationStr = duration >= 1e3 ? `${(duration / 1e3).toFixed(2)}s` : `${duration}ms`;
733
+ const text = getMessage(`${plugin.name} completed in ${durationStr}`);
734
+ console.log(text);
735
+ });
736
+ context.on("files:processing:start", (files) => {
737
+ if (logLevel <= LogLevel.silent) return;
738
+ const text = getMessage(`Writing ${files.length} files`);
739
+ console.log(text);
740
+ });
741
+ context.on("file:processing:update", ({ file, config }) => {
742
+ if (logLevel <= LogLevel.silent) return;
743
+ const text = getMessage(`Writing ${relative(config.root, file.path)}`);
744
+ console.log(text);
745
+ });
746
+ context.on("files:processing:end", () => {
747
+ if (logLevel <= LogLevel.silent) return;
748
+ const text = getMessage("Files written successfully");
749
+ console.log(text);
750
+ });
751
+ context.on("generation:end", (config) => {
752
+ const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
753
+ console.log(text);
754
+ });
755
+ context.on("hook:execute", async ({ command: command$1, args }, cb) => {
756
+ try {
757
+ const result = await execa(command$1, args, {
758
+ detached: true,
759
+ stripFinalNewline: true
760
+ });
761
+ await context.emit("debug", {
762
+ date: /* @__PURE__ */ new Date(),
763
+ logs: [result.stdout]
764
+ });
765
+ console.log(result.stdout);
766
+ cb();
767
+ } catch (err) {
768
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
769
+ error.cause = err;
770
+ await context.emit("debug", {
771
+ date: /* @__PURE__ */ new Date(),
772
+ logs: [err.stdout]
773
+ });
774
+ await context.emit("error", error);
775
+ }
776
+ });
777
+ context.on("format:start", () => {
778
+ if (logLevel <= LogLevel.silent) return;
779
+ const text = getMessage("Format started");
780
+ console.log(text);
781
+ });
782
+ context.on("format:end", () => {
783
+ if (logLevel <= LogLevel.silent) return;
784
+ const text = getMessage("Format completed");
785
+ console.log(text);
786
+ });
787
+ context.on("lint:start", () => {
788
+ if (logLevel <= LogLevel.silent) return;
789
+ const text = getMessage("Lint started");
790
+ console.log(text);
791
+ });
792
+ context.on("lint:end", () => {
793
+ if (logLevel <= LogLevel.silent) return;
794
+ const text = getMessage("Lint completed");
795
+ console.log(text);
796
+ });
797
+ context.on("hook:start", (command$1) => {
798
+ if (logLevel <= LogLevel.silent) return;
799
+ const text = getMessage(`Hook ${command$1} started`);
800
+ console.log(text);
801
+ });
802
+ context.on("hook:end", (command$1) => {
803
+ if (logLevel <= LogLevel.silent) return;
804
+ const text = getMessage(`Hook ${command$1} completed`);
805
+ console.log(text);
806
+ });
807
+ context.on("generation:summary", (config, { pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
808
+ const summary = getSummary({
809
+ failedPlugins,
810
+ filesCreated,
811
+ config,
812
+ status,
813
+ hrStart,
814
+ pluginTimings: logLevel >= LogLevel.verbose ? pluginTimings : void 0
815
+ });
816
+ console.log("---------------------------");
817
+ console.log(summary.join("\n"));
818
+ console.log("---------------------------");
819
+ });
820
+ }
821
+ });
822
+
823
+ //#endregion
824
+ //#region src/loggers/utils.ts
825
+ function detectLogger() {
826
+ if (isGitHubActions()) return "github-actions";
827
+ if (canUseTTY()) return "clack";
828
+ return "plain";
829
+ }
830
+ const logMapper = {
831
+ clack: clackLogger,
832
+ plain: plainLogger,
833
+ "github-actions": githubActionsLogger
834
+ };
835
+ async function setupLogger(context, { logLevel }) {
836
+ const type = detectLogger();
837
+ const logger = logMapper[type];
838
+ if (!logger) throw new Error(`Unknown adapter type: ${type}`);
839
+ const cleanup = await logger.install(context, { logLevel });
840
+ if (logLevel >= LogLevel.debug) await fileSystemLogger.install(context, { logLevel });
841
+ return cleanup;
842
+ }
843
+
844
+ //#endregion
845
+ //#region src/utils/executeHooks.ts
846
+ async function executeHooks({ hooks, events }) {
847
+ const commands = Array.isArray(hooks.done) ? hooks.done : [hooks.done].filter(Boolean);
848
+ for (const command$1 of commands) {
849
+ const [cmd, ...args] = [...parseArgsStringToArgv(command$1)];
850
+ if (!cmd) continue;
851
+ await events.emit("hook:start", command$1);
852
+ await events.emit("hook:execute", {
853
+ command: cmd,
854
+ args
855
+ }, async () => {
856
+ await events.emit("success", `${pc.dim(command$1)} successfully executed`);
857
+ await events.emit("hook:end", command$1);
858
+ });
859
+ }
860
+ }
861
+
862
+ //#endregion
863
+ //#region src/runners/generate.ts
864
+ async function generate({ input, config, events, logLevel }) {
865
+ const { root = process$1.cwd(), ...userConfig } = config;
866
+ const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0);
867
+ const hrStart = process$1.hrtime();
868
+ const definedConfig = {
869
+ root,
870
+ ...userConfig,
871
+ input: inputPath ? {
872
+ ...userConfig.input,
873
+ path: inputPath
874
+ } : userConfig.input,
875
+ output: {
876
+ write: true,
877
+ barrelType: "named",
878
+ extension: { ".ts": ".ts" },
879
+ format: "prettier",
880
+ ...userConfig.output
881
+ }
882
+ };
883
+ await events.emit("generation:start", definedConfig);
884
+ await events.emit("info", config.name ? `Setup generation ${pc.bold(config.name)}` : "Setup generation", inputPath);
885
+ const { fabric, pluginManager } = await setup({
886
+ config: definedConfig,
887
+ events
888
+ });
889
+ await events.emit("info", config.name ? `Build generation ${pc.bold(config.name)}` : "Build generation", inputPath);
890
+ const { files, failedPlugins, pluginTimings, error } = await safeBuild({
891
+ config: definedConfig,
892
+ events
893
+ }, {
894
+ pluginManager,
895
+ fabric,
896
+ events
897
+ });
898
+ await events.emit("info", "Load summary");
899
+ if (failedPlugins.size > 0 || error) {
900
+ [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean).forEach((err) => {
901
+ events.emit("error", err);
902
+ });
903
+ await events.emit("generation:end", definedConfig);
904
+ await events.emit("generation:summary", definedConfig, {
905
+ failedPlugins,
906
+ filesCreated: files.length,
907
+ status: failedPlugins.size > 0 || error ? "failed" : "success",
908
+ hrStart,
909
+ pluginTimings: logLevel >= LogLevel.verbose ? pluginTimings : void 0
910
+ });
911
+ process$1.exit(1);
912
+ }
913
+ await events.emit("success", "Generation successfully", inputPath);
914
+ await events.emit("generation:end", definedConfig);
915
+ if (config.output.format) {
916
+ await events.emit("format:start");
917
+ await events.emit("info", [`Formatting with ${pc.dim(config.output.format)}`, logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0].filter(Boolean).join(" "));
918
+ if (config.output.format === "prettier") {
919
+ try {
920
+ await events.emit("hook:execute", {
921
+ command: "prettier",
922
+ args: [
923
+ "--ignore-unknown",
924
+ "--write",
925
+ path.resolve(definedConfig.root, definedConfig.output.path)
926
+ ]
927
+ }, async () => {
928
+ await events.emit("success", [
929
+ `Formatting with ${pc.dim(config.output.format)}`,
930
+ logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
931
+ "successfully"
932
+ ].filter(Boolean).join(" "));
933
+ });
934
+ } catch (e) {
935
+ await events.emit("error", e);
936
+ }
937
+ await events.emit("success", `Formatted with ${config.output.format}`);
938
+ }
939
+ if (config.output.format === "biome") try {
940
+ await events.emit("hook:execute", {
941
+ command: "biome",
942
+ args: [
943
+ "format",
944
+ "--write",
945
+ path.resolve(definedConfig.root, definedConfig.output.path)
946
+ ]
947
+ }, async () => {
948
+ await events.emit("success", [
949
+ `Formatting with ${pc.dim(config.output.format)}`,
950
+ logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
951
+ "successfully"
952
+ ].filter(Boolean).join(" "));
953
+ });
954
+ } catch (e) {
955
+ const error$1 = /* @__PURE__ */ new Error("Biome not found");
956
+ error$1.cause = e;
957
+ await events.emit("error", error$1);
958
+ }
959
+ await events.emit("format:end");
960
+ }
961
+ if (config.output.lint) {
962
+ await events.emit("lint:start");
963
+ await events.emit("info", [`Linting with ${pc.dim(config.output.lint)}`, logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0].filter(Boolean).join(" "));
964
+ if (config.output.lint === "eslint") try {
965
+ await events.emit("hook:execute", {
966
+ command: "eslint",
967
+ args: [path.resolve(definedConfig.root, definedConfig.output.path), "--fix"]
968
+ }, async () => {
969
+ await events.emit("success", [
970
+ `Linted with ${pc.dim(config.output.lint)}`,
971
+ logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
972
+ "successfully"
973
+ ].filter(Boolean).join(" "));
974
+ });
975
+ } catch (e) {
976
+ const error$1 = /* @__PURE__ */ new Error("Eslint not found");
977
+ error$1.cause = e;
978
+ await events.emit("error", error$1);
979
+ }
980
+ if (config.output.lint === "biome") try {
981
+ await events.emit("hook:execute", {
982
+ command: "biome",
983
+ args: [
984
+ "lint",
985
+ "--fix",
986
+ path.resolve(definedConfig.root, definedConfig.output.path)
987
+ ]
988
+ }, async () => {
989
+ await events.emit("success", [
990
+ `Linted with ${pc.dim(config.output.lint)}`,
991
+ logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
992
+ "successfully"
993
+ ].filter(Boolean).join(" "));
994
+ });
995
+ } catch (e) {
996
+ const error$1 = /* @__PURE__ */ new Error("Biome not found");
997
+ error$1.cause = e;
998
+ await events.emit("error", error$1);
999
+ }
1000
+ if (config.output.lint === "oxlint") try {
1001
+ await events.emit("hook:execute", {
1002
+ command: "oxlint",
1003
+ args: ["--fix", path.resolve(definedConfig.root, definedConfig.output.path)]
1004
+ }, async () => {
1005
+ await events.emit("success", [
1006
+ `Linted with ${pc.dim(config.output.lint)}`,
1007
+ logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
1008
+ "successfully"
1009
+ ].filter(Boolean).join(" "));
1010
+ });
1011
+ } catch (e) {
1012
+ const error$1 = /* @__PURE__ */ new Error("Oxlint not found");
1013
+ error$1.cause = e;
1014
+ await events.emit("error", error$1);
1015
+ }
1016
+ await events.emit("lint:end");
1017
+ }
1018
+ if (config.hooks) {
1019
+ await events.emit("hooks:start");
1020
+ await executeHooks({
1021
+ hooks: config.hooks,
1022
+ events
1023
+ });
1024
+ await events.emit("hooks:end");
1025
+ }
1026
+ await events.emit("generation:summary", definedConfig, {
1027
+ failedPlugins,
1028
+ filesCreated: files.length,
1029
+ status: failedPlugins.size > 0 || error ? "failed" : "success",
1030
+ hrStart,
1031
+ pluginTimings
1032
+ });
1033
+ }
1034
+
1035
+ //#endregion
1036
+ //#region src/utils/getPlugins.ts
1037
+ function isJSONPlugins(plugins) {
1038
+ return !!plugins?.some((plugin) => {
1039
+ return Array.isArray(plugin) && typeof plugin?.at(0) === "string";
1040
+ });
1041
+ }
1042
+ function isObjectPlugins(plugins) {
1043
+ return plugins instanceof Object && !Array.isArray(plugins);
1044
+ }
1045
+ function getPlugins(plugins) {
1046
+ if (isObjectPlugins(plugins)) throw new Error("Object plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
1047
+ if (isJSONPlugins(plugins)) throw new Error("JSON plugins are not supported anymore, best to use http://kubb.dev/getting-started/configure#json");
1048
+ return Promise.resolve(plugins);
1049
+ }
1050
+
1051
+ //#endregion
1052
+ //#region src/utils/getConfig.ts
1053
+ /**
1054
+ * Converting UserConfig to Config without a change in the object beside the JSON convert.
1055
+ */
1056
+ async function getConfig(result, args) {
1057
+ const config = result?.config;
1058
+ let kubbUserConfig = Promise.resolve(config);
1059
+ if (typeof config === "function") {
1060
+ const possiblePromise = config(args);
1061
+ if (isPromise(possiblePromise)) kubbUserConfig = possiblePromise;
1062
+ kubbUserConfig = Promise.resolve(possiblePromise);
1063
+ }
1064
+ let JSONConfig = await kubbUserConfig;
1065
+ if (Array.isArray(JSONConfig)) {
1066
+ const results = [];
1067
+ for (const item of JSONConfig) {
1068
+ const plugins = item.plugins ? await getPlugins(item.plugins) : void 0;
1069
+ results.push({
1070
+ ...item,
1071
+ plugins
1072
+ });
1073
+ }
1074
+ return results;
1075
+ }
1076
+ JSONConfig = {
1077
+ ...JSONConfig,
1078
+ plugins: JSONConfig.plugins ? await getPlugins(JSONConfig.plugins) : void 0
1079
+ };
1080
+ return JSONConfig;
1081
+ }
1082
+
1083
+ //#endregion
1084
+ //#region src/utils/getCosmiConfig.ts
1085
+ const tsLoader = async (configFile) => {
1086
+ return await createJiti(import.meta.url, {
1087
+ jsx: {
1088
+ runtime: "automatic",
1089
+ importSource: "@kubb/react-fabric"
1090
+ },
1091
+ sourceMaps: true
1092
+ }).import(configFile, { default: true });
1093
+ };
1094
+ async function getCosmiConfig(moduleName, config) {
1095
+ let result;
1096
+ const searchPlaces = [
1097
+ "package.json",
1098
+ `.${moduleName}rc`,
1099
+ `.${moduleName}rc.json`,
1100
+ `.${moduleName}rc.yaml`,
1101
+ `.${moduleName}rc.yml`,
1102
+ `.${moduleName}rc.ts`,
1103
+ `.${moduleName}rc.js`,
1104
+ `.${moduleName}rc.mjs`,
1105
+ `.${moduleName}rc.cjs`,
1106
+ `${moduleName}.config.ts`,
1107
+ `${moduleName}.config.js`,
1108
+ `${moduleName}.config.mjs`,
1109
+ `${moduleName}.config.cjs`
1110
+ ];
1111
+ const explorer = cosmiconfig(moduleName, {
1112
+ cache: false,
1113
+ searchPlaces: [
1114
+ ...searchPlaces.map((searchPlace) => {
1115
+ return `.config/${searchPlace}`;
1116
+ }),
1117
+ ...searchPlaces.map((searchPlace) => {
1118
+ return `configs/${searchPlace}`;
1119
+ }),
1120
+ ...searchPlaces
1121
+ ],
1122
+ loaders: { ".ts": tsLoader }
1123
+ });
1124
+ try {
1125
+ result = config ? await explorer.load(config) : await explorer.search();
1126
+ } catch (e) {
1127
+ throw new Error("Config failed loading", { cause: e });
1128
+ }
1129
+ if (result?.isEmpty || !result || !result.config) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
1130
+ return result;
1131
+ }
1132
+
1133
+ //#endregion
1134
+ //#region src/utils/watcher.ts
1135
+ async function startWatcher(path$1, cb) {
1136
+ const { watch } = await import("chokidar");
1137
+ watch(path$1, {
1138
+ ignorePermissionErrors: true,
1139
+ ignored: "**/{.git,node_modules}/**"
1140
+ }).on("all", (type, file) => {
1141
+ console.log(pc.yellow(pc.bold(`Change detected: ${type} ${file}`)));
1142
+ try {
1143
+ cb(path$1);
1144
+ } catch (_e) {
1145
+ console.log(pc.red("Watcher failed"));
1146
+ }
1147
+ });
1148
+ }
1149
+
1150
+ //#endregion
1151
+ //#region src/commands/generate.ts
1152
+ const command = defineCommand({
1153
+ meta: {
1154
+ name: "generate",
1155
+ description: "[input] Generate files based on a 'kubb.config.ts' file"
1156
+ },
1157
+ args: {
1158
+ config: {
1159
+ type: "string",
1160
+ description: "Path to the Kubb config",
1161
+ alias: "c"
1162
+ },
1163
+ logLevel: {
1164
+ type: "string",
1165
+ description: "Info, silent, verbose or debug",
1166
+ alias: "l",
1167
+ default: "info",
1168
+ valueHint: "silent|info|verbose|debug"
1169
+ },
1170
+ watch: {
1171
+ type: "boolean",
1172
+ description: "Watch mode based on the input file",
1173
+ alias: "w",
1174
+ default: false
1175
+ },
1176
+ debug: {
1177
+ type: "boolean",
1178
+ description: "Override logLevel to debug",
1179
+ alias: "d",
1180
+ default: false
1181
+ },
1182
+ verbose: {
1183
+ type: "boolean",
1184
+ description: "Override logLevel to verbose",
1185
+ alias: "v",
1186
+ default: false
1187
+ },
1188
+ help: {
1189
+ type: "boolean",
1190
+ description: "Show help",
1191
+ alias: "h",
1192
+ default: false
1193
+ }
1194
+ },
1195
+ async run(commandContext) {
1196
+ const { args } = commandContext;
1197
+ const input = args._[0];
1198
+ const events = new AsyncEventEmitter();
1199
+ const promiseManager = new PromiseManager();
1200
+ if (args.help) return showUsage(command);
1201
+ if (args.debug) args.logLevel = "debug";
1202
+ if (args.verbose) args.logLevel = "verbose";
1203
+ const logLevel = LogLevel[args.logLevel] || 3;
1204
+ await setupLogger(events, { logLevel });
1205
+ const latestVersion = await getLatestVersion("@kubb/cli");
1206
+ if (lt(version, latestVersion)) await events.emit("version:new", version, latestVersion);
1207
+ try {
1208
+ await events.emit("lifecycle:start", version);
1209
+ await events.emit("config:start");
1210
+ const result = await getCosmiConfig("kubb", args.config);
1211
+ await events.emit("info", "Config loaded", path.relative(process$2.cwd(), result.filepath));
1212
+ const config = await getConfig(result, args);
1213
+ const configs = Array.isArray(config) ? config : [config];
1214
+ await events.emit("success", "Config loaded successfully", path.relative(process$2.cwd(), result.filepath));
1215
+ await events.emit("config:end", configs);
1216
+ const promises = configs.map((config$1) => {
1217
+ return async () => {
1218
+ if (isInputPath(config$1) && args.watch) {
1219
+ await startWatcher([input || config$1.input.path], async (paths) => {
1220
+ await generate({
1221
+ input,
1222
+ config: config$1,
1223
+ logLevel,
1224
+ events
1225
+ });
1226
+ clack.log.step(pc.yellow(`Watching for changes in ${paths.join(" and ")}`));
1227
+ });
1228
+ return;
1229
+ }
1230
+ await generate({
1231
+ input,
1232
+ config: config$1,
1233
+ logLevel,
1234
+ events
1235
+ });
1236
+ };
1237
+ });
1238
+ await promiseManager.run("seq", promises);
1239
+ await events.emit("lifecycle:end");
1240
+ } catch (e) {
1241
+ await events.emit("error", e);
1242
+ }
1243
+ }
1244
+ });
1245
+ var generate_default = command;
1246
+
1247
+ //#endregion
1248
+ export { generate_default as default };
1249
+ //# sourceMappingURL=generate-BfIvo80v.js.map