@kubb/cli 5.0.0-beta.3 → 5.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -26
- package/dist/agent-BAAO2W7u.cjs +70 -0
- package/dist/agent-BAAO2W7u.cjs.map +1 -0
- package/dist/agent-WLRLgsEM.js +68 -0
- package/dist/agent-WLRLgsEM.js.map +1 -0
- package/dist/{chunk--u3MIqq1.js → chunk-BvFE5Tac.js} +1 -0
- package/dist/constants-B2JTeRBb.js +42 -0
- package/dist/constants-B2JTeRBb.js.map +1 -0
- package/dist/constants-BINTA5VZ.cjs +77 -0
- package/dist/constants-BINTA5VZ.cjs.map +1 -0
- package/dist/constants-BYGmiFs0.cjs +139 -0
- package/dist/constants-BYGmiFs0.cjs.map +1 -0
- package/dist/constants-DSJ-Xrbv.js +116 -0
- package/dist/constants-DSJ-Xrbv.js.map +1 -0
- package/dist/define-Bdn8j5VM.cjs.map +1 -1
- package/dist/{define-Ctii4bel.js → define-m_fp-Aqm.js} +2 -2
- package/dist/{define-Ctii4bel.js.map → define-m_fp-Aqm.js.map} +1 -1
- package/dist/{errors-CjPmyZHy.js → errors-CINO1EIv.js} +2 -2
- package/dist/{errors-CjPmyZHy.js.map → errors-CINO1EIv.js.map} +1 -1
- package/dist/errors-CLCjoSg0.cjs.map +1 -1
- package/dist/{generate-CTdVvIaP.js → generate-C4iw5Nou.js} +12 -6
- package/dist/generate-C4iw5Nou.js.map +1 -0
- package/dist/{generate-BzCMyyNN.cjs → generate-DKtBY8eR.cjs} +10 -4
- package/dist/generate-DKtBY8eR.cjs.map +1 -0
- package/dist/index.cjs +20 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -13
- package/dist/index.js.map +1 -1
- package/dist/init-DE_judaK.js +53 -0
- package/dist/init-DE_judaK.js.map +1 -0
- package/dist/init-berpsF2G.cjs +53 -0
- package/dist/init-berpsF2G.cjs.map +1 -0
- package/dist/mcp-Ce6errt_.js +39 -0
- package/dist/mcp-Ce6errt_.js.map +1 -0
- package/dist/mcp-DcohdQTl.cjs +39 -0
- package/dist/mcp-DcohdQTl.cjs.map +1 -0
- package/dist/package-C0vNpFXU.js +6 -0
- package/dist/package-C0vNpFXU.js.map +1 -0
- package/dist/{package-DcmDg_mw.cjs → package-DZDnoPgZ.cjs} +2 -2
- package/dist/package-DZDnoPgZ.cjs.map +1 -0
- package/dist/run-B11-UaUs.cjs +33 -0
- package/dist/run-B11-UaUs.cjs.map +1 -0
- package/dist/{init-eNRlotJK.js → run-BNqMQygv.js} +107 -149
- package/dist/run-BNqMQygv.js.map +1 -0
- package/dist/{generate-BL-Kp5GY.js → run-BgM41TQT.js} +561 -493
- package/dist/run-BgM41TQT.js.map +1 -0
- package/dist/{init-CZ5Xq2Hd.cjs → run-BnGfi7Cp.cjs} +105 -147
- package/dist/run-BnGfi7Cp.cjs.map +1 -0
- package/dist/{agent-sdYBBgrd.js → run-BzpYYOQs.js} +46 -43
- package/dist/run-BzpYYOQs.js.map +1 -0
- package/dist/run-CCZ24VKk.js +51 -0
- package/dist/run-CCZ24VKk.js.map +1 -0
- package/dist/run-CQbj3ley.cjs +52 -0
- package/dist/run-CQbj3ley.cjs.map +1 -0
- package/dist/{generate-DMqdAYqy.cjs → run-DeWgpA6S.cjs} +558 -490
- package/dist/run-DeWgpA6S.cjs.map +1 -0
- package/dist/{agent-B4cAAab2.cjs → run-DwdAwnLG.cjs} +44 -41
- package/dist/run-DwdAwnLG.cjs.map +1 -0
- package/dist/run-PSA9X7ci.js +32 -0
- package/dist/run-PSA9X7ci.js.map +1 -0
- package/dist/shell-475fQKaX.cjs.map +1 -1
- package/dist/{shell-DLzN4fRo.js → shell-CN6DNqeC.js} +2 -2
- package/dist/{shell-DLzN4fRo.js.map → shell-CN6DNqeC.js.map} +1 -1
- package/dist/{telemetry-DN95_2pF.cjs → telemetry-B2iWkY5e.cjs} +5 -7
- package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
- package/dist/{telemetry-LgT_sdPe.js → telemetry-BkektVz6.js} +6 -8
- package/dist/telemetry-BkektVz6.js.map +1 -0
- package/dist/validate-DVeCYyIS.js +26 -0
- package/dist/validate-DVeCYyIS.js.map +1 -0
- package/dist/validate-ymG_XDSU.cjs +26 -0
- package/dist/validate-ymG_XDSU.cjs.map +1 -0
- package/package.json +14 -14
- package/src/commands/agent/start.ts +10 -7
- package/src/commands/agent.ts +3 -1
- package/src/commands/generate.ts +5 -3
- package/src/commands/init.ts +34 -3
- package/src/commands/mcp.ts +28 -4
- package/src/commands/validate.ts +6 -4
- package/src/constants.ts +2 -58
- package/src/index.ts +5 -3
- package/src/loggers/clackLogger.ts +85 -118
- package/src/loggers/fileSystemLogger.ts +28 -15
- package/src/loggers/githubActionsLogger.ts +87 -96
- package/src/loggers/plainLogger.ts +48 -81
- package/src/loggers/types.ts +6 -0
- package/src/loggers/utils.ts +235 -11
- package/src/runners/agent/run.ts +113 -0
- package/src/runners/agent/utils.ts +98 -0
- package/src/runners/generate/run.ts +321 -0
- package/src/runners/generate/utils.ts +225 -0
- package/src/runners/init/run.ts +212 -0
- package/src/{utils/packageManager.ts → runners/init/utils.ts} +12 -2
- package/src/runners/mcp/run.ts +37 -0
- package/src/runners/validate/run.ts +63 -0
- package/src/{utils/telemetry.ts → telemetry.ts} +27 -20
- package/dist/agent-B4cAAab2.cjs.map +0 -1
- package/dist/agent-BFACosbG.cjs +0 -58
- package/dist/agent-BFACosbG.cjs.map +0 -1
- package/dist/agent-s7TqqoTg.js +0 -56
- package/dist/agent-s7TqqoTg.js.map +0 -1
- package/dist/agent-sdYBBgrd.js.map +0 -1
- package/dist/constants-CnDXa1R6.cjs +0 -148
- package/dist/constants-CnDXa1R6.cjs.map +0 -1
- package/dist/constants-aL3CP_Wq.js +0 -95
- package/dist/constants-aL3CP_Wq.js.map +0 -1
- package/dist/generate-BL-Kp5GY.js.map +0 -1
- package/dist/generate-BzCMyyNN.cjs.map +0 -1
- package/dist/generate-CTdVvIaP.js.map +0 -1
- package/dist/generate-DMqdAYqy.cjs.map +0 -1
- package/dist/init-BHMGbly9.cjs +0 -25
- package/dist/init-BHMGbly9.cjs.map +0 -1
- package/dist/init-CZ5Xq2Hd.cjs.map +0 -1
- package/dist/init-eNRlotJK.js.map +0 -1
- package/dist/init-qgpg-iRW.js +0 -25
- package/dist/init-qgpg-iRW.js.map +0 -1
- package/dist/mcp-BRp-2Rdc.js +0 -16
- package/dist/mcp-BRp-2Rdc.js.map +0 -1
- package/dist/mcp-CYOgxB82.cjs +0 -47
- package/dist/mcp-CYOgxB82.cjs.map +0 -1
- package/dist/mcp-DmJm3TrU.js +0 -46
- package/dist/mcp-DmJm3TrU.js.map +0 -1
- package/dist/mcp-N3mRyVuO.cjs +0 -16
- package/dist/mcp-N3mRyVuO.cjs.map +0 -1
- package/dist/package-DcmDg_mw.cjs.map +0 -1
- package/dist/package-DtuyzAVW.js +0 -6
- package/dist/package-DtuyzAVW.js.map +0 -1
- package/dist/telemetry-DN95_2pF.cjs.map +0 -1
- package/dist/telemetry-LgT_sdPe.js.map +0 -1
- package/dist/validate-CJpTOzKA.js +0 -25
- package/dist/validate-CJpTOzKA.js.map +0 -1
- package/dist/validate-DyTbv7Bc.cjs +0 -25
- package/dist/validate-DyTbv7Bc.cjs.map +0 -1
- package/dist/validate-kLJoT_hi.js +0 -33
- package/dist/validate-kLJoT_hi.js.map +0 -1
- package/dist/validate-yKKzqEZ5.cjs +0 -34
- package/dist/validate-yKKzqEZ5.cjs.map +0 -1
- package/src/runners/agent.ts +0 -155
- package/src/runners/generate.ts +0 -333
- package/src/runners/init.ts +0 -296
- package/src/runners/mcp.ts +0 -51
- package/src/runners/validate.ts +0 -39
- package/src/types.ts +0 -11
- package/src/utils/Writables.ts +0 -17
- package/src/utils/executeHooks.ts +0 -45
- package/src/utils/flags.ts +0 -9
- package/src/utils/getConfig.ts +0 -10
- package/src/utils/getCosmiConfig.ts +0 -80
- package/src/utils/getSummary.ts +0 -68
- package/src/utils/runHook.ts +0 -91
- package/src/utils/watcher.ts +0 -19
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./chunk
|
|
2
|
-
import { n as toCause, r as toError } from "./errors-
|
|
3
|
-
import { a as canUseTTY, i as executeIfOnline, o as isGitHubActions, r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-
|
|
4
|
-
import { n as tokenize } from "./shell-
|
|
5
|
-
import { t as version } from "./package-
|
|
6
|
-
import { a as
|
|
1
|
+
import "./chunk-BvFE5Tac.js";
|
|
2
|
+
import { n as toCause, r as toError } from "./errors-CINO1EIv.js";
|
|
3
|
+
import { a as canUseTTY, i as executeIfOnline, o as isGitHubActions, r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-BkektVz6.js";
|
|
4
|
+
import { n as tokenize } from "./shell-CN6DNqeC.js";
|
|
5
|
+
import { t as version } from "./package-C0vNpFXU.js";
|
|
6
|
+
import { a as WATCHER_IGNORED_PATHS, i as SUMMARY_SEPARATOR, t as KUBB_NPM_PACKAGE_URL } from "./constants-B2JTeRBb.js";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import { EventEmitter } from "node:events";
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
@@ -14,10 +14,9 @@ import path, { dirname, relative, resolve } from "node:path";
|
|
|
14
14
|
import process$1 from "node:process";
|
|
15
15
|
import * as clack from "@clack/prompts";
|
|
16
16
|
import { createKubb, defineLogger, isInputPath, logLevel } from "@kubb/core";
|
|
17
|
-
import { NonZeroExitError, x } from "tinyexec";
|
|
18
|
-
import { Writable } from "node:stream";
|
|
19
17
|
import { cosmiconfig } from "cosmiconfig";
|
|
20
|
-
import {
|
|
18
|
+
import { createJiti } from "jiti";
|
|
19
|
+
import { NonZeroExitError, x } from "tinyexec";
|
|
21
20
|
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
22
21
|
/**
|
|
23
22
|
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
@@ -48,9 +47,12 @@ var AsyncEventEmitter = class {
|
|
|
48
47
|
* await emitter.emit('build', 'petstore')
|
|
49
48
|
* ```
|
|
50
49
|
*/
|
|
51
|
-
|
|
50
|
+
emit(eventName, ...eventArgs) {
|
|
52
51
|
const listeners = this.#emitter.listeners(eventName);
|
|
53
52
|
if (listeners.length === 0) return;
|
|
53
|
+
return this.#emitAll(eventName, listeners, eventArgs);
|
|
54
|
+
}
|
|
55
|
+
async #emitAll(eventName, listeners, eventArgs) {
|
|
54
56
|
for (const listener of listeners) try {
|
|
55
57
|
await listener(...eventArgs);
|
|
56
58
|
} catch (err) {
|
|
@@ -486,112 +488,6 @@ async function detectLinter() {
|
|
|
486
488
|
return null;
|
|
487
489
|
}
|
|
488
490
|
//#endregion
|
|
489
|
-
//#region src/utils/getSummary.ts
|
|
490
|
-
function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
|
|
491
|
-
const duration = formatHrtime(hrStart);
|
|
492
|
-
const pluginsCount = config.plugins?.length ?? 0;
|
|
493
|
-
const successCount = pluginsCount - failedPlugins.size;
|
|
494
|
-
const meta = {
|
|
495
|
-
plugins: status === "success" ? `${styleText("green", `${successCount} successful`)}, ${pluginsCount} total` : `${styleText("green", `${successCount} successful`)}, ${styleText("red", `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
|
|
496
|
-
pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
|
|
497
|
-
filesCreated,
|
|
498
|
-
time: styleText("green", duration),
|
|
499
|
-
output: path.resolve(config.root, config.output.path)
|
|
500
|
-
};
|
|
501
|
-
const labels = {
|
|
502
|
-
plugins: "Plugins:",
|
|
503
|
-
failed: "Failed:",
|
|
504
|
-
generated: "Generated:",
|
|
505
|
-
pluginTimings: "Plugin Timings:",
|
|
506
|
-
output: "Output:"
|
|
507
|
-
};
|
|
508
|
-
const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
|
|
509
|
-
const summaryLines = [];
|
|
510
|
-
summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
|
|
511
|
-
if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
|
|
512
|
-
summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
|
|
513
|
-
if (pluginTimings && pluginTimings.size > 0) {
|
|
514
|
-
const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
|
|
515
|
-
summaryLines.push(`${labels.pluginTimings}`);
|
|
516
|
-
sortedTimings.forEach(([name, time]) => {
|
|
517
|
-
const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
|
|
518
|
-
const barLength = Math.min(Math.ceil(time / 100), 10);
|
|
519
|
-
const bar = styleText("dim", "█".repeat(barLength));
|
|
520
|
-
summaryLines.push(`${styleText("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
|
|
524
|
-
return summaryLines;
|
|
525
|
-
}
|
|
526
|
-
//#endregion
|
|
527
|
-
//#region src/utils/runHook.ts
|
|
528
|
-
/**
|
|
529
|
-
* Executes a hook command, emits debug and completion events, and forwards output to an optional sink.
|
|
530
|
-
*/
|
|
531
|
-
async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
|
|
532
|
-
try {
|
|
533
|
-
const proc = x(command, [...args ?? []], {
|
|
534
|
-
nodeOptions: { detached: process.platform !== "win32" },
|
|
535
|
-
throwOnError: true
|
|
536
|
-
});
|
|
537
|
-
if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
|
|
538
|
-
const result = await proc;
|
|
539
|
-
await context.emit("kubb:debug", {
|
|
540
|
-
date: /* @__PURE__ */ new Date(),
|
|
541
|
-
logs: [result.stdout.trimEnd()]
|
|
542
|
-
});
|
|
543
|
-
await context.emit("kubb:hook:end", {
|
|
544
|
-
command,
|
|
545
|
-
args,
|
|
546
|
-
id,
|
|
547
|
-
success: true,
|
|
548
|
-
error: null
|
|
549
|
-
});
|
|
550
|
-
} catch (err) {
|
|
551
|
-
if (!(err instanceof NonZeroExitError)) {
|
|
552
|
-
await context.emit("kubb:hook:end", {
|
|
553
|
-
command,
|
|
554
|
-
args,
|
|
555
|
-
id,
|
|
556
|
-
success: false,
|
|
557
|
-
error: toError(err)
|
|
558
|
-
});
|
|
559
|
-
await context.emit("kubb:error", { error: toError(err) });
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
const stderr = err.output?.stderr ?? "";
|
|
563
|
-
const stdout = err.output?.stdout ?? "";
|
|
564
|
-
await context.emit("kubb:debug", {
|
|
565
|
-
date: /* @__PURE__ */ new Date(),
|
|
566
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
567
|
-
});
|
|
568
|
-
if (stderr) sink?.onStderr?.(stderr);
|
|
569
|
-
if (stdout) sink?.onStdout?.(stdout);
|
|
570
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
571
|
-
await context.emit("kubb:hook:end", {
|
|
572
|
-
command,
|
|
573
|
-
args,
|
|
574
|
-
id,
|
|
575
|
-
success: false,
|
|
576
|
-
error: errorMessage
|
|
577
|
-
});
|
|
578
|
-
await context.emit("kubb:error", { error: errorMessage });
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
//#endregion
|
|
582
|
-
//#region src/utils/Writables.ts
|
|
583
|
-
var ClackWritable = class extends Writable {
|
|
584
|
-
taskLog;
|
|
585
|
-
constructor(taskLog, opts) {
|
|
586
|
-
super(opts);
|
|
587
|
-
this.taskLog = taskLog;
|
|
588
|
-
}
|
|
589
|
-
_write(chunk, _encoding, callback) {
|
|
590
|
-
this.taskLog.message(`${styleText("dim", chunk.toString())}`);
|
|
591
|
-
callback();
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
//#endregion
|
|
595
491
|
//#region src/loggers/clackLogger.ts
|
|
596
492
|
/**
|
|
597
493
|
* TTY logger with beautiful UI and progress indicators for local development.
|
|
@@ -601,30 +497,22 @@ const clackLogger = defineLogger({
|
|
|
601
497
|
install(context, options) {
|
|
602
498
|
const logLevel$8 = options?.logLevel ?? logLevel.info;
|
|
603
499
|
const state = {
|
|
604
|
-
|
|
605
|
-
completedPlugins: 0,
|
|
606
|
-
failedPlugins: 0,
|
|
607
|
-
totalFiles: 0,
|
|
608
|
-
processedFiles: 0,
|
|
609
|
-
hrStart: process$1.hrtime(),
|
|
500
|
+
...createProgressCounters(),
|
|
610
501
|
spinner: clack.spinner(),
|
|
611
502
|
isSpinning: false,
|
|
612
|
-
activeProgress: /* @__PURE__ */ new Map()
|
|
503
|
+
activeProgress: /* @__PURE__ */ new Map(),
|
|
504
|
+
activeHookLogs: /* @__PURE__ */ new Map()
|
|
613
505
|
};
|
|
614
506
|
function reset() {
|
|
615
507
|
for (const [_key, active] of state.activeProgress) {
|
|
616
508
|
if (active.interval) clearInterval(active.interval);
|
|
617
509
|
active.progressBar?.stop();
|
|
618
510
|
}
|
|
619
|
-
state
|
|
620
|
-
state.completedPlugins = 0;
|
|
621
|
-
state.failedPlugins = 0;
|
|
622
|
-
state.totalFiles = 0;
|
|
623
|
-
state.processedFiles = 0;
|
|
624
|
-
state.hrStart = process$1.hrtime();
|
|
511
|
+
resetProgressCounters(state);
|
|
625
512
|
state.spinner = clack.spinner();
|
|
626
513
|
state.isSpinning = false;
|
|
627
514
|
state.activeProgress.clear();
|
|
515
|
+
state.activeHookLogs.clear();
|
|
628
516
|
}
|
|
629
517
|
function showProgressStep() {
|
|
630
518
|
if (logLevel$8 <= logLevel.silent) return;
|
|
@@ -634,11 +522,18 @@ const clackLogger = defineLogger({
|
|
|
634
522
|
function getMessage(message) {
|
|
635
523
|
return formatMessage(message, logLevel$8);
|
|
636
524
|
}
|
|
525
|
+
function onStep(event, message) {
|
|
526
|
+
context.on(event, () => {
|
|
527
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
528
|
+
clack.log.step(getMessage(message));
|
|
529
|
+
});
|
|
530
|
+
}
|
|
637
531
|
function startSpinner(text) {
|
|
638
532
|
state.spinner.start(text);
|
|
639
533
|
state.isSpinning = true;
|
|
640
534
|
}
|
|
641
535
|
function stopSpinner(text) {
|
|
536
|
+
if (!state.isSpinning) return;
|
|
642
537
|
state.spinner.stop(text);
|
|
643
538
|
state.isSpinning = false;
|
|
644
539
|
}
|
|
@@ -649,8 +544,11 @@ const clackLogger = defineLogger({
|
|
|
649
544
|
message,
|
|
650
545
|
styleText("dim", info)
|
|
651
546
|
].join(" "));
|
|
652
|
-
if (state.isSpinning)
|
|
653
|
-
|
|
547
|
+
if (state.isSpinning) {
|
|
548
|
+
state.spinner.message(text);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
clack.log.info(text);
|
|
654
552
|
});
|
|
655
553
|
context.on("kubb:success", ({ message, info = "" }) => {
|
|
656
554
|
if (logLevel$8 <= logLevel.silent) return;
|
|
@@ -659,8 +557,11 @@ const clackLogger = defineLogger({
|
|
|
659
557
|
message,
|
|
660
558
|
logLevel$8 >= logLevel.info ? styleText("dim", info) : void 0
|
|
661
559
|
].filter(Boolean).join(" "));
|
|
662
|
-
if (state.isSpinning)
|
|
663
|
-
|
|
560
|
+
if (state.isSpinning) {
|
|
561
|
+
stopSpinner(text);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
clack.log.success(text);
|
|
664
565
|
});
|
|
665
566
|
context.on("kubb:warn", ({ message, info }) => {
|
|
666
567
|
if (logLevel$8 < logLevel.warn) return;
|
|
@@ -674,8 +575,11 @@ const clackLogger = defineLogger({
|
|
|
674
575
|
context.on("kubb:error", ({ error }) => {
|
|
675
576
|
const caused = toCause(error);
|
|
676
577
|
const text = [styleText("red", "✗"), error.message].join(" ");
|
|
677
|
-
if (state.isSpinning)
|
|
678
|
-
|
|
578
|
+
if (state.isSpinning) {
|
|
579
|
+
stopSpinner(getMessage(text));
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
clack.log.error(getMessage(text));
|
|
679
583
|
if (logLevel$8 >= logLevel.debug && error.stack) {
|
|
680
584
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
681
585
|
for (const frame of frames) clack.log.message(getMessage(styleText("dim", frame.trim())));
|
|
@@ -726,6 +630,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
726
630
|
context.on("kubb:generation:start", ({ config }) => {
|
|
727
631
|
reset();
|
|
728
632
|
state.totalPlugins = config.plugins?.length ?? 0;
|
|
633
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
729
634
|
const text = getMessage(["Generation started", config.name ? `for ${styleText("dim", config.name)}` : void 0].filter(Boolean).join(" "));
|
|
730
635
|
clack.intro(text);
|
|
731
636
|
});
|
|
@@ -752,8 +657,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
752
657
|
const active = state.activeProgress.get(plugin.name);
|
|
753
658
|
if (!active || logLevel$8 === logLevel.silent) return;
|
|
754
659
|
clearInterval(active.interval);
|
|
755
|
-
|
|
756
|
-
else state.failedPlugins++;
|
|
660
|
+
recordPluginResult(state, success);
|
|
757
661
|
const durationStr = formatMsWithColor(duration);
|
|
758
662
|
const text = getMessage(success ? `${styleText("bold", plugin.name)} completed in ${durationStr}` : `${styleText("bold", plugin.name)} failed in ${styleText("red", formatMs(duration))}`);
|
|
759
663
|
active.progressBar.stop(text);
|
|
@@ -775,14 +679,14 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
775
679
|
progressBar.start(getMessage(text));
|
|
776
680
|
state.activeProgress.set("files", { progressBar });
|
|
777
681
|
});
|
|
778
|
-
context.on("kubb:
|
|
682
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
779
683
|
if (logLevel$8 <= logLevel.silent) return;
|
|
780
684
|
stopSpinner();
|
|
781
|
-
state.processedFiles++;
|
|
782
|
-
const text = `Writing ${relative(config.root, file.path)}`;
|
|
783
685
|
const active = state.activeProgress.get("files");
|
|
784
|
-
|
|
785
|
-
|
|
686
|
+
for (const { file, config } of files) {
|
|
687
|
+
state.processedFiles++;
|
|
688
|
+
if (active) active.progressBar.advance(void 0, `Writing ${relative(config.root, file.path)}`);
|
|
689
|
+
}
|
|
786
690
|
});
|
|
787
691
|
context.on("kubb:files:processing:end", () => {
|
|
788
692
|
if (logLevel$8 <= logLevel.silent) return;
|
|
@@ -795,68 +699,35 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
795
699
|
showProgressStep();
|
|
796
700
|
});
|
|
797
701
|
context.on("kubb:generation:end", ({ config }) => {
|
|
702
|
+
stopSpinner();
|
|
798
703
|
const text = getMessage(config.name ? `Generation completed for ${styleText("dim", config.name)}` : "Generation completed");
|
|
799
704
|
clack.outro(text);
|
|
800
705
|
});
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
const text = getMessage("Lint started");
|
|
814
|
-
clack.intro(text);
|
|
815
|
-
});
|
|
816
|
-
context.on("kubb:lint:end", () => {
|
|
817
|
-
if (logLevel$8 <= logLevel.silent) return;
|
|
818
|
-
const text = getMessage("Lint completed");
|
|
819
|
-
clack.outro(text);
|
|
706
|
+
onStep("kubb:format:start", "Formatting");
|
|
707
|
+
onStep("kubb:lint:start", "Linting");
|
|
708
|
+
onStep("kubb:hooks:start", "Running hooks");
|
|
709
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
710
|
+
if (logLevel$8 <= logLevel.silent || !id) return;
|
|
711
|
+
stopSpinner();
|
|
712
|
+
const title = getMessage(`Running ${styleText("dim", formatCommandWithArgs(command, args))}`);
|
|
713
|
+
const taskLog = clack.taskLog({ title });
|
|
714
|
+
state.activeHookLogs.set(id, {
|
|
715
|
+
taskLog,
|
|
716
|
+
hrStart: process$1.hrtime()
|
|
717
|
+
});
|
|
820
718
|
});
|
|
821
|
-
context.on("kubb:hook:
|
|
719
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
720
|
+
if (logLevel$8 <= logLevel.silent || !id) return;
|
|
721
|
+
const active = state.activeHookLogs.get(id);
|
|
722
|
+
if (!active) return;
|
|
723
|
+
state.activeHookLogs.delete(id);
|
|
822
724
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
823
|
-
const
|
|
824
|
-
if (
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
command,
|
|
829
|
-
args,
|
|
830
|
-
commandWithArgs,
|
|
831
|
-
context,
|
|
832
|
-
sink: {
|
|
833
|
-
onStderr: (s) => console.error(s),
|
|
834
|
-
onStdout: (s) => console.log(s)
|
|
835
|
-
}
|
|
836
|
-
});
|
|
837
|
-
return;
|
|
725
|
+
const duration = formatMsWithColor(getElapsedMs(active.hrStart));
|
|
726
|
+
if (success) active.taskLog.success(getMessage(`${styleText("dim", commandWithArgs)} completed in ${duration}`));
|
|
727
|
+
else {
|
|
728
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
729
|
+
active.taskLog.error(getMessage(`${styleText("dim", commandWithArgs)} failed${reason}`), { showLog: true });
|
|
838
730
|
}
|
|
839
|
-
clack.intro(text);
|
|
840
|
-
const logger = clack.taskLog({ title: getMessage(["Executing hook", logLevel$8 >= logLevel.info ? styleText("dim", commandWithArgs) : void 0].filter(Boolean).join(" ")) });
|
|
841
|
-
const writable = new ClackWritable(logger);
|
|
842
|
-
await runHook({
|
|
843
|
-
id,
|
|
844
|
-
command,
|
|
845
|
-
args,
|
|
846
|
-
commandWithArgs,
|
|
847
|
-
context,
|
|
848
|
-
stream: true,
|
|
849
|
-
sink: {
|
|
850
|
-
onLine: (line) => writable.write(line),
|
|
851
|
-
onStderr: (s) => logger.error(s),
|
|
852
|
-
onStdout: (s) => logger.message(s)
|
|
853
|
-
}
|
|
854
|
-
});
|
|
855
|
-
});
|
|
856
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
857
|
-
if (logLevel$8 <= logLevel.silent) return;
|
|
858
|
-
const text = getMessage(`Hook ${styleText("dim", formatCommandWithArgs(command, args))} successfully executed`);
|
|
859
|
-
clack.outro(text);
|
|
860
731
|
});
|
|
861
732
|
context.on("kubb:generation:summary", ({ config, pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
|
|
862
733
|
const summary = getSummary({
|
|
@@ -887,13 +758,29 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
887
758
|
context.on("kubb:lifecycle:end", () => {
|
|
888
759
|
reset();
|
|
889
760
|
});
|
|
761
|
+
return (_commandWithArgs, hookId) => {
|
|
762
|
+
if (logLevel$8 <= logLevel.silent) return {
|
|
763
|
+
onStdout: (s) => console.log(s),
|
|
764
|
+
onStderr: (s) => console.error(s)
|
|
765
|
+
};
|
|
766
|
+
const active = state.activeHookLogs.get(hookId);
|
|
767
|
+
if (!active) return null;
|
|
768
|
+
const { taskLog } = active;
|
|
769
|
+
return {
|
|
770
|
+
stream: true,
|
|
771
|
+
onLine: (line) => taskLog.message(styleText("dim", line)),
|
|
772
|
+
onStdout: (s) => taskLog.message(s),
|
|
773
|
+
onStderr: (s) => taskLog.message(styleText("red", s))
|
|
774
|
+
};
|
|
775
|
+
};
|
|
890
776
|
}
|
|
891
777
|
});
|
|
892
778
|
//#endregion
|
|
893
779
|
//#region src/loggers/fileSystemLogger.ts
|
|
894
780
|
/**
|
|
895
781
|
* FileSystem logger that captures debug events and writes them to `.kubb` directory files.
|
|
896
|
-
*
|
|
782
|
+
*
|
|
783
|
+
* @note Logs are written on `kubb:lifecycle:end` or process exit. Cached logs may be lost if the process crashes before either event.
|
|
897
784
|
*/
|
|
898
785
|
const fileSystemLogger = defineLogger({
|
|
899
786
|
name: "filesystem",
|
|
@@ -918,29 +805,31 @@ const fileSystemLogger = defineLogger({
|
|
|
918
805
|
const pathName = resolve(process$1.cwd(), ".kubb", baseName);
|
|
919
806
|
if (!files[pathName]) files[pathName] = [];
|
|
920
807
|
if (log.logs.length > 0) {
|
|
921
|
-
const
|
|
922
|
-
|
|
808
|
+
const prefix = `[${log.date.toLocaleString()}] `;
|
|
809
|
+
const indent = " ".repeat(prefix.length);
|
|
810
|
+
const [first, ...rest] = log.logs;
|
|
811
|
+
files[pathName].push([prefix + first, ...rest.map((line) => indent + line)].join("\n"));
|
|
923
812
|
}
|
|
924
813
|
}
|
|
925
|
-
for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n
|
|
814
|
+
for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n"));
|
|
926
815
|
return Object.keys(files);
|
|
927
816
|
}
|
|
928
817
|
context.on("kubb:info", ({ message, info }) => {
|
|
929
818
|
state.cachedLogs.add({
|
|
930
819
|
date: /* @__PURE__ */ new Date(),
|
|
931
|
-
logs: [`ℹ ${message
|
|
820
|
+
logs: [`ℹ ${[message, info].filter(Boolean).join(" ")}`]
|
|
932
821
|
});
|
|
933
822
|
});
|
|
934
823
|
context.on("kubb:success", ({ message, info }) => {
|
|
935
824
|
state.cachedLogs.add({
|
|
936
825
|
date: /* @__PURE__ */ new Date(),
|
|
937
|
-
logs: [`✓ ${message
|
|
826
|
+
logs: [`✓ ${[message, info].filter(Boolean).join(" ")}`]
|
|
938
827
|
});
|
|
939
828
|
});
|
|
940
829
|
context.on("kubb:warn", ({ message, info }) => {
|
|
941
830
|
state.cachedLogs.add({
|
|
942
831
|
date: /* @__PURE__ */ new Date(),
|
|
943
|
-
logs: [`⚠ ${message
|
|
832
|
+
logs: [`⚠ ${[message, info].filter(Boolean).join(" ")}`]
|
|
944
833
|
});
|
|
945
834
|
});
|
|
946
835
|
context.on("kubb:error", ({ error }) => {
|
|
@@ -949,29 +838,30 @@ const fileSystemLogger = defineLogger({
|
|
|
949
838
|
logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
|
|
950
839
|
});
|
|
951
840
|
});
|
|
952
|
-
context.on("kubb:debug", (
|
|
841
|
+
context.on("kubb:debug", ({ date, fileName, logs }) => {
|
|
953
842
|
state.cachedLogs.add({
|
|
954
|
-
date
|
|
955
|
-
|
|
843
|
+
date,
|
|
844
|
+
fileName,
|
|
845
|
+
logs
|
|
956
846
|
});
|
|
957
847
|
});
|
|
958
848
|
context.on("kubb:plugin:start", ({ plugin }) => {
|
|
959
849
|
state.cachedLogs.add({
|
|
960
850
|
date: /* @__PURE__ */ new Date(),
|
|
961
|
-
logs: [
|
|
851
|
+
logs: [`► Generating ${plugin.name}`]
|
|
962
852
|
});
|
|
963
853
|
});
|
|
964
854
|
context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
965
855
|
const durationStr = formatMs(duration);
|
|
966
856
|
state.cachedLogs.add({
|
|
967
857
|
date: /* @__PURE__ */ new Date(),
|
|
968
|
-
logs: [success ?
|
|
858
|
+
logs: [success ? `✓ ${plugin.name} completed in ${durationStr}` : `✗ ${plugin.name} failed in ${durationStr}`]
|
|
969
859
|
});
|
|
970
860
|
});
|
|
971
861
|
context.on("kubb:files:processing:start", ({ files }) => {
|
|
972
862
|
state.cachedLogs.add({
|
|
973
863
|
date: /* @__PURE__ */ new Date(),
|
|
974
|
-
logs: [
|
|
864
|
+
logs: [`► Writing ${files.length} files`, ...files.map((file) => ` ${file.path}`)]
|
|
975
865
|
});
|
|
976
866
|
});
|
|
977
867
|
context.on("kubb:generation:end", async ({ config }) => {
|
|
@@ -1003,22 +893,16 @@ const githubActionsLogger = defineLogger({
|
|
|
1003
893
|
install(context, options) {
|
|
1004
894
|
const logLevel$7 = options?.logLevel ?? logLevel.info;
|
|
1005
895
|
const state = {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
totalFiles: 0,
|
|
1010
|
-
processedFiles: 0,
|
|
1011
|
-
hrStart: process.hrtime(),
|
|
1012
|
-
currentConfigs: []
|
|
896
|
+
...createProgressCounters(),
|
|
897
|
+
currentConfigs: [],
|
|
898
|
+
openGroupDepth: 0
|
|
1013
899
|
};
|
|
900
|
+
const hookTimer = createHookTimer();
|
|
1014
901
|
function reset() {
|
|
1015
|
-
|
|
1016
|
-
state
|
|
1017
|
-
state.failedPlugins = 0;
|
|
1018
|
-
state.totalFiles = 0;
|
|
1019
|
-
state.processedFiles = 0;
|
|
1020
|
-
state.hrStart = process.hrtime();
|
|
902
|
+
closeAllGroups();
|
|
903
|
+
resetProgressCounters(state);
|
|
1021
904
|
state.currentConfigs = [];
|
|
905
|
+
hookTimer.clear();
|
|
1022
906
|
}
|
|
1023
907
|
function showProgressStep() {
|
|
1024
908
|
if (logLevel$7 <= logLevel.silent) return;
|
|
@@ -1030,9 +914,31 @@ const githubActionsLogger = defineLogger({
|
|
|
1030
914
|
}
|
|
1031
915
|
function openGroup(name) {
|
|
1032
916
|
console.log(`::group::${name}`);
|
|
917
|
+
state.openGroupDepth++;
|
|
1033
918
|
}
|
|
1034
919
|
function closeGroup(_name) {
|
|
1035
920
|
console.log("::endgroup::");
|
|
921
|
+
if (state.openGroupDepth > 0) state.openGroupDepth--;
|
|
922
|
+
}
|
|
923
|
+
function closeAllGroups() {
|
|
924
|
+
while (state.openGroupDepth > 0) {
|
|
925
|
+
console.log("::endgroup::");
|
|
926
|
+
state.openGroupDepth--;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
function onGroupStart(event, message, group) {
|
|
930
|
+
context.on(event, () => {
|
|
931
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
932
|
+
if (state.currentConfigs.length === 1) openGroup(group);
|
|
933
|
+
console.log(getMessage(message));
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
function onGroupEnd(event, message, group) {
|
|
937
|
+
context.on(event, () => {
|
|
938
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
939
|
+
console.log(getMessage(message));
|
|
940
|
+
if (state.currentConfigs.length === 1) closeGroup(group);
|
|
941
|
+
});
|
|
1036
942
|
}
|
|
1037
943
|
context.on("kubb:info", ({ message, info = "" }) => {
|
|
1038
944
|
if (logLevel$7 <= logLevel.silent) return;
|
|
@@ -1063,6 +969,7 @@ const githubActionsLogger = defineLogger({
|
|
|
1063
969
|
});
|
|
1064
970
|
context.on("kubb:error", ({ error }) => {
|
|
1065
971
|
const caused = toCause(error);
|
|
972
|
+
closeAllGroups();
|
|
1066
973
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1067
974
|
const message = error.message || String(error);
|
|
1068
975
|
console.error(`::error::${message}`);
|
|
@@ -1080,6 +987,9 @@ const githubActionsLogger = defineLogger({
|
|
|
1080
987
|
console.log(styleText("yellow", `Kubb ${version} 🧩`));
|
|
1081
988
|
reset();
|
|
1082
989
|
});
|
|
990
|
+
context.on("kubb:version:new", ({ currentVersion, latestVersion }) => {
|
|
991
|
+
console.log(`::notice::Update available for Kubb: v${currentVersion} → v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`);
|
|
992
|
+
});
|
|
1083
993
|
context.on("kubb:config:start", () => {
|
|
1084
994
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1085
995
|
const text = getMessage("Configuration started");
|
|
@@ -1108,8 +1018,7 @@ const githubActionsLogger = defineLogger({
|
|
|
1108
1018
|
});
|
|
1109
1019
|
context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
1110
1020
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1111
|
-
|
|
1112
|
-
else state.failedPlugins++;
|
|
1021
|
+
recordPluginResult(state, success);
|
|
1113
1022
|
const durationStr = formatMsWithColor(duration);
|
|
1114
1023
|
const text = getMessage(success ? `${styleText("bold", plugin.name)} completed in ${durationStr}` : `${styleText("bold", plugin.name)} failed in ${styleText("red", formatMs(duration))}`);
|
|
1115
1024
|
console.log(text);
|
|
@@ -1132,63 +1041,38 @@ const githubActionsLogger = defineLogger({
|
|
|
1132
1041
|
if (state.currentConfigs.length === 1) closeGroup("File Generation");
|
|
1133
1042
|
showProgressStep();
|
|
1134
1043
|
});
|
|
1135
|
-
context.on("kubb:
|
|
1044
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
1136
1045
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1137
|
-
state.processedFiles
|
|
1046
|
+
state.processedFiles += files.length;
|
|
1138
1047
|
});
|
|
1139
1048
|
context.on("kubb:generation:end", ({ config }) => {
|
|
1140
1049
|
const text = getMessage(config.name ? `${styleText("blue", "✓")} Generation completed for ${styleText("dim", config.name)}` : `${styleText("blue", "✓")} Generation completed`);
|
|
1141
1050
|
console.log(text);
|
|
1142
1051
|
});
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
context.on("kubb:
|
|
1150
|
-
if (logLevel$7 <= logLevel.silent) return;
|
|
1151
|
-
const text = getMessage("Format completed");
|
|
1152
|
-
console.log(text);
|
|
1153
|
-
if (state.currentConfigs.length === 1) closeGroup("Formatting");
|
|
1154
|
-
});
|
|
1155
|
-
context.on("kubb:lint:start", () => {
|
|
1156
|
-
if (logLevel$7 <= logLevel.silent) return;
|
|
1157
|
-
const text = getMessage("Lint started");
|
|
1158
|
-
if (state.currentConfigs.length === 1) openGroup("Linting");
|
|
1159
|
-
console.log(text);
|
|
1160
|
-
});
|
|
1161
|
-
context.on("kubb:lint:end", () => {
|
|
1052
|
+
onGroupStart("kubb:format:start", "Format started", "Formatting");
|
|
1053
|
+
onGroupEnd("kubb:format:end", "Format completed", "Formatting");
|
|
1054
|
+
onGroupStart("kubb:lint:start", "Lint started", "Linting");
|
|
1055
|
+
onGroupEnd("kubb:lint:end", "Lint completed", "Linting");
|
|
1056
|
+
onGroupStart("kubb:hooks:start", "Hooks started", "Hooks");
|
|
1057
|
+
onGroupEnd("kubb:hooks:end", "Hooks completed", "Hooks");
|
|
1058
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
1162
1059
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1163
|
-
|
|
1164
|
-
console.log(text);
|
|
1165
|
-
if (state.currentConfigs.length === 1) closeGroup("Linting");
|
|
1166
|
-
});
|
|
1167
|
-
context.on("kubb:hook:start", async ({ id, command, args }) => {
|
|
1060
|
+
if (id) hookTimer.start(id);
|
|
1168
1061
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1169
1062
|
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} started`);
|
|
1170
|
-
if (
|
|
1171
|
-
|
|
1172
|
-
console.log(text);
|
|
1173
|
-
}
|
|
1174
|
-
if (!id) return;
|
|
1175
|
-
await runHook({
|
|
1176
|
-
id,
|
|
1177
|
-
command,
|
|
1178
|
-
args,
|
|
1179
|
-
commandWithArgs,
|
|
1180
|
-
context,
|
|
1181
|
-
sink: {
|
|
1182
|
-
onStdout: logLevel$7 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1183
|
-
onStderr: logLevel$7 > logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
|
|
1184
|
-
}
|
|
1185
|
-
});
|
|
1063
|
+
if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
|
|
1064
|
+
console.log(text);
|
|
1186
1065
|
});
|
|
1187
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
1066
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
1188
1067
|
if (logLevel$7 <= logLevel.silent) return;
|
|
1068
|
+
const ms = id ? hookTimer.end(id) : void 0;
|
|
1069
|
+
const durationStr = ms !== void 0 ? ` in ${formatMsWithColor(ms)}` : "";
|
|
1189
1070
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1190
|
-
|
|
1191
|
-
|
|
1071
|
+
if (success) console.log(getMessage(`${styleText("green", "✓")} Hook ${styleText("dim", commandWithArgs)} completed${durationStr}`));
|
|
1072
|
+
else {
|
|
1073
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
1074
|
+
console.log(`::error::Hook ${commandWithArgs} failed${durationStr}${reason}`);
|
|
1075
|
+
}
|
|
1192
1076
|
if (state.currentConfigs.length === 1) closeGroup(`Hook ${commandWithArgs}`);
|
|
1193
1077
|
});
|
|
1194
1078
|
context.on("kubb:generation:summary", ({ config, status, hrStart, failedPlugins }) => {
|
|
@@ -1202,6 +1086,10 @@ const githubActionsLogger = defineLogger({
|
|
|
1202
1086
|
context.on("kubb:lifecycle:end", () => {
|
|
1203
1087
|
reset();
|
|
1204
1088
|
});
|
|
1089
|
+
return (_commandWithArgs, _hookId) => ({
|
|
1090
|
+
onStdout: logLevel$7 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1091
|
+
onStderr: logLevel$7 > logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
|
|
1092
|
+
});
|
|
1205
1093
|
}
|
|
1206
1094
|
});
|
|
1207
1095
|
//#endregion
|
|
@@ -1213,9 +1101,16 @@ const plainLogger = defineLogger({
|
|
|
1213
1101
|
name: "plain",
|
|
1214
1102
|
install(context, options) {
|
|
1215
1103
|
const logLevel$6 = options?.logLevel ?? logLevel.info;
|
|
1104
|
+
const hookTimer = createHookTimer();
|
|
1216
1105
|
function getMessage(message) {
|
|
1217
1106
|
return formatMessage(message, logLevel$6);
|
|
1218
1107
|
}
|
|
1108
|
+
function onStep(event, message) {
|
|
1109
|
+
context.on(event, () => {
|
|
1110
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1111
|
+
console.log(getMessage(message));
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1219
1114
|
context.on("kubb:info", ({ message, info }) => {
|
|
1220
1115
|
if (logLevel$6 <= logLevel.silent) return;
|
|
1221
1116
|
const text = getMessage([
|
|
@@ -1257,19 +1152,15 @@ const plainLogger = defineLogger({
|
|
|
1257
1152
|
}
|
|
1258
1153
|
}
|
|
1259
1154
|
});
|
|
1260
|
-
context.on("kubb:lifecycle:start", () => {
|
|
1261
|
-
console.log(
|
|
1262
|
-
});
|
|
1263
|
-
context.on("kubb:config:start", () => {
|
|
1264
|
-
if (logLevel$6 <= logLevel.silent) return;
|
|
1265
|
-
const text = getMessage("Configuration started");
|
|
1266
|
-
console.log(text);
|
|
1155
|
+
context.on("kubb:lifecycle:start", ({ version }) => {
|
|
1156
|
+
console.log(`Kubb CLI v${version}`);
|
|
1267
1157
|
});
|
|
1268
|
-
context.on("kubb:
|
|
1158
|
+
context.on("kubb:version:new", ({ currentVersion, latestVersion }) => {
|
|
1269
1159
|
if (logLevel$6 <= logLevel.silent) return;
|
|
1270
|
-
|
|
1271
|
-
console.log(text);
|
|
1160
|
+
console.log(getMessage(`Update available: v${currentVersion} → v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`));
|
|
1272
1161
|
});
|
|
1162
|
+
onStep("kubb:config:start", "Configuration started");
|
|
1163
|
+
onStep("kubb:config:end", "Configuration completed");
|
|
1273
1164
|
context.on("kubb:generation:start", () => {
|
|
1274
1165
|
const text = getMessage("Generation started");
|
|
1275
1166
|
console.log(text);
|
|
@@ -1290,10 +1181,9 @@ const plainLogger = defineLogger({
|
|
|
1290
1181
|
const text = getMessage(`Writing ${files.length} files`);
|
|
1291
1182
|
console.log(text);
|
|
1292
1183
|
});
|
|
1293
|
-
context.on("kubb:
|
|
1184
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
1294
1185
|
if (logLevel$6 <= logLevel.silent) return;
|
|
1295
|
-
const
|
|
1296
|
-
console.log(text);
|
|
1186
|
+
for (const { file, config } of files) console.log(getMessage(`Writing ${relative(config.root, file.path)}`));
|
|
1297
1187
|
});
|
|
1298
1188
|
context.on("kubb:files:processing:end", () => {
|
|
1299
1189
|
if (logLevel$6 <= logLevel.silent) return;
|
|
@@ -1304,47 +1194,28 @@ const plainLogger = defineLogger({
|
|
|
1304
1194
|
const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
|
|
1305
1195
|
console.log(text);
|
|
1306
1196
|
});
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
const text = getMessage("Format completed");
|
|
1315
|
-
console.log(text);
|
|
1316
|
-
});
|
|
1317
|
-
context.on("kubb:lint:start", () => {
|
|
1318
|
-
if (logLevel$6 <= logLevel.silent) return;
|
|
1319
|
-
const text = getMessage("Lint started");
|
|
1320
|
-
console.log(text);
|
|
1321
|
-
});
|
|
1322
|
-
context.on("kubb:lint:end", () => {
|
|
1197
|
+
onStep("kubb:format:start", "Format started");
|
|
1198
|
+
onStep("kubb:format:end", "Format completed");
|
|
1199
|
+
onStep("kubb:lint:start", "Lint started");
|
|
1200
|
+
onStep("kubb:lint:end", "Lint completed");
|
|
1201
|
+
onStep("kubb:hooks:start", "Hooks started");
|
|
1202
|
+
onStep("kubb:hooks:end", "Hooks completed");
|
|
1203
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
1323
1204
|
if (logLevel$6 <= logLevel.silent) return;
|
|
1324
|
-
|
|
1325
|
-
console.log(text);
|
|
1326
|
-
});
|
|
1327
|
-
context.on("kubb:hook:start", async ({ id, command, args }) => {
|
|
1205
|
+
if (id) hookTimer.start(id);
|
|
1328
1206
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1329
|
-
|
|
1330
|
-
if (logLevel$6 > logLevel.silent) console.log(text);
|
|
1331
|
-
if (!id) return;
|
|
1332
|
-
await runHook({
|
|
1333
|
-
id,
|
|
1334
|
-
command,
|
|
1335
|
-
args,
|
|
1336
|
-
commandWithArgs,
|
|
1337
|
-
context,
|
|
1338
|
-
sink: {
|
|
1339
|
-
onStdout: logLevel$6 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1340
|
-
onStderr: logLevel$6 > logLevel.silent ? (s) => console.error(s) : void 0
|
|
1341
|
-
}
|
|
1342
|
-
});
|
|
1207
|
+
console.log(getMessage(`Hook ${commandWithArgs} started`));
|
|
1343
1208
|
});
|
|
1344
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
1209
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
1345
1210
|
if (logLevel$6 <= logLevel.silent) return;
|
|
1346
|
-
const
|
|
1347
|
-
|
|
1211
|
+
const ms = id ? hookTimer.end(id) : void 0;
|
|
1212
|
+
const durationStr = ms !== void 0 ? ` in ${formatMs(ms)}` : "";
|
|
1213
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1214
|
+
if (success) console.log(getMessage(`✓ Hook ${commandWithArgs} completed${durationStr}`));
|
|
1215
|
+
else {
|
|
1216
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
1217
|
+
console.log(getMessage(`✗ Hook ${commandWithArgs} failed${durationStr}${reason}`));
|
|
1218
|
+
}
|
|
1348
1219
|
});
|
|
1349
1220
|
context.on("kubb:generation:summary", ({ config, pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
|
|
1350
1221
|
const summary = getSummary({
|
|
@@ -1359,6 +1230,10 @@ const plainLogger = defineLogger({
|
|
|
1359
1230
|
console.log(summary.join("\n"));
|
|
1360
1231
|
console.log(SUMMARY_SEPARATOR);
|
|
1361
1232
|
});
|
|
1233
|
+
return (_commandWithArgs, _hookId) => ({
|
|
1234
|
+
onStdout: logLevel$6 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1235
|
+
onStderr: logLevel$6 > logLevel.silent ? (s) => console.error(s) : void 0
|
|
1236
|
+
});
|
|
1362
1237
|
}
|
|
1363
1238
|
});
|
|
1364
1239
|
//#endregion
|
|
@@ -1393,6 +1268,57 @@ function buildProgressLine(state) {
|
|
|
1393
1268
|
return parts.join(styleText("dim", " | "));
|
|
1394
1269
|
}
|
|
1395
1270
|
/**
|
|
1271
|
+
* Creates the per-run progress counters shared by the clack and GitHub Actions loggers.
|
|
1272
|
+
*/
|
|
1273
|
+
function createProgressCounters() {
|
|
1274
|
+
return {
|
|
1275
|
+
totalPlugins: 0,
|
|
1276
|
+
completedPlugins: 0,
|
|
1277
|
+
failedPlugins: 0,
|
|
1278
|
+
totalFiles: 0,
|
|
1279
|
+
processedFiles: 0,
|
|
1280
|
+
hrStart: process$1.hrtime()
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Resets the progress counters in place at the start/end of a generation run.
|
|
1285
|
+
*/
|
|
1286
|
+
function resetProgressCounters(state) {
|
|
1287
|
+
state.totalPlugins = 0;
|
|
1288
|
+
state.completedPlugins = 0;
|
|
1289
|
+
state.failedPlugins = 0;
|
|
1290
|
+
state.totalFiles = 0;
|
|
1291
|
+
state.processedFiles = 0;
|
|
1292
|
+
state.hrStart = process$1.hrtime();
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Records a finished plugin against the progress counters.
|
|
1296
|
+
*/
|
|
1297
|
+
function recordPluginResult(state, success) {
|
|
1298
|
+
if (success) state.completedPlugins++;
|
|
1299
|
+
else state.failedPlugins++;
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Creates a {@link HookTimer} backed by a private `id → hrtime` map.
|
|
1303
|
+
*/
|
|
1304
|
+
function createHookTimer() {
|
|
1305
|
+
const starts = /* @__PURE__ */ new Map();
|
|
1306
|
+
return {
|
|
1307
|
+
start(id) {
|
|
1308
|
+
starts.set(id, process$1.hrtime());
|
|
1309
|
+
},
|
|
1310
|
+
end(id) {
|
|
1311
|
+
const hrStart = starts.get(id);
|
|
1312
|
+
if (!hrStart) return;
|
|
1313
|
+
starts.delete(id);
|
|
1314
|
+
return getElapsedMs(hrStart);
|
|
1315
|
+
},
|
|
1316
|
+
clear() {
|
|
1317
|
+
starts.clear();
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1396
1322
|
* Join a command and its optional args into a single display string.
|
|
1397
1323
|
* e.g. ("prettier", ["--write", "."]) → "prettier --write ."
|
|
1398
1324
|
*/
|
|
@@ -1413,125 +1339,247 @@ async function setupLogger(context, { logLevel: logLevel$5 }) {
|
|
|
1413
1339
|
const type = detectLogger();
|
|
1414
1340
|
const logger = logMapper[type];
|
|
1415
1341
|
if (!logger) throw new Error(`Unknown adapter type: ${type}`);
|
|
1416
|
-
const
|
|
1342
|
+
const makeSink = await logger.install(context, { logLevel: logLevel$5 });
|
|
1417
1343
|
if (logLevel$5 >= logLevel.debug) await fileSystemLogger.install(context, { logLevel: logLevel$5 });
|
|
1418
|
-
return
|
|
1344
|
+
return typeof makeSink === "function" ? makeSink : null;
|
|
1419
1345
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1346
|
+
/**
|
|
1347
|
+
* Builds the generation summary lines rendered in the end-of-run box.
|
|
1348
|
+
* Returns an array of styled strings, one per summary row.
|
|
1349
|
+
*/
|
|
1350
|
+
function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
|
|
1351
|
+
const duration = formatHrtime(hrStart);
|
|
1352
|
+
const pluginsCount = config.plugins?.length ?? 0;
|
|
1353
|
+
const successCount = pluginsCount - failedPlugins.size;
|
|
1354
|
+
const meta = {
|
|
1355
|
+
plugins: status === "success" ? `${styleText("green", `${successCount} successful`)}, ${pluginsCount} total` : `${styleText("green", `${successCount} successful`)}, ${styleText("red", `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
|
|
1356
|
+
pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
|
|
1357
|
+
filesCreated,
|
|
1358
|
+
time: styleText("green", duration),
|
|
1359
|
+
output: path.resolve(config.root, config.output.path)
|
|
1360
|
+
};
|
|
1361
|
+
const labels = {
|
|
1362
|
+
plugins: "Plugins:",
|
|
1363
|
+
failed: "Failed:",
|
|
1364
|
+
generated: "Generated:",
|
|
1365
|
+
pluginTimings: "Plugin Timings:",
|
|
1366
|
+
output: "Output:"
|
|
1367
|
+
};
|
|
1368
|
+
const maxLength = Math.max(0, ...[...Object.values(labels), ...pluginTimings ? Array.from(pluginTimings.keys()) : []].map((s) => s.length));
|
|
1369
|
+
const summaryLines = [];
|
|
1370
|
+
summaryLines.push(`${labels.plugins.padEnd(maxLength + 2)} ${meta.plugins}`);
|
|
1371
|
+
if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
|
|
1372
|
+
summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
|
|
1373
|
+
if (pluginTimings && pluginTimings.size > 0) {
|
|
1374
|
+
const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
|
|
1375
|
+
summaryLines.push(`${labels.pluginTimings}`);
|
|
1376
|
+
sortedTimings.forEach(([name, time]) => {
|
|
1377
|
+
const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
|
|
1378
|
+
const barLength = Math.min(Math.ceil(time / 100), 10);
|
|
1379
|
+
const bar = styleText("dim", "█".repeat(barLength));
|
|
1380
|
+
summaryLines.push(`${styleText("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
|
|
1444
1381
|
});
|
|
1445
|
-
await hookEndPromise;
|
|
1446
1382
|
}
|
|
1383
|
+
summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
|
|
1384
|
+
return summaryLines;
|
|
1447
1385
|
}
|
|
1448
1386
|
//#endregion
|
|
1449
|
-
//#region src/utils
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
const
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
`${moduleName}.config.mts`,
|
|
1486
|
-
`${moduleName}.config.cts`,
|
|
1487
|
-
`${moduleName}.config.js`,
|
|
1488
|
-
`${moduleName}.config.mjs`,
|
|
1489
|
-
`${moduleName}.config.cjs`
|
|
1490
|
-
];
|
|
1491
|
-
const explorer = cosmiconfig(moduleName, {
|
|
1387
|
+
//#region src/runners/generate/utils.ts
|
|
1388
|
+
const jiti = createJiti(import.meta.url, {
|
|
1389
|
+
jsx: {
|
|
1390
|
+
runtime: "automatic",
|
|
1391
|
+
importSource: "@kubb/renderer-jsx"
|
|
1392
|
+
},
|
|
1393
|
+
moduleCache: false
|
|
1394
|
+
});
|
|
1395
|
+
const tsLoader = (configFile) => jiti.import(configFile, { default: true });
|
|
1396
|
+
const MODULE_NAME = "kubb";
|
|
1397
|
+
const BASE_SEARCH_PLACES = [
|
|
1398
|
+
"package.json",
|
|
1399
|
+
`.${MODULE_NAME}rc`,
|
|
1400
|
+
`.${MODULE_NAME}rc.json`,
|
|
1401
|
+
`.${MODULE_NAME}rc.yaml`,
|
|
1402
|
+
`.${MODULE_NAME}rc.yml`,
|
|
1403
|
+
`.${MODULE_NAME}rc.ts`,
|
|
1404
|
+
`.${MODULE_NAME}rc.mts`,
|
|
1405
|
+
`.${MODULE_NAME}rc.cts`,
|
|
1406
|
+
`.${MODULE_NAME}rc.js`,
|
|
1407
|
+
`.${MODULE_NAME}rc.mjs`,
|
|
1408
|
+
`.${MODULE_NAME}rc.cjs`,
|
|
1409
|
+
`${MODULE_NAME}.config.ts`,
|
|
1410
|
+
`${MODULE_NAME}.config.mts`,
|
|
1411
|
+
`${MODULE_NAME}.config.cts`,
|
|
1412
|
+
`${MODULE_NAME}.config.js`,
|
|
1413
|
+
`${MODULE_NAME}.config.mjs`,
|
|
1414
|
+
`${MODULE_NAME}.config.cjs`
|
|
1415
|
+
];
|
|
1416
|
+
const SEARCH_PLACES = [
|
|
1417
|
+
"",
|
|
1418
|
+
".config/",
|
|
1419
|
+
"configs/"
|
|
1420
|
+
].flatMap((prefix) => BASE_SEARCH_PLACES.map((p) => `${prefix}${p}`));
|
|
1421
|
+
async function getCosmiConfig(configFile) {
|
|
1422
|
+
const explorer = cosmiconfig(MODULE_NAME, {
|
|
1492
1423
|
cache: false,
|
|
1493
|
-
searchPlaces:
|
|
1494
|
-
...searchPlaces.map((searchPlace) => {
|
|
1495
|
-
return `.config/${searchPlace}`;
|
|
1496
|
-
}),
|
|
1497
|
-
...searchPlaces.map((searchPlace) => {
|
|
1498
|
-
return `configs/${searchPlace}`;
|
|
1499
|
-
}),
|
|
1500
|
-
...searchPlaces
|
|
1501
|
-
],
|
|
1424
|
+
searchPlaces: SEARCH_PLACES,
|
|
1502
1425
|
loaders: {
|
|
1503
1426
|
".ts": tsLoader,
|
|
1504
1427
|
".mts": tsLoader,
|
|
1505
1428
|
".cts": tsLoader
|
|
1506
1429
|
}
|
|
1507
1430
|
});
|
|
1431
|
+
let result;
|
|
1508
1432
|
try {
|
|
1509
|
-
result =
|
|
1433
|
+
result = configFile ? await explorer.load(configFile) : await explorer.search();
|
|
1510
1434
|
} catch (error) {
|
|
1511
1435
|
throw new Error("Config failed loading", { cause: error });
|
|
1512
1436
|
}
|
|
1513
|
-
if (result?.
|
|
1437
|
+
if (!result?.config || result.isEmpty) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
|
|
1514
1438
|
return result;
|
|
1515
1439
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1440
|
+
/**
|
|
1441
|
+
* Discovers the Kubb config via cosmiconfig and resolves it into a normalized array of configs.
|
|
1442
|
+
* Every config in the result is guaranteed to have a `plugins` array.
|
|
1443
|
+
*/
|
|
1444
|
+
async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
1445
|
+
const result = await getCosmiConfig(configPath);
|
|
1446
|
+
const cli = {
|
|
1447
|
+
config: configPath,
|
|
1448
|
+
input,
|
|
1449
|
+
watch,
|
|
1450
|
+
logLevel
|
|
1451
|
+
};
|
|
1452
|
+
const resolved = await (typeof result.config === "function" ? result.config(cli) : result.config);
|
|
1453
|
+
const userConfigs = Array.isArray(resolved) ? resolved : [resolved];
|
|
1454
|
+
return {
|
|
1455
|
+
configPath: result.filepath,
|
|
1456
|
+
configs: userConfigs.map((item) => ({
|
|
1457
|
+
...item,
|
|
1458
|
+
plugins: item.plugins ?? []
|
|
1459
|
+
}))
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Runs the `done` hooks defined in a Kubb config in sequence.
|
|
1464
|
+
*/
|
|
1465
|
+
async function executeHooks({ configHooks, hooks, makeSink }) {
|
|
1466
|
+
const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
|
|
1467
|
+
for (const command of commands) {
|
|
1468
|
+
const [cmd, ...args] = tokenize(command);
|
|
1469
|
+
if (!cmd) continue;
|
|
1470
|
+
const hookId = createHash("sha256").update(command).digest("hex");
|
|
1471
|
+
const commandWithArgs = [cmd, ...args].join(" ");
|
|
1472
|
+
await hooks.emit("kubb:hook:start", {
|
|
1473
|
+
id: hookId,
|
|
1474
|
+
command: cmd,
|
|
1475
|
+
args
|
|
1476
|
+
});
|
|
1477
|
+
const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
|
|
1478
|
+
await runHook({
|
|
1479
|
+
id: hookId,
|
|
1480
|
+
command: cmd,
|
|
1481
|
+
args,
|
|
1482
|
+
commandWithArgs,
|
|
1483
|
+
context: hooks,
|
|
1484
|
+
stream,
|
|
1485
|
+
sink: {
|
|
1486
|
+
onLine,
|
|
1487
|
+
onStdout,
|
|
1488
|
+
onStderr
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
|
|
1494
|
+
const emitEnd = (success, error) => context.emit("kubb:hook:end", {
|
|
1495
|
+
command,
|
|
1496
|
+
args,
|
|
1497
|
+
id,
|
|
1498
|
+
success,
|
|
1499
|
+
error
|
|
1500
|
+
});
|
|
1501
|
+
try {
|
|
1502
|
+
const proc = x(command, [...args ?? []], {
|
|
1503
|
+
nodeOptions: { detached: process.platform !== "win32" },
|
|
1504
|
+
throwOnError: true
|
|
1505
|
+
});
|
|
1506
|
+
if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
|
|
1507
|
+
const result = await proc;
|
|
1508
|
+
await context.emit("kubb:debug", {
|
|
1509
|
+
date: /* @__PURE__ */ new Date(),
|
|
1510
|
+
logs: [result.stdout.trimEnd()]
|
|
1511
|
+
});
|
|
1512
|
+
await context.emit("kubb:success", { message: `${styleText("dim", commandWithArgs)} successfully executed` });
|
|
1513
|
+
await emitEnd(true, null);
|
|
1514
|
+
} catch (err) {
|
|
1515
|
+
if (!(err instanceof NonZeroExitError)) {
|
|
1516
|
+
const error = toError(err);
|
|
1517
|
+
await emitEnd(false, error);
|
|
1518
|
+
await context.emit("kubb:error", { error });
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
const stderr = err.output?.stderr ?? "";
|
|
1522
|
+
const stdout = err.output?.stdout ?? "";
|
|
1523
|
+
await context.emit("kubb:debug", {
|
|
1524
|
+
date: /* @__PURE__ */ new Date(),
|
|
1525
|
+
logs: [stdout, stderr].filter(Boolean)
|
|
1526
|
+
});
|
|
1527
|
+
if (stderr) sink?.onStderr?.(stderr);
|
|
1528
|
+
if (stdout) sink?.onStdout?.(stdout);
|
|
1529
|
+
const error = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
1530
|
+
await emitEnd(false, error);
|
|
1531
|
+
await context.emit("kubb:error", { error });
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* Starts a file watcher on the given paths and calls `cb` on any change.
|
|
1536
|
+
* Ignores `.git` and `node_modules` directories.
|
|
1537
|
+
*/
|
|
1538
|
+
async function startWatcher(path, cb, log = {
|
|
1539
|
+
info: console.log,
|
|
1540
|
+
error: console.log
|
|
1541
|
+
}) {
|
|
1519
1542
|
const { watch } = await import("chokidar");
|
|
1520
|
-
watch(path, {
|
|
1543
|
+
const watcher = watch(path, {
|
|
1521
1544
|
ignorePermissionErrors: true,
|
|
1522
1545
|
ignored: WATCHER_IGNORED_PATHS
|
|
1523
|
-
})
|
|
1524
|
-
|
|
1546
|
+
});
|
|
1547
|
+
process.once("SIGINT", () => {
|
|
1548
|
+
watcher.close();
|
|
1549
|
+
});
|
|
1550
|
+
process.once("SIGTERM", () => {
|
|
1551
|
+
watcher.close();
|
|
1552
|
+
});
|
|
1553
|
+
watcher.on("all", async (type, file) => {
|
|
1554
|
+
log.info(styleText("yellow", styleText("bold", `Change detected: ${type} ${file}`)));
|
|
1525
1555
|
try {
|
|
1526
1556
|
await cb(path);
|
|
1527
1557
|
} catch (_e) {
|
|
1528
|
-
|
|
1558
|
+
log.error(styleText("red", "Watcher failed"));
|
|
1529
1559
|
}
|
|
1530
1560
|
});
|
|
1531
1561
|
}
|
|
1532
1562
|
//#endregion
|
|
1533
|
-
//#region src/runners/generate.ts
|
|
1534
|
-
|
|
1563
|
+
//#region src/runners/generate/run.ts
|
|
1564
|
+
/**
|
|
1565
|
+
* Registers a one-shot `kubb:hook:end` listener for `hookId` BEFORE the caller emits `kubb:hook:start`,
|
|
1566
|
+
* avoiding the race where a synchronous emitter fires end before the listener is attached.
|
|
1567
|
+
*/
|
|
1568
|
+
function waitForHookEnd(hooks, hookId, onSuccess, fallbackErrorMessage) {
|
|
1569
|
+
return new Promise((resolve, reject) => {
|
|
1570
|
+
const handler = (ctx) => {
|
|
1571
|
+
if (ctx.id !== hookId) return;
|
|
1572
|
+
hooks.off("kubb:hook:end", handler);
|
|
1573
|
+
if (!ctx.success) {
|
|
1574
|
+
reject(ctx.error ?? new Error(fallbackErrorMessage));
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
Promise.resolve(onSuccess()).then(resolve).catch(reject);
|
|
1578
|
+
};
|
|
1579
|
+
hooks.on("kubb:hook:end", handler);
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel: logLevel$1, hooks, makeSink, onStart, onEnd }) {
|
|
1535
1583
|
await onStart();
|
|
1536
1584
|
let resolvedTool = toolValue;
|
|
1537
1585
|
if (resolvedTool === "auto") {
|
|
@@ -1545,29 +1593,35 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
|
|
|
1545
1593
|
let toolError;
|
|
1546
1594
|
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
|
|
1547
1595
|
const toolConfig = toolMap[resolvedTool];
|
|
1596
|
+
const hookId = createHash("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
|
|
1597
|
+
const successMessage = [
|
|
1598
|
+
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1599
|
+
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1600
|
+
"successfully"
|
|
1601
|
+
].filter(Boolean).join(" ");
|
|
1548
1602
|
try {
|
|
1549
|
-
const
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1552
|
-
if (ctx.id !== hookId) return;
|
|
1553
|
-
hooks.off("kubb:hook:end", handler);
|
|
1554
|
-
if (!ctx.success) {
|
|
1555
|
-
reject(ctx.error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
hooks.emit("kubb:success", { message: [
|
|
1559
|
-
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1560
|
-
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1561
|
-
"successfully"
|
|
1562
|
-
].filter(Boolean).join(" ") }).then(resolve).catch(reject);
|
|
1563
|
-
};
|
|
1564
|
-
hooks.on("kubb:hook:end", handler);
|
|
1565
|
-
});
|
|
1603
|
+
const hookArgs = toolConfig.args(outputPath);
|
|
1604
|
+
const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
|
|
1605
|
+
const hookEndPromise = waitForHookEnd(hooks, hookId, () => hooks.emit("kubb:success", { message: successMessage }), toolConfig.errorMessage);
|
|
1566
1606
|
await hooks.emit("kubb:hook:start", {
|
|
1567
1607
|
id: hookId,
|
|
1568
1608
|
command: toolConfig.command,
|
|
1569
|
-
args:
|
|
1609
|
+
args: hookArgs
|
|
1570
1610
|
});
|
|
1611
|
+
const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
|
|
1612
|
+
runHook({
|
|
1613
|
+
id: hookId,
|
|
1614
|
+
command: toolConfig.command,
|
|
1615
|
+
args: hookArgs,
|
|
1616
|
+
commandWithArgs,
|
|
1617
|
+
context: hooks,
|
|
1618
|
+
stream,
|
|
1619
|
+
sink: {
|
|
1620
|
+
onLine,
|
|
1621
|
+
onStdout,
|
|
1622
|
+
onStderr
|
|
1623
|
+
}
|
|
1624
|
+
}).catch(() => {});
|
|
1571
1625
|
await hookEndPromise;
|
|
1572
1626
|
} catch (caughtError) {
|
|
1573
1627
|
const err = toError(caughtError);
|
|
@@ -1579,9 +1633,9 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
|
|
|
1579
1633
|
if (toolError) throw toolError;
|
|
1580
1634
|
}
|
|
1581
1635
|
async function generate(options) {
|
|
1582
|
-
const { input, hooks, logLevel: logLevel$2 } = options;
|
|
1636
|
+
const { input, hooks, logLevel: logLevel$2, makeSink } = options;
|
|
1583
1637
|
const hrStart = process$1.hrtime();
|
|
1584
|
-
const inputPath = input ?? ("path" in options.config.input ? options.config.input.path : void 0);
|
|
1638
|
+
const inputPath = input ?? (options.config.input && "path" in options.config.input ? options.config.input.path : void 0);
|
|
1585
1639
|
const config = {
|
|
1586
1640
|
...options.config,
|
|
1587
1641
|
input: inputPath ? {
|
|
@@ -1591,25 +1645,36 @@ async function generate(options) {
|
|
|
1591
1645
|
...options.config.output
|
|
1592
1646
|
};
|
|
1593
1647
|
const kubb = createKubb(config, { hooks });
|
|
1594
|
-
await kubb.setup();
|
|
1595
1648
|
await hooks.emit("kubb:generation:start", { config });
|
|
1596
1649
|
await hooks.emit("kubb:info", {
|
|
1597
1650
|
message: config.name ? `Setup generation ${styleText("bold", config.name)}` : "Setup generation",
|
|
1598
1651
|
info: inputPath
|
|
1599
1652
|
});
|
|
1653
|
+
await kubb.setup();
|
|
1600
1654
|
await hooks.emit("kubb:info", {
|
|
1601
1655
|
message: config.name ? `Build generation ${styleText("bold", config.name)}` : "Build generation",
|
|
1602
1656
|
info: inputPath
|
|
1603
1657
|
});
|
|
1604
1658
|
const { files, failedPlugins, pluginTimings, error, driver } = await kubb.safeBuild();
|
|
1605
1659
|
await hooks.emit("kubb:info", { message: "Load summary" });
|
|
1660
|
+
const telemetryPlugins = Array.from(driver.plugins.values(), (p) => ({
|
|
1661
|
+
name: p.name,
|
|
1662
|
+
options: p.options
|
|
1663
|
+
}));
|
|
1664
|
+
const reportTelemetry = (status) => sendTelemetry(buildTelemetryEvent({
|
|
1665
|
+
command: "generate",
|
|
1666
|
+
kubbVersion: version,
|
|
1667
|
+
plugins: telemetryPlugins,
|
|
1668
|
+
hrStart,
|
|
1669
|
+
filesCreated: files.length,
|
|
1670
|
+
status
|
|
1671
|
+
}));
|
|
1606
1672
|
if (failedPlugins.size > 0 || error) {
|
|
1607
|
-
const allErrors = [error, ...Array.from(failedPlugins
|
|
1673
|
+
const allErrors = [error, ...Array.from(failedPlugins, (it) => it.error)].filter(Boolean);
|
|
1608
1674
|
for (const err of allErrors) await hooks.emit("kubb:error", { error: err });
|
|
1609
1675
|
await hooks.emit("kubb:generation:end", {
|
|
1610
1676
|
config,
|
|
1611
|
-
|
|
1612
|
-
sources: kubb.sources
|
|
1677
|
+
storage: kubb.storage
|
|
1613
1678
|
});
|
|
1614
1679
|
await hooks.emit("kubb:generation:summary", {
|
|
1615
1680
|
config,
|
|
@@ -1619,62 +1684,51 @@ async function generate(options) {
|
|
|
1619
1684
|
hrStart,
|
|
1620
1685
|
pluginTimings: logLevel$2 >= logLevel.verbose ? pluginTimings : void 0
|
|
1621
1686
|
});
|
|
1622
|
-
await
|
|
1623
|
-
|
|
1624
|
-
kubbVersion: version,
|
|
1625
|
-
plugins: Array.from(driver.plugins.values(), (p) => ({
|
|
1626
|
-
name: p.name,
|
|
1627
|
-
options: p.options
|
|
1628
|
-
})),
|
|
1629
|
-
hrStart,
|
|
1630
|
-
filesCreated: files.length,
|
|
1631
|
-
status: "failed"
|
|
1632
|
-
}));
|
|
1633
|
-
process$1.exit(1);
|
|
1687
|
+
await reportTelemetry("failed");
|
|
1688
|
+
return false;
|
|
1634
1689
|
}
|
|
1635
1690
|
await hooks.emit("kubb:success", {
|
|
1636
|
-
message: "Generation
|
|
1691
|
+
message: "Generation succeeded",
|
|
1637
1692
|
info: inputPath
|
|
1638
1693
|
});
|
|
1639
1694
|
await hooks.emit("kubb:generation:end", {
|
|
1640
1695
|
config,
|
|
1641
|
-
|
|
1642
|
-
sources: kubb.sources
|
|
1696
|
+
storage: kubb.storage
|
|
1643
1697
|
});
|
|
1644
1698
|
const outputPath = path.resolve(config.root, config.output.path);
|
|
1645
|
-
|
|
1699
|
+
const toolPasses = [config.output.format && {
|
|
1646
1700
|
toolValue: config.output.format,
|
|
1647
1701
|
detect: detectFormatter,
|
|
1648
1702
|
toolMap: formatters,
|
|
1649
1703
|
toolLabel: "formatter",
|
|
1650
1704
|
successPrefix: "Formatting",
|
|
1651
1705
|
noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
|
|
1652
|
-
configName: config.name,
|
|
1653
|
-
outputPath,
|
|
1654
|
-
logLevel: logLevel$2,
|
|
1655
|
-
hooks,
|
|
1656
1706
|
onStart: () => hooks.emit("kubb:format:start"),
|
|
1657
1707
|
onEnd: () => hooks.emit("kubb:format:end")
|
|
1658
|
-
}
|
|
1659
|
-
if (config.output.lint) await runToolPass({
|
|
1708
|
+
}, config.output.lint && {
|
|
1660
1709
|
toolValue: config.output.lint,
|
|
1661
1710
|
detect: detectLinter,
|
|
1662
1711
|
toolMap: linters,
|
|
1663
1712
|
toolLabel: "linter",
|
|
1664
1713
|
successPrefix: "Linting",
|
|
1665
1714
|
noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
|
|
1715
|
+
onStart: () => hooks.emit("kubb:lint:start"),
|
|
1716
|
+
onEnd: () => hooks.emit("kubb:lint:end")
|
|
1717
|
+
}].filter(Boolean);
|
|
1718
|
+
for (const pass of toolPasses) await runToolPass({
|
|
1719
|
+
...pass,
|
|
1666
1720
|
configName: config.name,
|
|
1667
1721
|
outputPath,
|
|
1668
1722
|
logLevel: logLevel$2,
|
|
1669
1723
|
hooks,
|
|
1670
|
-
|
|
1671
|
-
onEnd: () => hooks.emit("kubb:lint:end")
|
|
1724
|
+
makeSink
|
|
1672
1725
|
});
|
|
1673
1726
|
if (config.hooks) {
|
|
1674
1727
|
await hooks.emit("kubb:hooks:start");
|
|
1675
1728
|
await executeHooks({
|
|
1676
1729
|
configHooks: config.hooks,
|
|
1677
|
-
hooks
|
|
1730
|
+
hooks,
|
|
1731
|
+
makeSink
|
|
1678
1732
|
});
|
|
1679
1733
|
await hooks.emit("kubb:hooks:end");
|
|
1680
1734
|
}
|
|
@@ -1686,68 +1740,82 @@ async function generate(options) {
|
|
|
1686
1740
|
hrStart,
|
|
1687
1741
|
pluginTimings
|
|
1688
1742
|
});
|
|
1689
|
-
await
|
|
1690
|
-
|
|
1691
|
-
kubbVersion: version,
|
|
1692
|
-
plugins: Array.from(driver.plugins.values(), (p) => ({
|
|
1693
|
-
name: p.name,
|
|
1694
|
-
options: p.options
|
|
1695
|
-
})),
|
|
1696
|
-
hrStart,
|
|
1697
|
-
filesCreated: files.length,
|
|
1698
|
-
status: "success"
|
|
1699
|
-
}));
|
|
1743
|
+
await reportTelemetry("success");
|
|
1744
|
+
return true;
|
|
1700
1745
|
}
|
|
1701
|
-
async function
|
|
1702
|
-
const logLevel$3 = logLevel[logLevelKey] ?? logLevel.info;
|
|
1703
|
-
const hooks = new AsyncEventEmitter();
|
|
1704
|
-
await setupLogger(hooks, { logLevel: logLevel$3 });
|
|
1746
|
+
async function checkForUpdate(hooks) {
|
|
1705
1747
|
await executeIfOnline(async () => {
|
|
1706
1748
|
try {
|
|
1707
|
-
const
|
|
1708
|
-
if (
|
|
1749
|
+
const data = await (await fetch(KUBB_NPM_PACKAGE_URL)).json();
|
|
1750
|
+
if (data.version && version < data.version) await hooks.emit("kubb:version:new", {
|
|
1709
1751
|
currentVersion: version,
|
|
1710
|
-
latestVersion
|
|
1752
|
+
latestVersion: data.version
|
|
1711
1753
|
});
|
|
1712
1754
|
} catch {}
|
|
1713
1755
|
});
|
|
1756
|
+
}
|
|
1757
|
+
/**
|
|
1758
|
+
* Runs the full Kubb generation lifecycle for the given CLI options.
|
|
1759
|
+
* Sets up the logger, checks for a newer version, loads configs, and calls `generate` for each config entry.
|
|
1760
|
+
*/
|
|
1761
|
+
async function run({ input, configPath, logLevel: logLevelKey, watch }) {
|
|
1762
|
+
const logLevel$3 = logLevel[logLevelKey] ?? logLevel.info;
|
|
1763
|
+
const hooks = new AsyncEventEmitter();
|
|
1764
|
+
const makeSink = await setupLogger(hooks, { logLevel: logLevel$3 });
|
|
1765
|
+
await hooks.emit("kubb:lifecycle:start", { version });
|
|
1766
|
+
await checkForUpdate(hooks);
|
|
1714
1767
|
try {
|
|
1715
|
-
const result = await getCosmiConfig("kubb", configPath);
|
|
1716
|
-
const configs = await getConfigs(result.config, { input });
|
|
1717
1768
|
await hooks.emit("kubb:config:start");
|
|
1769
|
+
const { configs, configPath: resolvedConfigPath } = await getConfigs({
|
|
1770
|
+
configPath,
|
|
1771
|
+
input,
|
|
1772
|
+
watch,
|
|
1773
|
+
logLevel: logLevelKey
|
|
1774
|
+
});
|
|
1775
|
+
const relativeConfigPath = path.relative(process$1.cwd(), resolvedConfigPath);
|
|
1718
1776
|
await hooks.emit("kubb:info", {
|
|
1719
1777
|
message: "Config loaded",
|
|
1720
|
-
info:
|
|
1778
|
+
info: relativeConfigPath
|
|
1721
1779
|
});
|
|
1722
1780
|
await hooks.emit("kubb:success", {
|
|
1723
1781
|
message: "Config loaded successfully",
|
|
1724
|
-
info:
|
|
1782
|
+
info: relativeConfigPath
|
|
1725
1783
|
});
|
|
1726
1784
|
await hooks.emit("kubb:config:end", { configs });
|
|
1727
|
-
|
|
1785
|
+
let anyFailed = false;
|
|
1728
1786
|
for (const config of configs) if (isInputPath(config) && watch) await startWatcher([input || config.input.path], async (paths) => {
|
|
1729
|
-
hooks.removeAll();
|
|
1730
1787
|
await generate({
|
|
1731
1788
|
input,
|
|
1732
1789
|
config,
|
|
1733
1790
|
logLevel: logLevel$3,
|
|
1734
|
-
hooks
|
|
1791
|
+
hooks,
|
|
1792
|
+
makeSink
|
|
1735
1793
|
});
|
|
1736
1794
|
clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
1795
|
+
}, {
|
|
1796
|
+
info: (msg) => clack.log.info(msg),
|
|
1797
|
+
error: (msg) => clack.log.error(msg)
|
|
1737
1798
|
});
|
|
1738
|
-
else
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1799
|
+
else try {
|
|
1800
|
+
if (!await generate({
|
|
1801
|
+
input,
|
|
1802
|
+
config,
|
|
1803
|
+
logLevel: logLevel$3,
|
|
1804
|
+
hooks,
|
|
1805
|
+
makeSink
|
|
1806
|
+
})) anyFailed = true;
|
|
1807
|
+
} catch (configError) {
|
|
1808
|
+
await hooks.emit("kubb:error", { error: toError(configError) });
|
|
1809
|
+
anyFailed = true;
|
|
1810
|
+
}
|
|
1744
1811
|
await hooks.emit("kubb:lifecycle:end");
|
|
1812
|
+
if (anyFailed) process$1.exit(1);
|
|
1745
1813
|
} catch (error) {
|
|
1746
1814
|
await hooks.emit("kubb:error", { error: toError(error) });
|
|
1747
1815
|
process$1.exit(1);
|
|
1748
1816
|
}
|
|
1749
1817
|
}
|
|
1750
1818
|
//#endregion
|
|
1751
|
-
export {
|
|
1819
|
+
export { run };
|
|
1752
1820
|
|
|
1753
|
-
//# sourceMappingURL=
|
|
1821
|
+
//# sourceMappingURL=run-BgM41TQT.js.map
|