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