@kubb/cli 4.12.6 → 4.12.8

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 (35) hide show
  1. package/dist/{generate-DrdKyOOH.cjs → generate-BIq4hG_7.cjs} +350 -176
  2. package/dist/generate-BIq4hG_7.cjs.map +1 -0
  3. package/dist/{generate-M-5j2zqa.js → generate-DbvDQY54.js} +351 -177
  4. package/dist/generate-DbvDQY54.js.map +1 -0
  5. package/dist/index.cjs +3 -5
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +3 -5
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp-B5FWDVjp.js.map +1 -1
  10. package/dist/mcp-D7d_8Bma.cjs.map +1 -1
  11. package/dist/{package-4h1lfDoB.cjs → package-DIKLcg4Q.cjs} +2 -2
  12. package/dist/package-DIKLcg4Q.cjs.map +1 -0
  13. package/dist/package-sWmJhaYS.js +6 -0
  14. package/dist/package-sWmJhaYS.js.map +1 -0
  15. package/dist/validate-Bt922JN-.js.map +1 -1
  16. package/dist/validate-D9LPzg3-.cjs.map +1 -1
  17. package/package.json +4 -4
  18. package/src/commands/generate.ts +10 -0
  19. package/src/commands/mcp.ts +1 -3
  20. package/src/commands/validate.ts +1 -3
  21. package/src/index.ts +0 -9
  22. package/src/loggers/clackLogger.ts +152 -86
  23. package/src/loggers/fileSystemLogger.ts +81 -15
  24. package/src/loggers/githubActionsLogger.ts +137 -57
  25. package/src/loggers/plainLogger.ts +33 -36
  26. package/src/runners/generate.ts +56 -45
  27. package/src/utils/Writables.ts +0 -8
  28. package/src/utils/executeHooks.ts +7 -4
  29. package/src/utils/getSummary.ts +3 -3
  30. package/dist/generate-DrdKyOOH.cjs.map +0 -1
  31. package/dist/generate-M-5j2zqa.js.map +0 -1
  32. package/dist/package-4h1lfDoB.cjs.map +0 -1
  33. package/dist/package-B857a-xb.js +0 -6
  34. package/dist/package-B857a-xb.js.map +0 -1
  35. package/src/utils/parseHrtimeToSeconds.ts +0 -4
@@ -1,11 +1,11 @@
1
- import { t as version } from "./package-B857a-xb.js";
1
+ import { t as version } from "./package-sWmJhaYS.js";
2
2
  import { defineCommand, showUsage } from "citty";
3
3
  import path, { relative, resolve } from "node:path";
4
4
  import * as process$2 from "node:process";
5
5
  import process$1 from "node:process";
6
6
  import * as clack from "@clack/prompts";
7
7
  import { LogLevel, PromiseManager, defineLogger, isInputPath, safeBuild, setup } from "@kubb/core";
8
- import { AsyncEventEmitter, isPromise } from "@kubb/core/utils";
8
+ import { AsyncEventEmitter, formatHrtime, formatMs, isPromise } from "@kubb/core/utils";
9
9
  import getLatestVersion from "latest-version";
10
10
  import pc from "picocolors";
11
11
  import { lt } from "semver";
@@ -14,16 +14,11 @@ import gradientString from "gradient-string";
14
14
  import seedrandom from "seedrandom";
15
15
  import { Writable } from "node:stream";
16
16
  import { write } from "@kubb/core/fs";
17
+ import { createHash } from "node:crypto";
17
18
  import { parseArgsStringToArgv } from "string-argv";
18
19
  import { cosmiconfig } from "cosmiconfig";
19
20
  import { createJiti } from "jiti";
20
21
 
21
- //#region src/utils/parseHrtimeToSeconds.ts
22
- function parseHrtimeToSeconds(hrtime) {
23
- return (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
24
- }
25
-
26
- //#endregion
27
22
  //#region src/utils/randomColour.ts
28
23
  function randomColour(text) {
29
24
  if (!text) return "white";
@@ -51,14 +46,14 @@ function randomCliColour(text) {
51
46
  //#endregion
52
47
  //#region src/utils/getSummary.ts
53
48
  function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
54
- const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(hrStart));
49
+ const duration = formatHrtime(hrStart);
55
50
  const pluginsCount = config.plugins?.length || 0;
56
51
  const successCount = pluginsCount - failedPlugins.size;
57
52
  const meta = {
58
53
  plugins: status === "success" ? `${pc.green(`${successCount} successful`)}, ${pluginsCount} total` : `${pc.green(`${successCount} successful`)}, ${pc.red(`${failedPlugins.size} failed`)}, ${pluginsCount} total`,
59
54
  pluginsFailed: status === "failed" ? [...failedPlugins]?.map(({ plugin }) => randomCliColour(plugin.name))?.join(", ") : void 0,
60
55
  filesCreated,
61
- time: `${elapsedSeconds}s`,
56
+ time: pc.green(duration),
62
57
  output: path.isAbsolute(config.root) ? path.resolve(config.root, config.output.path) : config.root
63
58
  };
64
59
  const labels = {
@@ -115,9 +110,46 @@ const clackLogger = defineLogger({
115
110
  name: "clack",
116
111
  install(context, options) {
117
112
  const logLevel = options?.logLevel || LogLevel.info;
118
- const activeProgress = /* @__PURE__ */ new Map();
119
- const spinner = clack.spinner();
120
- let isSpinning = false;
113
+ const state = {
114
+ totalPlugins: 0,
115
+ completedPlugins: 0,
116
+ failedPlugins: 0,
117
+ totalFiles: 0,
118
+ processedFiles: 0,
119
+ hrStart: process$1.hrtime(),
120
+ spinner: clack.spinner(),
121
+ isSpinning: false,
122
+ activeProgress: /* @__PURE__ */ new Map()
123
+ };
124
+ function reset() {
125
+ for (const [_key, active] of state.activeProgress) {
126
+ if (active.interval) clearInterval(active.interval);
127
+ active.progressBar?.stop();
128
+ }
129
+ state.totalPlugins = 0;
130
+ state.completedPlugins = 0;
131
+ state.failedPlugins = 0;
132
+ state.totalFiles = 0;
133
+ state.processedFiles = 0;
134
+ state.hrStart = process$1.hrtime();
135
+ state.spinner = clack.spinner();
136
+ state.isSpinning = false;
137
+ state.activeProgress.clear();
138
+ }
139
+ function showProgressStep() {
140
+ if (logLevel <= LogLevel.silent) return;
141
+ const parts = [];
142
+ const duration = formatHrtime(state.hrStart);
143
+ if (state.totalPlugins > 0) {
144
+ const pluginStr = state.failedPlugins > 0 ? `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins} ${pc.red(`(${state.failedPlugins} failed)`)}` : `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins}`;
145
+ parts.push(pluginStr);
146
+ }
147
+ if (state.totalFiles > 0) parts.push(`Files ${pc.green(state.processedFiles.toString())}/${state.totalFiles}`);
148
+ if (parts.length > 0) {
149
+ parts.push(`${pc.green(duration)} elapsed`);
150
+ clack.log.step(getMessage(parts.join(pc.dim(" | "))));
151
+ }
152
+ }
121
153
  function getMessage(message) {
122
154
  if (logLevel >= LogLevel.verbose) {
123
155
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
@@ -131,12 +163,12 @@ const clackLogger = defineLogger({
131
163
  return message;
132
164
  }
133
165
  function startSpinner(text) {
134
- spinner.start(text);
135
- isSpinning = true;
166
+ state.spinner.start(text);
167
+ state.isSpinning = true;
136
168
  }
137
169
  function stopSpinner(text) {
138
- spinner.stop(text);
139
- isSpinning = false;
170
+ state.spinner.stop(text);
171
+ state.isSpinning = false;
140
172
  }
141
173
  context.on("info", (message, info = "") => {
142
174
  if (logLevel <= LogLevel.silent) return;
@@ -145,7 +177,7 @@ const clackLogger = defineLogger({
145
177
  message,
146
178
  pc.dim(info)
147
179
  ].join(" "));
148
- if (isSpinning) spinner.message(text);
180
+ if (state.isSpinning) state.spinner.message(text);
149
181
  else clack.log.info(text);
150
182
  });
151
183
  context.on("success", (message, info = "") => {
@@ -155,7 +187,7 @@ const clackLogger = defineLogger({
155
187
  message,
156
188
  logLevel >= LogLevel.info ? pc.dim(info) : void 0
157
189
  ].filter(Boolean).join(" "));
158
- if (isSpinning) stopSpinner(text);
190
+ if (state.isSpinning) stopSpinner(text);
159
191
  else clack.log.success(text);
160
192
  });
161
193
  context.on("warn", (message, info) => {
@@ -170,7 +202,7 @@ const clackLogger = defineLogger({
170
202
  context.on("error", (error) => {
171
203
  const caused = error.cause;
172
204
  const text = [pc.red("✗"), error.message].join(" ");
173
- if (isSpinning) stopSpinner(getMessage(text));
205
+ if (state.isSpinning) stopSpinner(getMessage(text));
174
206
  else clack.log.error(getMessage(text));
175
207
  if (logLevel >= LogLevel.debug && error.stack) {
176
208
  const frames = error.stack.split("\n").slice(1, 4);
@@ -200,6 +232,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
200
232
  "#F5A217",
201
233
  "#F55A17"
202
234
  ])(`Kubb ${version$1} 🧩`));
235
+ reset();
203
236
  });
204
237
  context.on("config:start", () => {
205
238
  if (logLevel <= LogLevel.silent) return;
@@ -207,14 +240,16 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
207
240
  clack.intro(text);
208
241
  startSpinner(getMessage("Configuration loading"));
209
242
  });
210
- context.on("config:end", () => {
243
+ context.on("config:end", (_configs) => {
211
244
  if (logLevel <= LogLevel.silent) return;
212
245
  const text = getMessage("Configuration completed");
213
246
  clack.outro(text);
214
247
  });
215
248
  context.on("generation:start", (config) => {
249
+ state.totalPlugins = config.plugins?.length || 0;
216
250
  const text = getMessage(["Generation started", config.name ? `for ${pc.dim(config.name)}` : void 0].filter(Boolean).join(" "));
217
251
  clack.intro(text);
252
+ reset();
218
253
  });
219
254
  context.on("plugin:start", (plugin) => {
220
255
  if (logLevel <= LogLevel.silent) return;
@@ -228,25 +263,30 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
228
263
  progressBar.start(text);
229
264
  const interval = setInterval(() => {
230
265
  progressBar.advance();
231
- }, 50);
232
- activeProgress.set(plugin.name, {
266
+ }, 100);
267
+ state.activeProgress.set(plugin.name, {
233
268
  progressBar,
234
269
  interval
235
270
  });
236
271
  });
237
- context.on("plugin:end", (plugin, duration) => {
272
+ context.on("plugin:end", (plugin, { duration, success }) => {
238
273
  stopSpinner();
239
- const active = activeProgress.get(plugin.name);
274
+ const active = state.activeProgress.get(plugin.name);
240
275
  if (!active || logLevel === LogLevel.silent) return;
241
276
  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)}`);
277
+ if (success) state.completedPlugins++;
278
+ else state.failedPlugins++;
279
+ const durationStr = formatMs(duration);
280
+ const text = getMessage(success ? `${pc.bold(plugin.name)} completed in ${pc.green(durationStr)}` : `${pc.bold(plugin.name)} failed in ${pc.red(durationStr)}`);
244
281
  active.progressBar.stop(text);
245
- activeProgress.delete(plugin.name);
282
+ state.activeProgress.delete(plugin.name);
283
+ showProgressStep();
246
284
  });
247
285
  context.on("files:processing:start", (files) => {
248
286
  if (logLevel <= LogLevel.silent) return;
249
287
  stopSpinner();
288
+ state.totalFiles = files.length;
289
+ state.processedFiles = 0;
250
290
  const text = `Writing ${files.length} files`;
251
291
  const progressBar = clack.progress({
252
292
  style: "block",
@@ -255,13 +295,14 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
255
295
  });
256
296
  context.emit("info", text);
257
297
  progressBar.start(getMessage(text));
258
- activeProgress.set("files", { progressBar });
298
+ state.activeProgress.set("files", { progressBar });
259
299
  });
260
300
  context.on("file:processing:update", ({ file, config }) => {
261
301
  if (logLevel <= LogLevel.silent) return;
262
302
  stopSpinner();
303
+ state.processedFiles++;
263
304
  const text = `Writing ${relative(config.root, file.path)}`;
264
- const active = activeProgress.get("files");
305
+ const active = state.activeProgress.get("files");
265
306
  if (!active) return;
266
307
  active.progressBar.advance(void 0, text);
267
308
  });
@@ -269,16 +310,38 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
269
310
  if (logLevel <= LogLevel.silent) return;
270
311
  stopSpinner();
271
312
  const text = getMessage("Files written successfully");
272
- const active = activeProgress.get("files");
313
+ const active = state.activeProgress.get("files");
273
314
  if (!active) return;
274
315
  active.progressBar.stop(text);
275
- activeProgress.delete("files");
316
+ state.activeProgress.delete("files");
317
+ showProgressStep();
276
318
  });
277
319
  context.on("generation:end", (config) => {
278
320
  const text = getMessage(config.name ? `Generation completed for ${pc.dim(config.name)}` : "Generation completed");
279
321
  clack.outro(text);
280
322
  });
281
- context.on("hook:execute", async ({ command: command$1, args }, cb) => {
323
+ context.on("format:start", () => {
324
+ if (logLevel <= LogLevel.silent) return;
325
+ const text = getMessage("Format started");
326
+ clack.intro(text);
327
+ });
328
+ context.on("format:end", () => {
329
+ if (logLevel <= LogLevel.silent) return;
330
+ const text = getMessage("Format completed");
331
+ clack.outro(text);
332
+ });
333
+ context.on("lint:start", () => {
334
+ if (logLevel <= LogLevel.silent) return;
335
+ const text = getMessage("Lint started");
336
+ clack.intro(text);
337
+ });
338
+ context.on("lint:end", () => {
339
+ if (logLevel <= LogLevel.silent) return;
340
+ const text = getMessage("Lint completed");
341
+ clack.outro(text);
342
+ });
343
+ context.on("hook:start", async ({ id, command: command$1, args }) => {
344
+ const text = getMessage(`Hook ${pc.dim(command$1)} started`);
282
345
  if (logLevel <= LogLevel.silent) {
283
346
  try {
284
347
  const result = await execa(command$1, args, {
@@ -289,7 +352,10 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
289
352
  date: /* @__PURE__ */ new Date(),
290
353
  logs: [result.stdout]
291
354
  });
292
- cb();
355
+ await context.emit("hook:end", {
356
+ command: command$1,
357
+ id
358
+ });
293
359
  } catch (err) {
294
360
  const error = /* @__PURE__ */ new Error("Hook execute failed");
295
361
  error.cause = err;
@@ -301,6 +367,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
301
367
  }
302
368
  return;
303
369
  }
370
+ clack.intro(text);
304
371
  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
372
  try {
306
373
  const result = await execa(command$1, args, {
@@ -312,7 +379,10 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
312
379
  date: /* @__PURE__ */ new Date(),
313
380
  logs: [result.stdout]
314
381
  });
315
- cb();
382
+ await context.emit("hook:end", {
383
+ command: command$1,
384
+ id
385
+ });
316
386
  } catch (err) {
317
387
  const error = /* @__PURE__ */ new Error("Hook execute failed");
318
388
  error.cause = err;
@@ -323,34 +393,9 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
323
393
  await context.emit("error", error);
324
394
  }
325
395
  });
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", () => {
396
+ context.on("hook:end", ({ command: command$1 }) => {
342
397
  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`);
398
+ const text = getMessage(`Hook ${pc.dim(command$1)} successfully executed`);
354
399
  clack.outro(text);
355
400
  });
356
401
  context.on("generation:summary", (config, { pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
@@ -386,11 +431,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
386
431
  });
387
432
  });
388
433
  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();
434
+ reset();
394
435
  });
395
436
  }
396
437
  });
@@ -428,36 +469,97 @@ function canUseTTY() {
428
469
  const fileSystemLogger = defineLogger({
429
470
  name: "filesystem",
430
471
  install(context) {
431
- const cachedLogs = /* @__PURE__ */ new Set();
432
- const startDate = Date.now();
433
- async function writeLogs() {
434
- if (cachedLogs.size === 0) return;
472
+ const state = {
473
+ cachedLogs: /* @__PURE__ */ new Set(),
474
+ startDate: Date.now()
475
+ };
476
+ function reset() {
477
+ state.cachedLogs = /* @__PURE__ */ new Set();
478
+ state.startDate = Date.now();
479
+ }
480
+ async function writeLogs(name) {
481
+ if (state.cachedLogs.size === 0) return;
435
482
  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] = [];
483
+ for (const log of state.cachedLogs) {
484
+ const baseName = log.fileName || `${[
485
+ "kubb",
486
+ name,
487
+ state.startDate
488
+ ].filter(Boolean).join("-")}.log`;
489
+ const pathName = resolve(process.cwd(), ".kubb", baseName);
490
+ if (!files[pathName]) files[pathName] = [];
439
491
  if (log.logs.length > 0) {
440
492
  const timestamp = log.date.toLocaleString();
441
- files[fileName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
493
+ files[pathName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
442
494
  }
443
495
  }
444
496
  await Promise.all(Object.entries(files).map(async ([fileName, logs]) => {
445
497
  return write(fileName, logs.join("\n\n"));
446
498
  }));
447
- cachedLogs.clear();
448
499
  }
500
+ context.on("info", (message, info) => {
501
+ state.cachedLogs.add({
502
+ date: /* @__PURE__ */ new Date(),
503
+ logs: [`ℹ ${message} ${info}`],
504
+ fileName: void 0
505
+ });
506
+ });
507
+ context.on("success", (message, info) => {
508
+ state.cachedLogs.add({
509
+ date: /* @__PURE__ */ new Date(),
510
+ logs: [`✓ ${message} ${info}`],
511
+ fileName: void 0
512
+ });
513
+ });
514
+ context.on("warn", (message, info) => {
515
+ state.cachedLogs.add({
516
+ date: /* @__PURE__ */ new Date(),
517
+ logs: [`⚠ ${message} ${info}`],
518
+ fileName: void 0
519
+ });
520
+ });
521
+ context.on("error", (error) => {
522
+ state.cachedLogs.add({
523
+ date: /* @__PURE__ */ new Date(),
524
+ logs: [`✗ ${error.message}`, error.stack || "unknown stack"],
525
+ fileName: void 0
526
+ });
527
+ });
449
528
  context.on("debug", (message) => {
450
- cachedLogs.add({
529
+ state.cachedLogs.add({
451
530
  date: /* @__PURE__ */ new Date(),
452
531
  logs: message.logs,
453
532
  fileName: void 0
454
533
  });
455
534
  });
456
- context.on("lifecycle:end", async () => {
457
- await writeLogs();
535
+ context.on("plugin:start", (plugin) => {
536
+ state.cachedLogs.add({
537
+ date: /* @__PURE__ */ new Date(),
538
+ logs: [`Generating ${plugin.name}`],
539
+ fileName: void 0
540
+ });
541
+ });
542
+ context.on("plugin:end", (plugin, { duration, success }) => {
543
+ const durationStr = formatMs(duration);
544
+ state.cachedLogs.add({
545
+ date: /* @__PURE__ */ new Date(),
546
+ logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`],
547
+ fileName: void 0
548
+ });
549
+ });
550
+ context.on("files:processing:start", (files) => {
551
+ state.cachedLogs.add({
552
+ date: /* @__PURE__ */ new Date(),
553
+ logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)],
554
+ fileName: void 0
555
+ });
556
+ });
557
+ context.on("generation:end", async (config) => {
558
+ await writeLogs(config.name);
559
+ reset();
458
560
  });
459
561
  const exitHandler = () => {
460
- if (cachedLogs.size > 0) writeLogs().catch(() => {});
562
+ if (state.cachedLogs.size > 0) writeLogs().catch(() => {});
461
563
  };
462
564
  process.once("exit", exitHandler);
463
565
  process.once("SIGINT", exitHandler);
@@ -475,7 +577,37 @@ const githubActionsLogger = defineLogger({
475
577
  name: "github-actions",
476
578
  install(context, options) {
477
579
  const logLevel = options?.logLevel || LogLevel.info;
478
- let currentConfigs = [];
580
+ const state = {
581
+ totalPlugins: 0,
582
+ completedPlugins: 0,
583
+ failedPlugins: 0,
584
+ totalFiles: 0,
585
+ processedFiles: 0,
586
+ hrStart: process.hrtime(),
587
+ currentConfigs: []
588
+ };
589
+ function reset() {
590
+ state.totalPlugins = 0;
591
+ state.completedPlugins = 0;
592
+ state.failedPlugins = 0;
593
+ state.totalFiles = 0;
594
+ state.processedFiles = 0;
595
+ state.hrStart = process.hrtime();
596
+ }
597
+ function showProgressStep() {
598
+ if (logLevel <= LogLevel.silent) return;
599
+ const parts = [];
600
+ const duration = formatHrtime(state.hrStart);
601
+ if (state.totalPlugins > 0) {
602
+ const pluginStr = state.failedPlugins > 0 ? `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins} ${pc.red(`(${state.failedPlugins} failed)`)}` : `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins}`;
603
+ parts.push(pluginStr);
604
+ }
605
+ if (state.totalFiles > 0) parts.push(`Files ${pc.green(state.processedFiles.toString())}/${state.totalFiles}`);
606
+ if (parts.length > 0) {
607
+ parts.push(`${pc.green(duration)} elapsed`);
608
+ console.log(getMessage(parts.join(pc.dim(" | "))));
609
+ }
610
+ }
479
611
  function getMessage(message) {
480
612
  if (logLevel >= LogLevel.verbose) {
481
613
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
@@ -528,6 +660,7 @@ const githubActionsLogger = defineLogger({
528
660
  });
529
661
  context.on("lifecycle:start", (version$1) => {
530
662
  console.log(pc.yellow(`Kubb ${version$1} 🧩`));
663
+ reset();
531
664
  });
532
665
  context.on("config:start", () => {
533
666
  if (logLevel <= LogLevel.silent) return;
@@ -536,34 +669,41 @@ const githubActionsLogger = defineLogger({
536
669
  console.log(text);
537
670
  });
538
671
  context.on("config:end", (configs) => {
539
- currentConfigs = configs;
672
+ state.currentConfigs = configs;
540
673
  if (logLevel <= LogLevel.silent) return;
541
674
  const text = getMessage("Configuration completed");
542
675
  console.log(text);
543
676
  closeGroup("Configuration");
544
677
  });
545
678
  context.on("generation:start", (config) => {
679
+ state.totalPlugins = config.plugins?.length || 0;
546
680
  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));
681
+ if (state.currentConfigs.length > 1) openGroup(text);
682
+ if (state.currentConfigs.length === 1) console.log(getMessage(text));
683
+ reset();
549
684
  });
550
685
  context.on("plugin:start", (plugin) => {
551
686
  if (logLevel <= LogLevel.silent) return;
552
687
  const text = getMessage(`Generating ${pc.bold(plugin.name)}`);
553
- if (currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
688
+ if (state.currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
554
689
  console.log(text);
555
690
  });
556
- context.on("plugin:end", (plugin, duration) => {
691
+ context.on("plugin:end", (plugin, { duration, success }) => {
557
692
  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)}`);
693
+ if (success) state.completedPlugins++;
694
+ else state.failedPlugins++;
695
+ const durationStr = formatMs(duration);
696
+ const text = getMessage(success ? `${pc.bold(plugin.name)} completed in ${pc.green(durationStr)}` : `${pc.bold(plugin.name)} failed in ${pc.red(durationStr)}`);
560
697
  console.log(text);
561
- if (currentConfigs.length > 1) console.log(" ");
562
- if (currentConfigs.length === 1) closeGroup(`Plugin: ${plugin.name}`);
698
+ if (state.currentConfigs.length > 1) console.log(" ");
699
+ if (state.currentConfigs.length === 1) closeGroup(`Plugin: ${plugin.name}`);
700
+ showProgressStep();
563
701
  });
564
702
  context.on("files:processing:start", (files) => {
565
703
  if (logLevel <= LogLevel.silent) return;
566
- if (currentConfigs.length === 1) openGroup("File Generation");
704
+ state.totalFiles = files.length;
705
+ state.processedFiles = 0;
706
+ if (state.currentConfigs.length === 1) openGroup("File Generation");
567
707
  const text = getMessage(`Writing ${files.length} files`);
568
708
  console.log(text);
569
709
  });
@@ -571,76 +711,87 @@ const githubActionsLogger = defineLogger({
571
711
  if (logLevel <= LogLevel.silent) return;
572
712
  const text = getMessage("Files written successfully");
573
713
  console.log(text);
574
- if (currentConfigs.length === 1) closeGroup("File Generation");
714
+ if (state.currentConfigs.length === 1) closeGroup("File Generation");
715
+ });
716
+ context.on("file:processing:update", () => {
717
+ if (logLevel <= LogLevel.silent) return;
718
+ state.processedFiles++;
719
+ });
720
+ context.on("files:processing:end", () => {
721
+ if (logLevel <= LogLevel.silent) return;
722
+ showProgressStep();
575
723
  });
576
724
  context.on("generation:end", (config) => {
577
725
  const text = getMessage(config.name ? `${pc.blue("✓")} Generation completed for ${pc.dim(config.name)}` : `${pc.blue("✓")} Generation completed`);
578
726
  console.log(text);
579
727
  });
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
728
  context.on("format:start", () => {
603
729
  if (logLevel <= LogLevel.silent) return;
604
730
  const text = getMessage("Format started");
605
- if (currentConfigs.length === 1) openGroup("Formatting");
731
+ if (state.currentConfigs.length === 1) openGroup("Formatting");
606
732
  console.log(text);
607
733
  });
608
734
  context.on("format:end", () => {
609
735
  if (logLevel <= LogLevel.silent) return;
610
736
  const text = getMessage("Format completed");
611
737
  console.log(text);
612
- if (currentConfigs.length === 1) closeGroup("Formatting");
738
+ if (state.currentConfigs.length === 1) closeGroup("Formatting");
613
739
  });
614
740
  context.on("lint:start", () => {
615
741
  if (logLevel <= LogLevel.silent) return;
616
742
  const text = getMessage("Lint started");
617
- if (currentConfigs.length === 1) openGroup("Linting");
743
+ if (state.currentConfigs.length === 1) openGroup("Linting");
618
744
  console.log(text);
619
745
  });
620
746
  context.on("lint:end", () => {
621
747
  if (logLevel <= LogLevel.silent) return;
622
748
  const text = getMessage("Lint completed");
623
749
  console.log(text);
624
- if (currentConfigs.length === 1) closeGroup("Linting");
750
+ if (state.currentConfigs.length === 1) closeGroup("Linting");
625
751
  });
626
- context.on("hook:start", (command$1) => {
627
- if (logLevel <= LogLevel.silent) return;
752
+ context.on("hook:start", async ({ id, command: command$1, args }) => {
628
753
  const text = getMessage(`Hook ${pc.dim(command$1)} started`);
629
- if (currentConfigs.length === 1) openGroup(`Hook ${command$1}`);
630
- console.log(text);
754
+ if (logLevel > LogLevel.silent) {
755
+ if (state.currentConfigs.length === 1) openGroup(`Hook ${command$1}`);
756
+ console.log(text);
757
+ }
758
+ try {
759
+ const result = await execa(command$1, args, {
760
+ detached: true,
761
+ stripFinalNewline: true
762
+ });
763
+ await context.emit("debug", {
764
+ date: /* @__PURE__ */ new Date(),
765
+ logs: [result.stdout]
766
+ });
767
+ console.log(result.stdout);
768
+ await context.emit("hook:end", {
769
+ command: command$1,
770
+ id
771
+ });
772
+ } catch (err) {
773
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
774
+ error.cause = err;
775
+ await context.emit("debug", {
776
+ date: /* @__PURE__ */ new Date(),
777
+ logs: [err.stdout]
778
+ });
779
+ await context.emit("error", error);
780
+ }
631
781
  });
632
- context.on("hook:end", (command$1) => {
782
+ context.on("hook:end", ({ command: command$1 }) => {
633
783
  if (logLevel <= LogLevel.silent) return;
634
784
  const text = getMessage(`Hook ${pc.dim(command$1)} completed`);
635
785
  console.log(text);
636
- if (currentConfigs.length === 1) closeGroup(`Hook ${command$1}`);
786
+ if (state.currentConfigs.length === 1) closeGroup(`Hook ${command$1}`);
637
787
  });
638
- context.on("generation:summary", (config, { status, failedPlugins }) => {
788
+ context.on("generation:summary", (config, { status, hrStart, failedPlugins }) => {
639
789
  const pluginsCount = config.plugins?.length || 0;
640
790
  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");
791
+ const duration = formatHrtime(hrStart);
792
+ if (state.currentConfigs.length > 1) console.log(" ");
793
+ console.log(status === "success" ? `Kubb Summary: ${pc.blue("✓")} ${`${successCount} successful`}, ${pluginsCount} total, ${pc.green(duration)}` : `Kubb Summary: ${pc.blue("")} ${`${successCount} successful`}, ✗ ${`${failedPlugins.size} failed`}, ${pluginsCount} total, ${pc.green(duration)}`);
794
+ if (state.currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${pc.bold(config.name)}` : "Generation");
644
795
  });
645
796
  }
646
797
  });
@@ -727,10 +878,10 @@ const plainLogger = defineLogger({
727
878
  const text = getMessage(`Generating ${plugin.name}`);
728
879
  console.log(text);
729
880
  });
730
- context.on("plugin:end", (plugin, duration) => {
881
+ context.on("plugin:end", (plugin, { duration, success }) => {
731
882
  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}`);
883
+ const durationStr = formatMs(duration);
884
+ const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`);
734
885
  console.log(text);
735
886
  });
736
887
  context.on("files:processing:start", (files) => {
@@ -752,28 +903,6 @@ const plainLogger = defineLogger({
752
903
  const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
753
904
  console.log(text);
754
905
  });
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
906
  context.on("format:start", () => {
778
907
  if (logLevel <= LogLevel.silent) return;
779
908
  const text = getMessage("Format started");
@@ -794,10 +923,32 @@ const plainLogger = defineLogger({
794
923
  const text = getMessage("Lint completed");
795
924
  console.log(text);
796
925
  });
797
- context.on("hook:start", (command$1) => {
798
- if (logLevel <= LogLevel.silent) return;
926
+ context.on("hook:start", async ({ id, command: command$1, args }) => {
799
927
  const text = getMessage(`Hook ${command$1} started`);
800
- console.log(text);
928
+ if (logLevel > LogLevel.silent) console.log(text);
929
+ try {
930
+ const result = await execa(command$1, args, {
931
+ detached: true,
932
+ stripFinalNewline: true
933
+ });
934
+ await context.emit("debug", {
935
+ date: /* @__PURE__ */ new Date(),
936
+ logs: [result.stdout]
937
+ });
938
+ console.log(result.stdout);
939
+ await context.emit("hook:end", {
940
+ command: command$1,
941
+ id
942
+ });
943
+ } catch (err) {
944
+ const error = /* @__PURE__ */ new Error("Hook execute failed");
945
+ error.cause = err;
946
+ await context.emit("debug", {
947
+ date: /* @__PURE__ */ new Date(),
948
+ logs: [err.stdout]
949
+ });
950
+ await context.emit("error", error);
951
+ }
801
952
  });
802
953
  context.on("hook:end", (command$1) => {
803
954
  if (logLevel <= LogLevel.silent) return;
@@ -848,13 +999,14 @@ async function executeHooks({ hooks, events }) {
848
999
  for (const command$1 of commands) {
849
1000
  const [cmd, ...args] = [...parseArgsStringToArgv(command$1)];
850
1001
  if (!cmd) continue;
851
- await events.emit("hook:start", command$1);
852
- await events.emit("hook:execute", {
1002
+ const hookId = createHash("sha256").update(command$1).digest("hex");
1003
+ await events.emit("hook:start", {
1004
+ id: hookId,
853
1005
  command: cmd,
854
1006
  args
855
- }, async () => {
856
- await events.emit("success", `${pc.dim(command$1)} successfully executed`);
857
- await events.emit("hook:end", command$1);
1007
+ });
1008
+ await events.on("hook:end", async ({ id }) => {
1009
+ if (id === hookId) await events.emit("success", `${pc.dim(command$1)} successfully executed`);
858
1010
  });
859
1011
  }
860
1012
  }
@@ -917,15 +1069,18 @@ async function generate({ input, config, events, logLevel }) {
917
1069
  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
1070
  if (config.output.format === "prettier") {
919
1071
  try {
920
- await events.emit("hook:execute", {
1072
+ const hookId = createHash("sha256").update(config.output.format).digest("hex");
1073
+ await events.emit("hook:start", {
1074
+ id: hookId,
921
1075
  command: "prettier",
922
1076
  args: [
923
1077
  "--ignore-unknown",
924
1078
  "--write",
925
1079
  path.resolve(definedConfig.root, definedConfig.output.path)
926
1080
  ]
927
- }, async () => {
928
- await events.emit("success", [
1081
+ });
1082
+ await events.on("hook:end", async ({ id }) => {
1083
+ if (id === hookId) await events.emit("success", [
929
1084
  `Formatting with ${pc.dim(config.output.format)}`,
930
1085
  logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
931
1086
  "successfully"
@@ -937,15 +1092,18 @@ async function generate({ input, config, events, logLevel }) {
937
1092
  await events.emit("success", `Formatted with ${config.output.format}`);
938
1093
  }
939
1094
  if (config.output.format === "biome") try {
940
- await events.emit("hook:execute", {
1095
+ const hookId = createHash("sha256").update(config.output.format).digest("hex");
1096
+ await events.emit("hook:start", {
1097
+ id: hookId,
941
1098
  command: "biome",
942
1099
  args: [
943
1100
  "format",
944
1101
  "--write",
945
1102
  path.resolve(definedConfig.root, definedConfig.output.path)
946
1103
  ]
947
- }, async () => {
948
- await events.emit("success", [
1104
+ });
1105
+ await events.on("hook:end", async ({ id }) => {
1106
+ if (id === hookId) await events.emit("success", [
949
1107
  `Formatting with ${pc.dim(config.output.format)}`,
950
1108
  logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
951
1109
  "successfully"
@@ -962,11 +1120,14 @@ async function generate({ input, config, events, logLevel }) {
962
1120
  await events.emit("lint:start");
963
1121
  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
1122
  if (config.output.lint === "eslint") try {
965
- await events.emit("hook:execute", {
1123
+ const hookId = createHash("sha256").update(config.output.lint).digest("hex");
1124
+ await events.emit("hook:start", {
1125
+ id: hookId,
966
1126
  command: "eslint",
967
1127
  args: [path.resolve(definedConfig.root, definedConfig.output.path), "--fix"]
968
- }, async () => {
969
- await events.emit("success", [
1128
+ });
1129
+ await events.on("hook:end", async ({ id }) => {
1130
+ if (id === hookId) await events.emit("success", [
970
1131
  `Linted with ${pc.dim(config.output.lint)}`,
971
1132
  logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
972
1133
  "successfully"
@@ -978,15 +1139,18 @@ async function generate({ input, config, events, logLevel }) {
978
1139
  await events.emit("error", error$1);
979
1140
  }
980
1141
  if (config.output.lint === "biome") try {
981
- await events.emit("hook:execute", {
1142
+ const hookId = createHash("sha256").update(config.output.lint).digest("hex");
1143
+ await events.emit("hook:start", {
1144
+ id: hookId,
982
1145
  command: "biome",
983
1146
  args: [
984
1147
  "lint",
985
1148
  "--fix",
986
1149
  path.resolve(definedConfig.root, definedConfig.output.path)
987
1150
  ]
988
- }, async () => {
989
- await events.emit("success", [
1151
+ });
1152
+ await events.on("hook:end", async ({ id }) => {
1153
+ if (id === hookId) await events.emit("success", [
990
1154
  `Linted with ${pc.dim(config.output.lint)}`,
991
1155
  logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
992
1156
  "successfully"
@@ -998,11 +1162,14 @@ async function generate({ input, config, events, logLevel }) {
998
1162
  await events.emit("error", error$1);
999
1163
  }
1000
1164
  if (config.output.lint === "oxlint") try {
1001
- await events.emit("hook:execute", {
1165
+ const hookId = createHash("sha256").update(config.output.lint).digest("hex");
1166
+ await events.emit("hook:start", {
1167
+ id: hookId,
1002
1168
  command: "oxlint",
1003
1169
  args: ["--fix", path.resolve(definedConfig.root, definedConfig.output.path)]
1004
- }, async () => {
1005
- await events.emit("success", [
1170
+ });
1171
+ await events.on("hook:end", async ({ id }) => {
1172
+ if (id === hookId) await events.emit("success", [
1006
1173
  `Linted with ${pc.dim(config.output.lint)}`,
1007
1174
  logLevel >= LogLevel.info ? `on ${pc.dim(path.resolve(definedConfig.root, definedConfig.output.path))}` : void 0,
1008
1175
  "successfully"
@@ -1185,6 +1352,12 @@ const command = defineCommand({
1185
1352
  alias: "v",
1186
1353
  default: false
1187
1354
  },
1355
+ silent: {
1356
+ type: "boolean",
1357
+ description: "Override logLevel to silent",
1358
+ alias: "s",
1359
+ default: false
1360
+ },
1188
1361
  help: {
1189
1362
  type: "boolean",
1190
1363
  description: "Show help",
@@ -1200,6 +1373,7 @@ const command = defineCommand({
1200
1373
  if (args.help) return showUsage(command);
1201
1374
  if (args.debug) args.logLevel = "debug";
1202
1375
  if (args.verbose) args.logLevel = "verbose";
1376
+ if (args.silent) args.logLevel = "silent";
1203
1377
  const logLevel = LogLevel[args.logLevel] || 3;
1204
1378
  await setupLogger(events, { logLevel });
1205
1379
  const latestVersion = await getLatestVersion("@kubb/cli");
@@ -1246,4 +1420,4 @@ var generate_default = command;
1246
1420
 
1247
1421
  //#endregion
1248
1422
  export { generate_default as default };
1249
- //# sourceMappingURL=generate-M-5j2zqa.js.map
1423
+ //# sourceMappingURL=generate-DbvDQY54.js.map