@kubb/cli 4.32.4 → 4.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-Bd1QdPVV.cjs +91 -0
- package/dist/agent-Bd1QdPVV.cjs.map +1 -0
- package/dist/agent-D83d9Pud.cjs +60 -0
- package/dist/agent-D83d9Pud.cjs.map +1 -0
- package/dist/agent-DgKQXSmR.js +57 -0
- package/dist/agent-DgKQXSmR.js.map +1 -0
- package/dist/agent-u_Ehwz6r.js +87 -0
- package/dist/agent-u_Ehwz6r.js.map +1 -0
- package/dist/constants-BTUap0zs.cjs +108 -0
- package/dist/constants-BTUap0zs.cjs.map +1 -0
- package/dist/constants-CM3dJzjK.js +67 -0
- package/dist/constants-CM3dJzjK.js.map +1 -0
- package/dist/define--M_JMcDC.js +25 -0
- package/dist/define--M_JMcDC.js.map +1 -0
- package/dist/define-D6Kfm7-Z.cjs +36 -0
- package/dist/define-D6Kfm7-Z.cjs.map +1 -0
- package/dist/errors-6mF_WKxg.js +27 -0
- package/dist/errors-6mF_WKxg.js.map +1 -0
- package/dist/errors-DBW0N9w4.cjs +44 -0
- package/dist/errors-DBW0N9w4.cjs.map +1 -0
- package/dist/generate-Bn8n4w1O.cjs +65 -0
- package/dist/generate-Bn8n4w1O.cjs.map +1 -0
- package/dist/{generate-CpWtSc45.js → generate-CAsV9wSx.js} +656 -689
- package/dist/generate-CAsV9wSx.js.map +1 -0
- package/dist/generate-D-59YK0L.js +66 -0
- package/dist/generate-D-59YK0L.js.map +1 -0
- package/dist/{generate-COj0aMS6.cjs → generate-JC65igQh.cjs} +662 -694
- package/dist/generate-JC65igQh.cjs.map +1 -0
- package/dist/index.cjs +226 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +226 -35
- package/dist/index.js.map +1 -1
- package/dist/init-C-InrmSY.js +302 -0
- package/dist/init-C-InrmSY.js.map +1 -0
- package/dist/init-CXP8OfMe.js +25 -0
- package/dist/init-CXP8OfMe.js.map +1 -0
- package/dist/init-CbeE-L-0.cjs +25 -0
- package/dist/init-CbeE-L-0.cjs.map +1 -0
- package/dist/init-hmolV6B4.cjs +306 -0
- package/dist/init-hmolV6B4.cjs.map +1 -0
- package/dist/jiti-Cd3S0xwr.cjs +16 -0
- package/dist/jiti-Cd3S0xwr.cjs.map +1 -0
- package/dist/jiti-e08mD2Ph.js +11 -0
- package/dist/jiti-e08mD2Ph.js.map +1 -0
- package/dist/mcp-BDxg2oJm.cjs +16 -0
- package/dist/mcp-BDxg2oJm.cjs.map +1 -0
- package/dist/mcp-ChHFPRzD.cjs +42 -0
- package/dist/mcp-ChHFPRzD.cjs.map +1 -0
- package/dist/mcp-D2SHEg_d.js +41 -0
- package/dist/mcp-D2SHEg_d.js.map +1 -0
- package/dist/mcp-MSoE4vNA.js +16 -0
- package/dist/mcp-MSoE4vNA.js.map +1 -0
- package/dist/{package-aNQWvWbS.cjs → package-CUVyeIbt.cjs} +2 -2
- package/dist/package-CUVyeIbt.cjs.map +1 -0
- package/dist/package-Cbd8OC6q.js +6 -0
- package/dist/package-Cbd8OC6q.js.map +1 -0
- package/dist/shell-7HPrTCJ5.cjs +57 -0
- package/dist/shell-7HPrTCJ5.cjs.map +1 -0
- package/dist/shell-DqqWsHCD.js +46 -0
- package/dist/shell-DqqWsHCD.js.map +1 -0
- package/dist/{telemetry-BDSSqUiG.cjs → telemetry-Cn9X1I5B.cjs} +79 -9
- package/dist/telemetry-Cn9X1I5B.cjs.map +1 -0
- package/dist/{telemetry-DYWvlxqs.js → telemetry-DxiR7clS.js} +63 -11
- package/dist/telemetry-DxiR7clS.js.map +1 -0
- package/dist/validate-BG8A3aQS.cjs +25 -0
- package/dist/validate-BG8A3aQS.cjs.map +1 -0
- package/dist/validate-BZ1UFkwA.js +25 -0
- package/dist/validate-BZ1UFkwA.js.map +1 -0
- package/dist/validate-Bbrn3Q-A.cjs +42 -0
- package/dist/validate-Bbrn3Q-A.cjs.map +1 -0
- package/dist/validate-l8vLmwKA.js +41 -0
- package/dist/validate-l8vLmwKA.js.map +1 -0
- package/package.json +6 -6
- package/src/commands/agent/start.ts +27 -136
- package/src/commands/agent.ts +6 -25
- package/src/commands/generate.ts +26 -158
- package/src/commands/init.ts +9 -360
- package/src/commands/mcp.ts +7 -52
- package/src/commands/validate.ts +9 -60
- package/src/constants.ts +76 -0
- package/src/index.ts +36 -42
- package/src/loggers/clackLogger.ts +65 -165
- package/src/loggers/fileSystemLogger.ts +2 -14
- package/src/loggers/githubActionsLogger.ts +58 -125
- package/src/loggers/plainLogger.ts +44 -92
- package/src/loggers/utils.ts +67 -4
- package/src/runners/agent.ts +100 -0
- package/src/runners/generate.ts +223 -102
- package/src/runners/init.ts +323 -0
- package/src/runners/mcp.ts +32 -0
- package/src/runners/validate.ts +35 -0
- package/src/utils/Writables.ts +2 -2
- package/src/utils/executeHooks.ts +20 -8
- package/src/utils/getCosmiConfig.ts +10 -11
- package/src/utils/getIntro.ts +1 -81
- package/src/utils/getSummary.ts +12 -17
- package/src/utils/jiti.ts +9 -0
- package/src/utils/packageManager.ts +4 -4
- package/src/utils/runHook.ts +75 -0
- package/src/utils/telemetry.ts +8 -26
- package/src/utils/watcher.ts +2 -4
- package/dist/agent-6COck3B9.cjs +0 -20
- package/dist/agent-6COck3B9.cjs.map +0 -1
- package/dist/agent-DMm6c5Vg.js +0 -20
- package/dist/agent-DMm6c5Vg.js.map +0 -1
- package/dist/generate-COj0aMS6.cjs.map +0 -1
- package/dist/generate-CpWtSc45.js.map +0 -1
- package/dist/init-Bdn3_qir.js +0 -304
- package/dist/init-Bdn3_qir.js.map +0 -1
- package/dist/init-CFW2kWY8.cjs +0 -308
- package/dist/init-CFW2kWY8.cjs.map +0 -1
- package/dist/mcp-DkwtARfo.cjs +0 -57
- package/dist/mcp-DkwtARfo.cjs.map +0 -1
- package/dist/mcp-DrH93Vq4.js +0 -57
- package/dist/mcp-DrH93Vq4.js.map +0 -1
- package/dist/package-BnJbGmLm.js +0 -6
- package/dist/package-BnJbGmLm.js.map +0 -1
- package/dist/package-aNQWvWbS.cjs.map +0 -1
- package/dist/start-CqTUu14n.js +0 -131
- package/dist/start-CqTUu14n.js.map +0 -1
- package/dist/start-D-rsIJGo.cjs +0 -134
- package/dist/start-D-rsIJGo.cjs.map +0 -1
- package/dist/telemetry-BDSSqUiG.cjs.map +0 -1
- package/dist/telemetry-DYWvlxqs.js.map +0 -1
- package/dist/validate-BlV8L8gC.js +0 -66
- package/dist/validate-BlV8L8gC.js.map +0 -1
- package/dist/validate-COhZUXF8.cjs +0 -66
- package/dist/validate-COhZUXF8.cjs.map +0 -1
- package/src/loggers/envDetection.ts +0 -28
- package/src/loggers/index.ts +0 -5
- package/src/utils/formatMsWithColor.ts +0 -22
- package/src/utils/randomColor.ts +0 -23
|
@@ -1,76 +1,143 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
|
-
import {
|
|
3
|
-
import { r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-
|
|
2
|
+
import { n as toCause, r as toError } from "./errors-6mF_WKxg.js";
|
|
3
|
+
import { a as canUseTTY, i as executeIfOnline, o as isGitHubActions, r as sendTelemetry, t as buildTelemetryEvent } from "./telemetry-DxiR7clS.js";
|
|
4
|
+
import { n as tokenize } from "./shell-DqqWsHCD.js";
|
|
5
|
+
import { t as version } from "./package-Cbd8OC6q.js";
|
|
6
|
+
import { i as WATCHER_IGNORED_PATHS, r as SUMMARY_SEPARATOR, t as KUBB_NPM_PACKAGE_URL } from "./constants-CM3dJzjK.js";
|
|
4
7
|
import { styleText } from "node:util";
|
|
5
|
-
import {
|
|
8
|
+
import { EventEmitter } from "node:events";
|
|
6
9
|
import { createHash } from "node:crypto";
|
|
7
|
-
import
|
|
10
|
+
import "node:fs";
|
|
11
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
12
|
+
import path, { dirname, relative, resolve } from "node:path";
|
|
8
13
|
import process$1 from "node:process";
|
|
9
|
-
import { AsyncEventEmitter, detectFormatter, detectLinter, executeIfOnline, formatHrtime, formatMs, formatters, getConfigs, linters, tokenize } from "@kubb/core/utils";
|
|
10
|
-
import path, { relative, resolve } from "node:path";
|
|
11
14
|
import * as clack from "@clack/prompts";
|
|
12
|
-
import {
|
|
13
|
-
import { x } from "tinyexec";
|
|
15
|
+
import { PromiseManager, defineLogger, detectFormatter, detectLinter, formatters, getConfigs, isInputPath, linters, logLevel, safeBuild, setup } from "@kubb/core";
|
|
16
|
+
import { NonZeroExitError, x } from "tinyexec";
|
|
14
17
|
import { Writable } from "node:stream";
|
|
15
|
-
import { write } from "@kubb/core/fs";
|
|
16
18
|
import { cosmiconfig } from "cosmiconfig";
|
|
17
19
|
import { createJiti } from "jiti";
|
|
18
|
-
//#region
|
|
20
|
+
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
19
21
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* - Yellow: > 500ms and <= 1000ms
|
|
23
|
-
* - Red: > 1000ms
|
|
22
|
+
* A typed EventEmitter that awaits all async listeners before resolving.
|
|
23
|
+
* Wraps Node's `EventEmitter` with full TypeScript event-map inference.
|
|
24
24
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
var AsyncEventEmitter = class {
|
|
26
|
+
/**
|
|
27
|
+
* `maxListener` controls the maximum number of listeners per event before Node emits a memory-leak warning.
|
|
28
|
+
* @default 10
|
|
29
|
+
*/
|
|
30
|
+
constructor(maxListener = 10) {
|
|
31
|
+
this.#emitter.setMaxListeners(maxListener);
|
|
32
|
+
}
|
|
33
|
+
#emitter = new EventEmitter();
|
|
34
|
+
/**
|
|
35
|
+
* Emits an event and awaits all registered listeners in parallel.
|
|
36
|
+
* Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
|
|
37
|
+
*/
|
|
38
|
+
async emit(eventName, ...eventArgs) {
|
|
39
|
+
const listeners = this.#emitter.listeners(eventName);
|
|
40
|
+
if (listeners.length === 0) return;
|
|
41
|
+
await Promise.all(listeners.map(async (listener) => {
|
|
42
|
+
try {
|
|
43
|
+
return await listener(...eventArgs);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
let serializedArgs;
|
|
46
|
+
try {
|
|
47
|
+
serializedArgs = JSON.stringify(eventArgs);
|
|
48
|
+
} catch {
|
|
49
|
+
serializedArgs = String(eventArgs);
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
/** Registers a persistent listener for the given event. */
|
|
56
|
+
on(eventName, handler) {
|
|
57
|
+
this.#emitter.on(eventName, handler);
|
|
58
|
+
}
|
|
59
|
+
/** Registers a one-shot listener that removes itself after the first invocation. */
|
|
60
|
+
onOnce(eventName, handler) {
|
|
61
|
+
const wrapper = (...args) => {
|
|
62
|
+
this.off(eventName, wrapper);
|
|
63
|
+
return handler(...args);
|
|
64
|
+
};
|
|
65
|
+
this.on(eventName, wrapper);
|
|
66
|
+
}
|
|
67
|
+
/** Removes a previously registered listener. */
|
|
68
|
+
off(eventName, handler) {
|
|
69
|
+
this.#emitter.off(eventName, handler);
|
|
70
|
+
}
|
|
71
|
+
/** Removes all listeners from every event channel. */
|
|
72
|
+
removeAll() {
|
|
73
|
+
this.#emitter.removeAllListeners();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
31
76
|
//#endregion
|
|
32
|
-
//#region
|
|
77
|
+
//#region ../../internals/utils/src/time.ts
|
|
78
|
+
/**
|
|
79
|
+
* Calculates elapsed time in milliseconds from a high-resolution start time.
|
|
80
|
+
* Rounds to 2 decimal places to provide sub-millisecond precision without noise.
|
|
81
|
+
*/
|
|
82
|
+
function getElapsedMs(hrStart) {
|
|
83
|
+
const [seconds, nanoseconds] = process.hrtime(hrStart);
|
|
84
|
+
const ms = seconds * 1e3 + nanoseconds / 1e6;
|
|
85
|
+
return Math.round(ms * 100) / 100;
|
|
86
|
+
}
|
|
33
87
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
88
|
+
* Converts a millisecond duration into a human-readable string.
|
|
89
|
+
* Adjusts units (ms, s, m s) based on the magnitude of the duration.
|
|
36
90
|
*/
|
|
91
|
+
function formatMs(ms) {
|
|
92
|
+
if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
|
|
93
|
+
if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
|
|
94
|
+
return `${Math.round(ms)}ms`;
|
|
95
|
+
}
|
|
37
96
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @param color - Hex color code (with or without #), e.g., '#FF5500' or 'FF5500'
|
|
40
|
-
* @returns Function that wraps text with the color
|
|
97
|
+
* Convenience helper: formats the elapsed time since `hrStart` in one step.
|
|
41
98
|
*/
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
const r = Number.parseInt(cleanHex.slice(0, 2), 16);
|
|
45
|
-
const g = Number.parseInt(cleanHex.slice(2, 4), 16);
|
|
46
|
-
const b = Number.parseInt(cleanHex.slice(4, 6), 16);
|
|
47
|
-
const safeR = Number.isNaN(r) ? 255 : r;
|
|
48
|
-
const safeG = Number.isNaN(g) ? 255 : g;
|
|
49
|
-
const safeB = Number.isNaN(b) ? 255 : b;
|
|
50
|
-
return (text) => `\x1b[38;2;${safeR};${safeG};${safeB}m${text}\x1b[0m`;
|
|
99
|
+
function formatHrtime(hrStart) {
|
|
100
|
+
return formatMs(getElapsedMs(hrStart));
|
|
51
101
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region ../../internals/utils/src/colors.ts
|
|
104
|
+
/**
|
|
105
|
+
* Parses a CSS hex color string (`#RGB`) into its RGB channels.
|
|
106
|
+
* Falls back to `255` for any channel that cannot be parsed.
|
|
107
|
+
*/
|
|
108
|
+
function parseHex(color) {
|
|
109
|
+
const int = Number.parseInt(color.replace("#", ""), 16);
|
|
110
|
+
return Number.isNaN(int) ? {
|
|
111
|
+
r: 255,
|
|
112
|
+
g: 255,
|
|
113
|
+
b: 255
|
|
114
|
+
} : {
|
|
115
|
+
r: int >> 16 & 255,
|
|
116
|
+
g: int >> 8 & 255,
|
|
117
|
+
b: int & 255
|
|
58
118
|
};
|
|
59
119
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const from = hexToRgb(colors[seg]);
|
|
68
|
-
const to = hexToRgb(colors[seg + 1]);
|
|
69
|
-
return `\x1b[38;2;${Math.round(from.r + (to.r - from.r) * lt)};${Math.round(from.g + (to.g - from.g) * lt)};${Math.round(from.b + (to.b - from.b) * lt)}m${char}\x1b[0m`;
|
|
70
|
-
}).join("");
|
|
71
|
-
};
|
|
120
|
+
/**
|
|
121
|
+
* Returns a function that wraps a string in a 24-bit ANSI true-color escape sequence
|
|
122
|
+
* for the given hex color.
|
|
123
|
+
*/
|
|
124
|
+
function hex(color) {
|
|
125
|
+
const { r, g, b } = parseHex(color);
|
|
126
|
+
return (text) => `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
|
|
72
127
|
}
|
|
73
|
-
|
|
128
|
+
function gradient(colorStops, text) {
|
|
129
|
+
const chars = text.split("");
|
|
130
|
+
return chars.map((char, i) => {
|
|
131
|
+
const t = chars.length <= 1 ? 0 : i / (chars.length - 1);
|
|
132
|
+
const seg = Math.min(Math.floor(t * (colorStops.length - 1)), colorStops.length - 2);
|
|
133
|
+
const lt = t * (colorStops.length - 1) - seg;
|
|
134
|
+
const from = parseHex(colorStops[seg]);
|
|
135
|
+
const to = parseHex(colorStops[seg + 1]);
|
|
136
|
+
return `\x1b[38;2;${Math.round(from.r + (to.r - from.r) * lt)};${Math.round(from.g + (to.g - from.g) * lt)};${Math.round(from.b + (to.b - from.b) * lt)}m${char}\x1b[0m`;
|
|
137
|
+
}).join("");
|
|
138
|
+
}
|
|
139
|
+
/** ANSI color functions for each part of the Kubb mascot illustration. */
|
|
140
|
+
const palette = {
|
|
74
141
|
lid: hex("#F55A17"),
|
|
75
142
|
woodTop: hex("#F5A217"),
|
|
76
143
|
woodMid: hex("#F58517"),
|
|
@@ -80,57 +147,94 @@ const colors = {
|
|
|
80
147
|
blush: hex("#FDA4AF")
|
|
81
148
|
};
|
|
82
149
|
/**
|
|
83
|
-
* Generates the Kubb mascot
|
|
84
|
-
* @param version - The version string to display
|
|
85
|
-
* @returns Formatted mascot face string
|
|
150
|
+
* Generates the Kubb mascot welcome banner.
|
|
86
151
|
*/
|
|
87
152
|
function getIntro({ title, description, version, areEyesOpen }) {
|
|
88
153
|
const kubbVersion = gradient([
|
|
89
154
|
"#F58517",
|
|
90
155
|
"#F5A217",
|
|
91
156
|
"#F55A17"
|
|
92
|
-
]
|
|
93
|
-
const eyeTop = areEyesOpen ?
|
|
94
|
-
const eyeBottom = areEyesOpen ?
|
|
157
|
+
], `KUBB v${version}`);
|
|
158
|
+
const eyeTop = areEyesOpen ? palette.eye("█▀█") : palette.eye("───");
|
|
159
|
+
const eyeBottom = areEyesOpen ? palette.eye("▀▀▀") : palette.eye("───");
|
|
95
160
|
return `
|
|
96
|
-
${
|
|
97
|
-
${
|
|
98
|
-
${
|
|
99
|
-
${
|
|
100
|
-
${
|
|
161
|
+
${palette.lid("▄▄▄▄▄▄▄▄▄▄▄▄▄")}
|
|
162
|
+
${palette.woodTop("█ ")}${palette.highlight("▄▄")}${palette.woodTop(" ")}${palette.highlight("▄▄")}${palette.woodTop(" █")} ${kubbVersion}
|
|
163
|
+
${palette.woodMid("█ ")}${eyeTop}${palette.woodMid(" ")}${eyeTop}${palette.woodMid(" █")} ${styleText("gray", title)}
|
|
164
|
+
${palette.woodMid("█ ")}${eyeBottom}${palette.woodMid(" ")}${palette.blush("◡")}${palette.woodMid(" ")}${eyeBottom}${palette.woodMid(" █")} ${styleText("yellow", "➜")} ${styleText("white", description)}
|
|
165
|
+
${palette.woodBase("▀▀▀▀▀▀▀▀▀▀▀▀▀")}
|
|
101
166
|
`;
|
|
102
167
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
];
|
|
119
|
-
return defaultColors[createHash("sha256").update(text).digest().readUInt32BE(0) % defaultColors.length] ?? "white";
|
|
120
|
-
}
|
|
168
|
+
/** ANSI color names available for terminal output. */
|
|
169
|
+
const randomColors = [
|
|
170
|
+
"black",
|
|
171
|
+
"red",
|
|
172
|
+
"green",
|
|
173
|
+
"yellow",
|
|
174
|
+
"blue",
|
|
175
|
+
"white",
|
|
176
|
+
"magenta",
|
|
177
|
+
"cyan",
|
|
178
|
+
"gray"
|
|
179
|
+
];
|
|
180
|
+
/**
|
|
181
|
+
* Returns the text wrapped in a deterministic ANSI color derived from the text's SHA-256 hash.
|
|
182
|
+
*/
|
|
121
183
|
function randomCliColor(text) {
|
|
122
184
|
if (!text) return "";
|
|
123
|
-
return styleText(
|
|
185
|
+
return styleText(randomColors[createHash("sha256").update(text).digest().readUInt32BE(0) % randomColors.length] ?? "white", text);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Formats a millisecond duration with an ANSI color based on thresholds:
|
|
189
|
+
* green ≤ 500 ms · yellow ≤ 1 000 ms · red > 1 000 ms
|
|
190
|
+
*/
|
|
191
|
+
function formatMsWithColor(ms) {
|
|
192
|
+
const formatted = formatMs(ms);
|
|
193
|
+
if (ms <= 500) return styleText("green", formatted);
|
|
194
|
+
if (ms <= 1e3) return styleText("yellow", formatted);
|
|
195
|
+
return styleText("red", formatted);
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region ../../internals/utils/src/fs.ts
|
|
199
|
+
/**
|
|
200
|
+
* Writes `data` to `path`, trimming leading/trailing whitespace before saving.
|
|
201
|
+
* Skips the write and returns `undefined` when the trimmed content is empty or
|
|
202
|
+
* identical to what is already on disk.
|
|
203
|
+
* Creates any missing parent directories automatically.
|
|
204
|
+
* When `sanity` is `true`, re-reads the file after writing and throws if the
|
|
205
|
+
* content does not match — useful for catching write failures on unreliable file systems.
|
|
206
|
+
*/
|
|
207
|
+
async function write(path, data, options = {}) {
|
|
208
|
+
const trimmed = data.trim();
|
|
209
|
+
if (trimmed === "") return void 0;
|
|
210
|
+
const resolved = resolve(path);
|
|
211
|
+
if (typeof Bun !== "undefined") {
|
|
212
|
+
const file = Bun.file(resolved);
|
|
213
|
+
if ((await file.exists() ? await file.text() : null) === trimmed) return void 0;
|
|
214
|
+
await Bun.write(resolved, trimmed);
|
|
215
|
+
return trimmed;
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
if (await readFile(resolved, { encoding: "utf-8" }) === trimmed) return void 0;
|
|
219
|
+
} catch {}
|
|
220
|
+
await mkdir(dirname(resolved), { recursive: true });
|
|
221
|
+
await writeFile(resolved, trimmed, { encoding: "utf-8" });
|
|
222
|
+
if (options.sanity) {
|
|
223
|
+
const savedData = await readFile(resolved, { encoding: "utf-8" });
|
|
224
|
+
if (savedData !== trimmed) throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`);
|
|
225
|
+
return savedData;
|
|
226
|
+
}
|
|
227
|
+
return trimmed;
|
|
124
228
|
}
|
|
125
229
|
//#endregion
|
|
126
230
|
//#region src/utils/getSummary.ts
|
|
127
231
|
function getSummary({ failedPlugins, filesCreated, status, hrStart, config, pluginTimings }) {
|
|
128
232
|
const duration = formatHrtime(hrStart);
|
|
129
|
-
const pluginsCount = config.plugins?.length
|
|
233
|
+
const pluginsCount = config.plugins?.length ?? 0;
|
|
130
234
|
const successCount = pluginsCount - failedPlugins.size;
|
|
131
235
|
const meta = {
|
|
132
236
|
plugins: status === "success" ? `${styleText("green", `${successCount} successful`)}, ${pluginsCount} total` : `${styleText("green", `${successCount} successful`)}, ${styleText("red", `${failedPlugins.size} failed`)}, ${pluginsCount} total`,
|
|
133
|
-
pluginsFailed: status === "failed" ? [...failedPlugins]
|
|
237
|
+
pluginsFailed: status === "failed" ? [...failedPlugins].map(({ plugin }) => randomCliColor(plugin.name)).join(", ") : void 0,
|
|
134
238
|
filesCreated,
|
|
135
239
|
time: styleText("green", duration),
|
|
136
240
|
output: path.isAbsolute(config.root) ? path.resolve(config.root, config.output.path) : config.root
|
|
@@ -148,23 +252,76 @@ function getSummary({ failedPlugins, filesCreated, status, hrStart, config, plug
|
|
|
148
252
|
if (meta.pluginsFailed) summaryLines.push(`${labels.failed.padEnd(maxLength + 2)} ${meta.pluginsFailed}`);
|
|
149
253
|
summaryLines.push(`${labels.generated.padEnd(maxLength + 2)} ${meta.filesCreated} files in ${meta.time}`);
|
|
150
254
|
if (pluginTimings && pluginTimings.size > 0) {
|
|
151
|
-
const TIME_SCALE_DIVISOR = 100;
|
|
152
|
-
const MAX_BAR_LENGTH = 10;
|
|
153
255
|
const sortedTimings = Array.from(pluginTimings.entries()).sort((a, b) => b[1] - a[1]);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
162
|
-
}
|
|
256
|
+
summaryLines.push(`${labels.pluginTimings}`);
|
|
257
|
+
sortedTimings.forEach(([name, time]) => {
|
|
258
|
+
const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
|
|
259
|
+
const barLength = Math.min(Math.ceil(time / 100), 10);
|
|
260
|
+
const bar = styleText("dim", "█".repeat(barLength));
|
|
261
|
+
summaryLines.push(`${styleText("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
|
|
262
|
+
});
|
|
163
263
|
}
|
|
164
264
|
summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
|
|
165
265
|
return summaryLines;
|
|
166
266
|
}
|
|
167
267
|
//#endregion
|
|
268
|
+
//#region src/utils/runHook.ts
|
|
269
|
+
/**
|
|
270
|
+
* Execute a hook command, emit debug/hook:end events, and forward output to
|
|
271
|
+
* an optional HookOutputSink. All three logger adapters share this function
|
|
272
|
+
* so the process-spawning logic lives in exactly one place.
|
|
273
|
+
*/
|
|
274
|
+
async function runHook({ id, command, args, commandWithArgs, context, stream = false, sink }) {
|
|
275
|
+
try {
|
|
276
|
+
const proc = x(command, [...args ?? []], {
|
|
277
|
+
nodeOptions: { detached: true },
|
|
278
|
+
throwOnError: true
|
|
279
|
+
});
|
|
280
|
+
if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
|
|
281
|
+
const result = await proc;
|
|
282
|
+
await context.emit("debug", {
|
|
283
|
+
date: /* @__PURE__ */ new Date(),
|
|
284
|
+
logs: [result.stdout.trimEnd()]
|
|
285
|
+
});
|
|
286
|
+
await context.emit("hook:end", {
|
|
287
|
+
command,
|
|
288
|
+
args,
|
|
289
|
+
id,
|
|
290
|
+
success: true,
|
|
291
|
+
error: null
|
|
292
|
+
});
|
|
293
|
+
} catch (err) {
|
|
294
|
+
if (!(err instanceof NonZeroExitError)) {
|
|
295
|
+
await context.emit("hook:end", {
|
|
296
|
+
command,
|
|
297
|
+
args,
|
|
298
|
+
id,
|
|
299
|
+
success: false,
|
|
300
|
+
error: toError(err)
|
|
301
|
+
});
|
|
302
|
+
await context.emit("error", toError(err));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const stderr = err.output?.stderr ?? "";
|
|
306
|
+
const stdout = err.output?.stdout ?? "";
|
|
307
|
+
await context.emit("debug", {
|
|
308
|
+
date: /* @__PURE__ */ new Date(),
|
|
309
|
+
logs: [stdout, stderr].filter(Boolean)
|
|
310
|
+
});
|
|
311
|
+
if (stderr) sink?.onStderr?.(stderr);
|
|
312
|
+
if (stdout) sink?.onStdout?.(stdout);
|
|
313
|
+
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
314
|
+
await context.emit("hook:end", {
|
|
315
|
+
command,
|
|
316
|
+
args,
|
|
317
|
+
id,
|
|
318
|
+
success: false,
|
|
319
|
+
error: errorMessage
|
|
320
|
+
});
|
|
321
|
+
await context.emit("error", errorMessage);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
168
325
|
//#region src/utils/Writables.ts
|
|
169
326
|
var ClackWritable = class extends Writable {
|
|
170
327
|
taskLog;
|
|
@@ -173,7 +330,7 @@ var ClackWritable = class extends Writable {
|
|
|
173
330
|
this.taskLog = taskLog;
|
|
174
331
|
}
|
|
175
332
|
_write(chunk, _encoding, callback) {
|
|
176
|
-
this.taskLog.message(`${styleText("dim", chunk
|
|
333
|
+
this.taskLog.message(`${styleText("dim", chunk.toString())}`);
|
|
177
334
|
callback();
|
|
178
335
|
}
|
|
179
336
|
};
|
|
@@ -186,7 +343,7 @@ var ClackWritable = class extends Writable {
|
|
|
186
343
|
const clackLogger = defineLogger({
|
|
187
344
|
name: "clack",
|
|
188
345
|
install(context, options) {
|
|
189
|
-
const logLevel = options?.logLevel
|
|
346
|
+
const logLevel$8 = options?.logLevel ?? logLevel.info;
|
|
190
347
|
const state = {
|
|
191
348
|
totalPlugins: 0,
|
|
192
349
|
completedPlugins: 0,
|
|
@@ -214,27 +371,12 @@ const clackLogger = defineLogger({
|
|
|
214
371
|
state.activeProgress.clear();
|
|
215
372
|
}
|
|
216
373
|
function showProgressStep() {
|
|
217
|
-
if (logLevel <=
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
if (state.totalPlugins > 0) {
|
|
221
|
-
const pluginStr = state.failedPlugins > 0 ? `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins} ${styleText("red", `(${state.failedPlugins} failed)`)}` : `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins}`;
|
|
222
|
-
parts.push(pluginStr);
|
|
223
|
-
}
|
|
224
|
-
if (state.totalFiles > 0) parts.push(`Files ${styleText("green", state.processedFiles.toString())}/${state.totalFiles}`);
|
|
225
|
-
if (parts.length > 0) {
|
|
226
|
-
parts.push(`${styleText("green", duration)} elapsed`);
|
|
227
|
-
clack.log.step(getMessage(parts.join(styleText("dim", " | "))));
|
|
228
|
-
}
|
|
374
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
375
|
+
const line = buildProgressLine(state);
|
|
376
|
+
if (line) clack.log.step(getMessage(line));
|
|
229
377
|
}
|
|
230
378
|
function getMessage(message) {
|
|
231
|
-
|
|
232
|
-
hour12: false,
|
|
233
|
-
hour: "2-digit",
|
|
234
|
-
minute: "2-digit",
|
|
235
|
-
second: "2-digit"
|
|
236
|
-
})}]`), message].join(" ");
|
|
237
|
-
return message;
|
|
379
|
+
return formatMessage(message, logLevel$8);
|
|
238
380
|
}
|
|
239
381
|
function startSpinner(text) {
|
|
240
382
|
state.spinner.start(text);
|
|
@@ -245,7 +387,7 @@ const clackLogger = defineLogger({
|
|
|
245
387
|
state.isSpinning = false;
|
|
246
388
|
}
|
|
247
389
|
context.on("info", (message, info = "") => {
|
|
248
|
-
if (logLevel <=
|
|
390
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
249
391
|
const text = getMessage([
|
|
250
392
|
styleText("blue", "ℹ"),
|
|
251
393
|
message,
|
|
@@ -255,30 +397,30 @@ const clackLogger = defineLogger({
|
|
|
255
397
|
else clack.log.info(text);
|
|
256
398
|
});
|
|
257
399
|
context.on("success", (message, info = "") => {
|
|
258
|
-
if (logLevel <=
|
|
400
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
259
401
|
const text = getMessage([
|
|
260
402
|
styleText("blue", "✓"),
|
|
261
403
|
message,
|
|
262
|
-
logLevel >=
|
|
404
|
+
logLevel$8 >= logLevel.info ? styleText("dim", info) : void 0
|
|
263
405
|
].filter(Boolean).join(" "));
|
|
264
406
|
if (state.isSpinning) stopSpinner(text);
|
|
265
407
|
else clack.log.success(text);
|
|
266
408
|
});
|
|
267
409
|
context.on("warn", (message, info) => {
|
|
268
|
-
if (logLevel <
|
|
410
|
+
if (logLevel$8 < logLevel.warn) return;
|
|
269
411
|
const text = getMessage([
|
|
270
412
|
styleText("yellow", "⚠"),
|
|
271
413
|
message,
|
|
272
|
-
logLevel >=
|
|
414
|
+
logLevel$8 >= logLevel.info && info ? styleText("dim", info) : void 0
|
|
273
415
|
].filter(Boolean).join(" "));
|
|
274
416
|
clack.log.warn(text);
|
|
275
417
|
});
|
|
276
418
|
context.on("error", (error) => {
|
|
277
|
-
const caused = error
|
|
419
|
+
const caused = toCause(error);
|
|
278
420
|
const text = [styleText("red", "✗"), error.message].join(" ");
|
|
279
421
|
if (state.isSpinning) stopSpinner(getMessage(text));
|
|
280
422
|
else clack.log.error(getMessage(text));
|
|
281
|
-
if (logLevel >=
|
|
423
|
+
if (logLevel$8 >= logLevel.debug && error.stack) {
|
|
282
424
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
283
425
|
for (const frame of frames) clack.log.message(getMessage(styleText("dim", frame.trim())));
|
|
284
426
|
if (caused?.stack) {
|
|
@@ -289,7 +431,7 @@ const clackLogger = defineLogger({
|
|
|
289
431
|
}
|
|
290
432
|
});
|
|
291
433
|
context.on("version:new", (version, latestVersion) => {
|
|
292
|
-
if (logLevel <=
|
|
434
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
293
435
|
clack.box(`\`v${version}\` → \`v${latestVersion}\`
|
|
294
436
|
Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
295
437
|
width: "auto",
|
|
@@ -310,24 +452,24 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
310
452
|
reset();
|
|
311
453
|
});
|
|
312
454
|
context.on("config:start", () => {
|
|
313
|
-
if (logLevel <=
|
|
455
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
314
456
|
const text = getMessage("Configuration started");
|
|
315
457
|
clack.intro(text);
|
|
316
458
|
startSpinner(getMessage("Configuration loading"));
|
|
317
459
|
});
|
|
318
460
|
context.on("config:end", (_configs) => {
|
|
319
|
-
if (logLevel <=
|
|
461
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
320
462
|
const text = getMessage("Configuration completed");
|
|
321
463
|
clack.outro(text);
|
|
322
464
|
});
|
|
323
465
|
context.on("generation:start", (config) => {
|
|
324
|
-
|
|
466
|
+
reset();
|
|
467
|
+
state.totalPlugins = config.plugins?.length ?? 0;
|
|
325
468
|
const text = getMessage(["Generation started", config.name ? `for ${styleText("dim", config.name)}` : void 0].filter(Boolean).join(" "));
|
|
326
469
|
clack.intro(text);
|
|
327
|
-
reset();
|
|
328
470
|
});
|
|
329
471
|
context.on("plugin:start", (plugin) => {
|
|
330
|
-
if (logLevel <=
|
|
472
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
331
473
|
stopSpinner();
|
|
332
474
|
const progressBar = clack.progress({
|
|
333
475
|
style: "block",
|
|
@@ -347,7 +489,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
347
489
|
context.on("plugin:end", (plugin, { duration, success }) => {
|
|
348
490
|
stopSpinner();
|
|
349
491
|
const active = state.activeProgress.get(plugin.name);
|
|
350
|
-
if (!active || logLevel ===
|
|
492
|
+
if (!active || logLevel$8 === logLevel.silent) return;
|
|
351
493
|
clearInterval(active.interval);
|
|
352
494
|
if (success) state.completedPlugins++;
|
|
353
495
|
else state.failedPlugins++;
|
|
@@ -358,7 +500,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
358
500
|
showProgressStep();
|
|
359
501
|
});
|
|
360
502
|
context.on("files:processing:start", (files) => {
|
|
361
|
-
if (logLevel <=
|
|
503
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
362
504
|
stopSpinner();
|
|
363
505
|
state.totalFiles = files.length;
|
|
364
506
|
state.processedFiles = 0;
|
|
@@ -373,7 +515,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
373
515
|
state.activeProgress.set("files", { progressBar });
|
|
374
516
|
});
|
|
375
517
|
context.on("file:processing:update", ({ file, config }) => {
|
|
376
|
-
if (logLevel <=
|
|
518
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
377
519
|
stopSpinner();
|
|
378
520
|
state.processedFiles++;
|
|
379
521
|
const text = `Writing ${relative(config.root, file.path)}`;
|
|
@@ -382,7 +524,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
382
524
|
active.progressBar.advance(void 0, text);
|
|
383
525
|
});
|
|
384
526
|
context.on("files:processing:end", () => {
|
|
385
|
-
if (logLevel <=
|
|
527
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
386
528
|
stopSpinner();
|
|
387
529
|
const text = getMessage("Files written successfully");
|
|
388
530
|
const active = state.activeProgress.get("files");
|
|
@@ -396,113 +538,63 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
396
538
|
clack.outro(text);
|
|
397
539
|
});
|
|
398
540
|
context.on("format:start", () => {
|
|
399
|
-
if (logLevel <=
|
|
541
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
400
542
|
const text = getMessage("Format started");
|
|
401
543
|
clack.intro(text);
|
|
402
544
|
});
|
|
403
545
|
context.on("format:end", () => {
|
|
404
|
-
if (logLevel <=
|
|
546
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
405
547
|
const text = getMessage("Format completed");
|
|
406
548
|
clack.outro(text);
|
|
407
549
|
});
|
|
408
550
|
context.on("lint:start", () => {
|
|
409
|
-
if (logLevel <=
|
|
551
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
410
552
|
const text = getMessage("Lint started");
|
|
411
553
|
clack.intro(text);
|
|
412
554
|
});
|
|
413
555
|
context.on("lint:end", () => {
|
|
414
|
-
if (logLevel <=
|
|
556
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
415
557
|
const text = getMessage("Lint completed");
|
|
416
558
|
clack.outro(text);
|
|
417
559
|
});
|
|
418
560
|
context.on("hook:start", async ({ id, command, args }) => {
|
|
419
|
-
const commandWithArgs =
|
|
561
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
420
562
|
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} started`);
|
|
421
563
|
if (!id) return;
|
|
422
|
-
if (logLevel <=
|
|
423
|
-
|
|
424
|
-
const result = await x(command, [...args ?? []], {
|
|
425
|
-
nodeOptions: { detached: true },
|
|
426
|
-
throwOnError: true
|
|
427
|
-
});
|
|
428
|
-
await context.emit("debug", {
|
|
429
|
-
date: /* @__PURE__ */ new Date(),
|
|
430
|
-
logs: [result.stdout.trimEnd()]
|
|
431
|
-
});
|
|
432
|
-
await context.emit("hook:end", {
|
|
433
|
-
command,
|
|
434
|
-
args,
|
|
435
|
-
id,
|
|
436
|
-
success: true,
|
|
437
|
-
error: null
|
|
438
|
-
});
|
|
439
|
-
} catch (err) {
|
|
440
|
-
const error = err;
|
|
441
|
-
const stderr = error.output?.stderr ?? "";
|
|
442
|
-
const stdout = error.output?.stdout ?? "";
|
|
443
|
-
await context.emit("debug", {
|
|
444
|
-
date: /* @__PURE__ */ new Date(),
|
|
445
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
446
|
-
});
|
|
447
|
-
if (stderr) console.error(stderr);
|
|
448
|
-
if (stdout) console.log(stdout);
|
|
449
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
450
|
-
await context.emit("hook:end", {
|
|
451
|
-
command,
|
|
452
|
-
args,
|
|
453
|
-
id,
|
|
454
|
-
success: false,
|
|
455
|
-
error: errorMessage
|
|
456
|
-
});
|
|
457
|
-
await context.emit("error", errorMessage);
|
|
458
|
-
}
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
clack.intro(text);
|
|
462
|
-
const logger = clack.taskLog({ title: getMessage(["Executing hook", logLevel >= LogLevel.info ? styleText("dim", commandWithArgs) : void 0].filter(Boolean).join(" ")) });
|
|
463
|
-
const writable = new ClackWritable(logger);
|
|
464
|
-
try {
|
|
465
|
-
const proc = x(command, [...args ?? []], {
|
|
466
|
-
nodeOptions: { detached: true },
|
|
467
|
-
throwOnError: true
|
|
468
|
-
});
|
|
469
|
-
for await (const line of proc) writable.write(line);
|
|
470
|
-
const result = await proc;
|
|
471
|
-
await context.emit("debug", {
|
|
472
|
-
date: /* @__PURE__ */ new Date(),
|
|
473
|
-
logs: [result.stdout.trimEnd()]
|
|
474
|
-
});
|
|
475
|
-
await context.emit("hook:end", {
|
|
476
|
-
command,
|
|
477
|
-
args,
|
|
564
|
+
if (logLevel$8 <= logLevel.silent) {
|
|
565
|
+
await runHook({
|
|
478
566
|
id,
|
|
479
|
-
success: true,
|
|
480
|
-
error: null
|
|
481
|
-
});
|
|
482
|
-
} catch (err) {
|
|
483
|
-
const error = err;
|
|
484
|
-
const stderr = error.output?.stderr ?? "";
|
|
485
|
-
const stdout = error.output?.stdout ?? "";
|
|
486
|
-
await context.emit("debug", {
|
|
487
|
-
date: /* @__PURE__ */ new Date(),
|
|
488
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
489
|
-
});
|
|
490
|
-
if (stderr) logger.error(stderr);
|
|
491
|
-
if (stdout) logger.message(stdout);
|
|
492
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
493
|
-
await context.emit("hook:end", {
|
|
494
567
|
command,
|
|
495
568
|
args,
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
569
|
+
commandWithArgs,
|
|
570
|
+
context,
|
|
571
|
+
sink: {
|
|
572
|
+
onStderr: (s) => console.error(s),
|
|
573
|
+
onStdout: (s) => console.log(s)
|
|
574
|
+
}
|
|
499
575
|
});
|
|
500
|
-
|
|
576
|
+
return;
|
|
501
577
|
}
|
|
578
|
+
clack.intro(text);
|
|
579
|
+
const logger = clack.taskLog({ title: getMessage(["Executing hook", logLevel$8 >= logLevel.info ? styleText("dim", commandWithArgs) : void 0].filter(Boolean).join(" ")) });
|
|
580
|
+
const writable = new ClackWritable(logger);
|
|
581
|
+
await runHook({
|
|
582
|
+
id,
|
|
583
|
+
command,
|
|
584
|
+
args,
|
|
585
|
+
commandWithArgs,
|
|
586
|
+
context,
|
|
587
|
+
stream: true,
|
|
588
|
+
sink: {
|
|
589
|
+
onLine: (line) => writable.write(line),
|
|
590
|
+
onStderr: (s) => logger.error(s),
|
|
591
|
+
onStdout: (s) => logger.message(s)
|
|
592
|
+
}
|
|
593
|
+
});
|
|
502
594
|
});
|
|
503
595
|
context.on("hook:end", ({ command, args }) => {
|
|
504
|
-
if (logLevel <=
|
|
505
|
-
const text = getMessage(`Hook ${styleText("dim",
|
|
596
|
+
if (logLevel$8 <= logLevel.silent) return;
|
|
597
|
+
const text = getMessage(`Hook ${styleText("dim", formatCommandWithArgs(command, args))} successfully executed`);
|
|
506
598
|
clack.outro(text);
|
|
507
599
|
});
|
|
508
600
|
context.on("generation:summary", (config, { pluginTimings, failedPlugins, filesCreated, status, hrStart }) => {
|
|
@@ -512,25 +604,15 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
512
604
|
config,
|
|
513
605
|
status,
|
|
514
606
|
hrStart,
|
|
515
|
-
pluginTimings: logLevel >=
|
|
607
|
+
pluginTimings: logLevel$8 >= logLevel.verbose ? pluginTimings : void 0
|
|
516
608
|
});
|
|
517
609
|
const title = config.name || "";
|
|
518
610
|
summary.unshift("\n");
|
|
519
611
|
summary.push("\n");
|
|
520
|
-
|
|
521
|
-
clack.box(summary.join("\n"), getMessage(title), {
|
|
522
|
-
width: "auto",
|
|
523
|
-
formatBorder: (s) => styleText("green", s),
|
|
524
|
-
rounded: true,
|
|
525
|
-
withGuide: false,
|
|
526
|
-
contentAlign: "left",
|
|
527
|
-
titleAlign: "center"
|
|
528
|
-
});
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
612
|
+
const borderColor = status === "success" ? "green" : "red";
|
|
531
613
|
clack.box(summary.join("\n"), getMessage(title), {
|
|
532
614
|
width: "auto",
|
|
533
|
-
formatBorder: (s) => styleText(
|
|
615
|
+
formatBorder: (s) => styleText(borderColor, s),
|
|
534
616
|
rounded: true,
|
|
535
617
|
withGuide: false,
|
|
536
618
|
contentAlign: "left",
|
|
@@ -543,26 +625,6 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
543
625
|
}
|
|
544
626
|
});
|
|
545
627
|
//#endregion
|
|
546
|
-
//#region src/loggers/envDetection.ts
|
|
547
|
-
/**
|
|
548
|
-
* Check if running in GitHub Actions environment
|
|
549
|
-
*/
|
|
550
|
-
function isGitHubActions() {
|
|
551
|
-
return !!process.env.GITHUB_ACTIONS;
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* Check if running in any CI environment
|
|
555
|
-
*/
|
|
556
|
-
function isCIEnvironment() {
|
|
557
|
-
return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.TRAVIS || process.env.JENKINS_URL || process.env.BUILDKITE);
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Check if TTY is available for interactive output
|
|
561
|
-
*/
|
|
562
|
-
function canUseTTY() {
|
|
563
|
-
return !!process.stdout.isTTY && !isCIEnvironment();
|
|
564
|
-
}
|
|
565
|
-
//#endregion
|
|
566
628
|
//#region src/loggers/fileSystemLogger.ts
|
|
567
629
|
/**
|
|
568
630
|
* FileSystem logger for debug log persistence
|
|
@@ -591,7 +653,7 @@ const fileSystemLogger = defineLogger({
|
|
|
591
653
|
name,
|
|
592
654
|
state.startDate
|
|
593
655
|
].filter(Boolean).join("-")}.log`;
|
|
594
|
-
const pathName = resolve(process.cwd(), ".kubb", baseName);
|
|
656
|
+
const pathName = resolve(process$1.cwd(), ".kubb", baseName);
|
|
595
657
|
if (!files[pathName]) files[pathName] = [];
|
|
596
658
|
if (log.logs.length > 0) {
|
|
597
659
|
const timestamp = log.date.toLocaleString();
|
|
@@ -606,75 +668,66 @@ const fileSystemLogger = defineLogger({
|
|
|
606
668
|
context.on("info", (message, info) => {
|
|
607
669
|
state.cachedLogs.add({
|
|
608
670
|
date: /* @__PURE__ */ new Date(),
|
|
609
|
-
logs: [`ℹ ${message} ${info}`]
|
|
610
|
-
fileName: void 0
|
|
671
|
+
logs: [`ℹ ${message} ${info}`]
|
|
611
672
|
});
|
|
612
673
|
});
|
|
613
674
|
context.on("success", (message, info) => {
|
|
614
675
|
state.cachedLogs.add({
|
|
615
676
|
date: /* @__PURE__ */ new Date(),
|
|
616
|
-
logs: [`✓ ${message} ${info}`]
|
|
617
|
-
fileName: void 0
|
|
677
|
+
logs: [`✓ ${message} ${info}`]
|
|
618
678
|
});
|
|
619
679
|
});
|
|
620
680
|
context.on("warn", (message, info) => {
|
|
621
681
|
state.cachedLogs.add({
|
|
622
682
|
date: /* @__PURE__ */ new Date(),
|
|
623
|
-
logs: [`⚠ ${message} ${info}`]
|
|
624
|
-
fileName: void 0
|
|
683
|
+
logs: [`⚠ ${message} ${info}`]
|
|
625
684
|
});
|
|
626
685
|
});
|
|
627
686
|
context.on("error", (error) => {
|
|
628
687
|
state.cachedLogs.add({
|
|
629
688
|
date: /* @__PURE__ */ new Date(),
|
|
630
|
-
logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
|
|
631
|
-
fileName: void 0
|
|
689
|
+
logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
|
|
632
690
|
});
|
|
633
691
|
});
|
|
634
692
|
context.on("debug", (message) => {
|
|
635
693
|
state.cachedLogs.add({
|
|
636
694
|
date: /* @__PURE__ */ new Date(),
|
|
637
|
-
logs: message.logs
|
|
638
|
-
fileName: void 0
|
|
695
|
+
logs: message.logs
|
|
639
696
|
});
|
|
640
697
|
});
|
|
641
698
|
context.on("plugin:start", (plugin) => {
|
|
642
699
|
state.cachedLogs.add({
|
|
643
700
|
date: /* @__PURE__ */ new Date(),
|
|
644
|
-
logs: [`Generating ${plugin.name}`]
|
|
645
|
-
fileName: void 0
|
|
701
|
+
logs: [`Generating ${plugin.name}`]
|
|
646
702
|
});
|
|
647
703
|
});
|
|
648
704
|
context.on("plugin:end", (plugin, { duration, success }) => {
|
|
649
705
|
const durationStr = formatMs(duration);
|
|
650
706
|
state.cachedLogs.add({
|
|
651
707
|
date: /* @__PURE__ */ new Date(),
|
|
652
|
-
logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`]
|
|
653
|
-
fileName: void 0
|
|
708
|
+
logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`]
|
|
654
709
|
});
|
|
655
710
|
});
|
|
656
711
|
context.on("files:processing:start", (files) => {
|
|
657
712
|
state.cachedLogs.add({
|
|
658
713
|
date: /* @__PURE__ */ new Date(),
|
|
659
|
-
logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)]
|
|
660
|
-
fileName: void 0
|
|
714
|
+
logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)]
|
|
661
715
|
});
|
|
662
716
|
});
|
|
663
717
|
context.on("generation:end", async (config) => {
|
|
664
718
|
const writtenFilePaths = await writeLogs(config.name);
|
|
665
719
|
if (writtenFilePaths.length > 0) {
|
|
666
|
-
const files = writtenFilePaths.map((f) => relative(process.cwd(), f));
|
|
720
|
+
const files = writtenFilePaths.map((f) => relative(process$1.cwd(), f));
|
|
667
721
|
await context.emit("info", "Debug files written to:", files.join(", "));
|
|
668
722
|
}
|
|
669
723
|
reset();
|
|
670
724
|
});
|
|
671
|
-
context.on("lifecycle:end", async () => {});
|
|
672
725
|
const exitHandler = () => {
|
|
673
726
|
if (state.cachedLogs.size > 0) writeLogs().catch(() => {});
|
|
674
727
|
};
|
|
675
|
-
process.once("exit", exitHandler);
|
|
676
|
-
process.once("SIGINT", exitHandler);
|
|
677
|
-
process.once("SIGTERM", exitHandler);
|
|
728
|
+
process$1.once("exit", exitHandler);
|
|
729
|
+
process$1.once("SIGINT", exitHandler);
|
|
730
|
+
process$1.once("SIGTERM", exitHandler);
|
|
678
731
|
}
|
|
679
732
|
});
|
|
680
733
|
//#endregion
|
|
@@ -686,7 +739,7 @@ const fileSystemLogger = defineLogger({
|
|
|
686
739
|
const githubActionsLogger = defineLogger({
|
|
687
740
|
name: "github-actions",
|
|
688
741
|
install(context, options) {
|
|
689
|
-
const logLevel = options?.logLevel
|
|
742
|
+
const logLevel$7 = options?.logLevel ?? logLevel.info;
|
|
690
743
|
const state = {
|
|
691
744
|
totalPlugins: 0,
|
|
692
745
|
completedPlugins: 0,
|
|
@@ -703,29 +756,15 @@ const githubActionsLogger = defineLogger({
|
|
|
703
756
|
state.totalFiles = 0;
|
|
704
757
|
state.processedFiles = 0;
|
|
705
758
|
state.hrStart = process.hrtime();
|
|
759
|
+
state.currentConfigs = [];
|
|
706
760
|
}
|
|
707
761
|
function showProgressStep() {
|
|
708
|
-
if (logLevel <=
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
if (state.totalPlugins > 0) {
|
|
712
|
-
const pluginStr = state.failedPlugins > 0 ? `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins} ${styleText("red", `(${state.failedPlugins} failed)`)}` : `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins}`;
|
|
713
|
-
parts.push(pluginStr);
|
|
714
|
-
}
|
|
715
|
-
if (state.totalFiles > 0) parts.push(`Files ${styleText("green", state.processedFiles.toString())}/${state.totalFiles}`);
|
|
716
|
-
if (parts.length > 0) {
|
|
717
|
-
parts.push(`${styleText("green", duration)} elapsed`);
|
|
718
|
-
console.log(getMessage(parts.join(styleText("dim", " | "))));
|
|
719
|
-
}
|
|
762
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
763
|
+
const line = buildProgressLine(state);
|
|
764
|
+
if (line) console.log(getMessage(line));
|
|
720
765
|
}
|
|
721
766
|
function getMessage(message) {
|
|
722
|
-
|
|
723
|
-
hour12: false,
|
|
724
|
-
hour: "2-digit",
|
|
725
|
-
minute: "2-digit",
|
|
726
|
-
second: "2-digit"
|
|
727
|
-
})}]`), message].join(" ");
|
|
728
|
-
return message;
|
|
767
|
+
return formatMessage(message, logLevel$7);
|
|
729
768
|
}
|
|
730
769
|
function openGroup(name) {
|
|
731
770
|
console.log(`::group::${name}`);
|
|
@@ -734,7 +773,7 @@ const githubActionsLogger = defineLogger({
|
|
|
734
773
|
console.log("::endgroup::");
|
|
735
774
|
}
|
|
736
775
|
context.on("info", (message, info = "") => {
|
|
737
|
-
if (logLevel <=
|
|
776
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
738
777
|
const text = getMessage([
|
|
739
778
|
styleText("blue", "ℹ"),
|
|
740
779
|
message,
|
|
@@ -743,29 +782,29 @@ const githubActionsLogger = defineLogger({
|
|
|
743
782
|
console.log(text);
|
|
744
783
|
});
|
|
745
784
|
context.on("success", (message, info = "") => {
|
|
746
|
-
if (logLevel <=
|
|
785
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
747
786
|
const text = getMessage([
|
|
748
787
|
styleText("blue", "✓"),
|
|
749
788
|
message,
|
|
750
|
-
logLevel >=
|
|
789
|
+
logLevel$7 >= logLevel.info ? styleText("dim", info) : void 0
|
|
751
790
|
].filter(Boolean).join(" "));
|
|
752
791
|
console.log(text);
|
|
753
792
|
});
|
|
754
793
|
context.on("warn", (message, info = "") => {
|
|
755
|
-
if (logLevel <=
|
|
794
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
756
795
|
const text = getMessage([
|
|
757
796
|
styleText("yellow", "⚠"),
|
|
758
797
|
message,
|
|
759
|
-
logLevel >=
|
|
798
|
+
logLevel$7 >= logLevel.info ? styleText("dim", info) : void 0
|
|
760
799
|
].filter(Boolean).join(" "));
|
|
761
800
|
console.warn(`::warning::${text}`);
|
|
762
801
|
});
|
|
763
802
|
context.on("error", (error) => {
|
|
764
|
-
const caused = error
|
|
765
|
-
if (logLevel <=
|
|
803
|
+
const caused = toCause(error);
|
|
804
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
766
805
|
const message = error.message || String(error);
|
|
767
806
|
console.error(`::error::${message}`);
|
|
768
|
-
if (logLevel >=
|
|
807
|
+
if (logLevel$7 >= logLevel.debug && error.stack) {
|
|
769
808
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
770
809
|
for (const frame of frames) console.log(getMessage(styleText("dim", frame.trim())));
|
|
771
810
|
if (caused?.stack) {
|
|
@@ -780,33 +819,33 @@ const githubActionsLogger = defineLogger({
|
|
|
780
819
|
reset();
|
|
781
820
|
});
|
|
782
821
|
context.on("config:start", () => {
|
|
783
|
-
if (logLevel <=
|
|
822
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
784
823
|
const text = getMessage("Configuration started");
|
|
785
824
|
openGroup("Configuration");
|
|
786
825
|
console.log(text);
|
|
787
826
|
});
|
|
788
827
|
context.on("config:end", (configs) => {
|
|
789
828
|
state.currentConfigs = configs;
|
|
790
|
-
if (logLevel <=
|
|
829
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
791
830
|
const text = getMessage("Configuration completed");
|
|
792
831
|
console.log(text);
|
|
793
832
|
closeGroup("Configuration");
|
|
794
833
|
});
|
|
795
834
|
context.on("generation:start", (config) => {
|
|
796
|
-
|
|
835
|
+
reset();
|
|
836
|
+
state.totalPlugins = config.plugins?.length ?? 0;
|
|
797
837
|
const text = config.name ? `Generation for ${styleText("bold", config.name)}` : "Generation";
|
|
798
838
|
if (state.currentConfigs.length > 1) openGroup(text);
|
|
799
839
|
if (state.currentConfigs.length === 1) console.log(getMessage(text));
|
|
800
|
-
reset();
|
|
801
840
|
});
|
|
802
841
|
context.on("plugin:start", (plugin) => {
|
|
803
|
-
if (logLevel <=
|
|
842
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
804
843
|
const text = getMessage(`Generating ${styleText("bold", plugin.name)}`);
|
|
805
844
|
if (state.currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
|
|
806
845
|
console.log(text);
|
|
807
846
|
});
|
|
808
847
|
context.on("plugin:end", (plugin, { duration, success }) => {
|
|
809
|
-
if (logLevel <=
|
|
848
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
810
849
|
if (success) state.completedPlugins++;
|
|
811
850
|
else state.failedPlugins++;
|
|
812
851
|
const durationStr = formatMsWithColor(duration);
|
|
@@ -817,7 +856,7 @@ const githubActionsLogger = defineLogger({
|
|
|
817
856
|
showProgressStep();
|
|
818
857
|
});
|
|
819
858
|
context.on("files:processing:start", (files) => {
|
|
820
|
-
if (logLevel <=
|
|
859
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
821
860
|
state.totalFiles = files.length;
|
|
822
861
|
state.processedFiles = 0;
|
|
823
862
|
if (state.currentConfigs.length === 1) openGroup("File Generation");
|
|
@@ -825,108 +864,82 @@ const githubActionsLogger = defineLogger({
|
|
|
825
864
|
console.log(text);
|
|
826
865
|
});
|
|
827
866
|
context.on("files:processing:end", () => {
|
|
828
|
-
if (logLevel <=
|
|
867
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
829
868
|
const text = getMessage("Files written successfully");
|
|
830
869
|
console.log(text);
|
|
831
870
|
if (state.currentConfigs.length === 1) closeGroup("File Generation");
|
|
871
|
+
showProgressStep();
|
|
832
872
|
});
|
|
833
873
|
context.on("file:processing:update", () => {
|
|
834
|
-
if (logLevel <=
|
|
874
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
835
875
|
state.processedFiles++;
|
|
836
876
|
});
|
|
837
|
-
context.on("files:processing:end", () => {
|
|
838
|
-
if (logLevel <= LogLevel.silent) return;
|
|
839
|
-
showProgressStep();
|
|
840
|
-
});
|
|
841
877
|
context.on("generation:end", (config) => {
|
|
842
878
|
const text = getMessage(config.name ? `${styleText("blue", "✓")} Generation completed for ${styleText("dim", config.name)}` : `${styleText("blue", "✓")} Generation completed`);
|
|
843
879
|
console.log(text);
|
|
844
880
|
});
|
|
845
881
|
context.on("format:start", () => {
|
|
846
|
-
if (logLevel <=
|
|
882
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
847
883
|
const text = getMessage("Format started");
|
|
848
884
|
if (state.currentConfigs.length === 1) openGroup("Formatting");
|
|
849
885
|
console.log(text);
|
|
850
886
|
});
|
|
851
887
|
context.on("format:end", () => {
|
|
852
|
-
if (logLevel <=
|
|
888
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
853
889
|
const text = getMessage("Format completed");
|
|
854
890
|
console.log(text);
|
|
855
891
|
if (state.currentConfigs.length === 1) closeGroup("Formatting");
|
|
856
892
|
});
|
|
857
893
|
context.on("lint:start", () => {
|
|
858
|
-
if (logLevel <=
|
|
894
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
859
895
|
const text = getMessage("Lint started");
|
|
860
896
|
if (state.currentConfigs.length === 1) openGroup("Linting");
|
|
861
897
|
console.log(text);
|
|
862
898
|
});
|
|
863
899
|
context.on("lint:end", () => {
|
|
864
|
-
if (logLevel <=
|
|
900
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
865
901
|
const text = getMessage("Lint completed");
|
|
866
902
|
console.log(text);
|
|
867
903
|
if (state.currentConfigs.length === 1) closeGroup("Linting");
|
|
868
904
|
});
|
|
869
905
|
context.on("hook:start", async ({ id, command, args }) => {
|
|
870
|
-
const commandWithArgs =
|
|
906
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
871
907
|
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} started`);
|
|
872
|
-
if (logLevel >
|
|
908
|
+
if (logLevel$7 > logLevel.silent) {
|
|
873
909
|
if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
|
|
874
910
|
console.log(text);
|
|
875
911
|
}
|
|
876
912
|
if (!id) return;
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
command,
|
|
889
|
-
args,
|
|
890
|
-
id,
|
|
891
|
-
success: true,
|
|
892
|
-
error: null
|
|
893
|
-
});
|
|
894
|
-
} catch (err) {
|
|
895
|
-
const error = err;
|
|
896
|
-
const stderr = error.output?.stderr ?? "";
|
|
897
|
-
const stdout = error.output?.stdout ?? "";
|
|
898
|
-
await context.emit("debug", {
|
|
899
|
-
date: /* @__PURE__ */ new Date(),
|
|
900
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
901
|
-
});
|
|
902
|
-
if (stderr) console.error(`::error::${stderr}`);
|
|
903
|
-
if (stdout) console.log(stdout);
|
|
904
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
905
|
-
await context.emit("hook:end", {
|
|
906
|
-
command,
|
|
907
|
-
args,
|
|
908
|
-
id,
|
|
909
|
-
success: false,
|
|
910
|
-
error: errorMessage
|
|
911
|
-
});
|
|
912
|
-
await context.emit("error", errorMessage);
|
|
913
|
-
}
|
|
913
|
+
await runHook({
|
|
914
|
+
id,
|
|
915
|
+
command,
|
|
916
|
+
args,
|
|
917
|
+
commandWithArgs,
|
|
918
|
+
context,
|
|
919
|
+
sink: {
|
|
920
|
+
onStdout: logLevel$7 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
921
|
+
onStderr: logLevel$7 > logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
|
|
922
|
+
}
|
|
923
|
+
});
|
|
914
924
|
});
|
|
915
925
|
context.on("hook:end", ({ command, args }) => {
|
|
916
|
-
if (logLevel <=
|
|
917
|
-
const commandWithArgs =
|
|
926
|
+
if (logLevel$7 <= logLevel.silent) return;
|
|
927
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
918
928
|
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} completed`);
|
|
919
929
|
console.log(text);
|
|
920
930
|
if (state.currentConfigs.length === 1) closeGroup(`Hook ${commandWithArgs}`);
|
|
921
931
|
});
|
|
922
932
|
context.on("generation:summary", (config, { status, hrStart, failedPlugins }) => {
|
|
923
|
-
const pluginsCount = config.plugins?.length
|
|
933
|
+
const pluginsCount = config.plugins?.length ?? 0;
|
|
924
934
|
const successCount = pluginsCount - failedPlugins.size;
|
|
925
935
|
const duration = formatHrtime(hrStart);
|
|
926
936
|
if (state.currentConfigs.length > 1) console.log(" ");
|
|
927
937
|
console.log(status === "success" ? `Kubb Summary: ${styleText("blue", "✓")} ${`${successCount} successful`}, ${pluginsCount} total, ${styleText("green", duration)}` : `Kubb Summary: ${styleText("blue", "✓")} ${`${successCount} successful`}, ✗ ${`${failedPlugins.size} failed`}, ${pluginsCount} total, ${styleText("green", duration)}`);
|
|
928
938
|
if (state.currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${styleText("bold", config.name)}` : "Generation");
|
|
929
939
|
});
|
|
940
|
+
context.on("lifecycle:end", () => {
|
|
941
|
+
reset();
|
|
942
|
+
});
|
|
930
943
|
}
|
|
931
944
|
});
|
|
932
945
|
//#endregion
|
|
@@ -938,18 +951,12 @@ const githubActionsLogger = defineLogger({
|
|
|
938
951
|
const plainLogger = defineLogger({
|
|
939
952
|
name: "plain",
|
|
940
953
|
install(context, options) {
|
|
941
|
-
const logLevel = options?.logLevel
|
|
954
|
+
const logLevel$6 = options?.logLevel ?? logLevel.info;
|
|
942
955
|
function getMessage(message) {
|
|
943
|
-
|
|
944
|
-
hour12: false,
|
|
945
|
-
hour: "2-digit",
|
|
946
|
-
minute: "2-digit",
|
|
947
|
-
second: "2-digit"
|
|
948
|
-
})}]`, message].join(" ");
|
|
949
|
-
return message;
|
|
956
|
+
return formatMessage(message, logLevel$6);
|
|
950
957
|
}
|
|
951
958
|
context.on("info", (message, info) => {
|
|
952
|
-
if (logLevel <=
|
|
959
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
953
960
|
const text = getMessage([
|
|
954
961
|
"ℹ",
|
|
955
962
|
message,
|
|
@@ -958,28 +965,28 @@ const plainLogger = defineLogger({
|
|
|
958
965
|
console.log(text);
|
|
959
966
|
});
|
|
960
967
|
context.on("success", (message, info = "") => {
|
|
961
|
-
if (logLevel <=
|
|
968
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
962
969
|
const text = getMessage([
|
|
963
970
|
"✓",
|
|
964
971
|
message,
|
|
965
|
-
logLevel >=
|
|
972
|
+
logLevel$6 >= logLevel.info ? info : void 0
|
|
966
973
|
].filter(Boolean).join(" "));
|
|
967
974
|
console.log(text);
|
|
968
975
|
});
|
|
969
976
|
context.on("warn", (message, info) => {
|
|
970
|
-
if (logLevel <
|
|
977
|
+
if (logLevel$6 < logLevel.warn) return;
|
|
971
978
|
const text = getMessage([
|
|
972
979
|
"⚠",
|
|
973
980
|
message,
|
|
974
|
-
logLevel >=
|
|
981
|
+
logLevel$6 >= logLevel.info ? info : void 0
|
|
975
982
|
].filter(Boolean).join(" "));
|
|
976
983
|
console.log(text);
|
|
977
984
|
});
|
|
978
985
|
context.on("error", (error) => {
|
|
979
|
-
const caused = error
|
|
986
|
+
const caused = toCause(error);
|
|
980
987
|
const text = getMessage(["✗", error.message].join(" "));
|
|
981
988
|
console.log(text);
|
|
982
|
-
if (logLevel >=
|
|
989
|
+
if (logLevel$6 >= logLevel.debug && error.stack) {
|
|
983
990
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
984
991
|
for (const frame of frames) console.log(getMessage(frame.trim()));
|
|
985
992
|
if (caused?.stack) {
|
|
@@ -993,42 +1000,42 @@ const plainLogger = defineLogger({
|
|
|
993
1000
|
console.log("Kubb CLI 🧩");
|
|
994
1001
|
});
|
|
995
1002
|
context.on("config:start", () => {
|
|
996
|
-
if (logLevel <=
|
|
1003
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
997
1004
|
const text = getMessage("Configuration started");
|
|
998
1005
|
console.log(text);
|
|
999
1006
|
});
|
|
1000
1007
|
context.on("config:end", () => {
|
|
1001
|
-
if (logLevel <=
|
|
1008
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1002
1009
|
const text = getMessage("Configuration completed");
|
|
1003
1010
|
console.log(text);
|
|
1004
1011
|
});
|
|
1005
1012
|
context.on("generation:start", () => {
|
|
1006
|
-
const text = getMessage("
|
|
1013
|
+
const text = getMessage("Generation started");
|
|
1007
1014
|
console.log(text);
|
|
1008
1015
|
});
|
|
1009
1016
|
context.on("plugin:start", (plugin) => {
|
|
1010
|
-
if (logLevel <=
|
|
1017
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1011
1018
|
const text = getMessage(`Generating ${plugin.name}`);
|
|
1012
1019
|
console.log(text);
|
|
1013
1020
|
});
|
|
1014
1021
|
context.on("plugin:end", (plugin, { duration, success }) => {
|
|
1015
|
-
if (logLevel <=
|
|
1022
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1016
1023
|
const durationStr = formatMs(duration);
|
|
1017
1024
|
const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`);
|
|
1018
1025
|
console.log(text);
|
|
1019
1026
|
});
|
|
1020
1027
|
context.on("files:processing:start", (files) => {
|
|
1021
|
-
if (logLevel <=
|
|
1028
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1022
1029
|
const text = getMessage(`Writing ${files.length} files`);
|
|
1023
1030
|
console.log(text);
|
|
1024
1031
|
});
|
|
1025
1032
|
context.on("file:processing:update", ({ file, config }) => {
|
|
1026
|
-
if (logLevel <=
|
|
1033
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1027
1034
|
const text = getMessage(`Writing ${relative(config.root, file.path)}`);
|
|
1028
1035
|
console.log(text);
|
|
1029
1036
|
});
|
|
1030
1037
|
context.on("files:processing:end", () => {
|
|
1031
|
-
if (logLevel <=
|
|
1038
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1032
1039
|
const text = getMessage("Files written successfully");
|
|
1033
1040
|
console.log(text);
|
|
1034
1041
|
});
|
|
@@ -1037,71 +1044,45 @@ const plainLogger = defineLogger({
|
|
|
1037
1044
|
console.log(text);
|
|
1038
1045
|
});
|
|
1039
1046
|
context.on("format:start", () => {
|
|
1040
|
-
if (logLevel <=
|
|
1047
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1041
1048
|
const text = getMessage("Format started");
|
|
1042
1049
|
console.log(text);
|
|
1043
1050
|
});
|
|
1044
1051
|
context.on("format:end", () => {
|
|
1045
|
-
if (logLevel <=
|
|
1052
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1046
1053
|
const text = getMessage("Format completed");
|
|
1047
1054
|
console.log(text);
|
|
1048
1055
|
});
|
|
1049
1056
|
context.on("lint:start", () => {
|
|
1050
|
-
if (logLevel <=
|
|
1057
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1051
1058
|
const text = getMessage("Lint started");
|
|
1052
1059
|
console.log(text);
|
|
1053
1060
|
});
|
|
1054
1061
|
context.on("lint:end", () => {
|
|
1055
|
-
if (logLevel <=
|
|
1062
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1056
1063
|
const text = getMessage("Lint completed");
|
|
1057
1064
|
console.log(text);
|
|
1058
1065
|
});
|
|
1059
1066
|
context.on("hook:start", async ({ id, command, args }) => {
|
|
1060
|
-
const commandWithArgs =
|
|
1067
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1061
1068
|
const text = getMessage(`Hook ${commandWithArgs} started`);
|
|
1062
|
-
if (logLevel >
|
|
1069
|
+
if (logLevel$6 > logLevel.silent) console.log(text);
|
|
1063
1070
|
if (!id) return;
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
command,
|
|
1076
|
-
args,
|
|
1077
|
-
id,
|
|
1078
|
-
success: true,
|
|
1079
|
-
error: null
|
|
1080
|
-
});
|
|
1081
|
-
} catch (err) {
|
|
1082
|
-
const error = err;
|
|
1083
|
-
const stderr = error.output?.stderr ?? "";
|
|
1084
|
-
const stdout = error.output?.stdout ?? "";
|
|
1085
|
-
await context.emit("debug", {
|
|
1086
|
-
date: /* @__PURE__ */ new Date(),
|
|
1087
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
1088
|
-
});
|
|
1089
|
-
if (stderr) console.error(stderr);
|
|
1090
|
-
if (stdout) console.log(stdout);
|
|
1091
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
1092
|
-
await context.emit("hook:end", {
|
|
1093
|
-
command,
|
|
1094
|
-
args,
|
|
1095
|
-
id,
|
|
1096
|
-
success: false,
|
|
1097
|
-
error: errorMessage
|
|
1098
|
-
});
|
|
1099
|
-
await context.emit("error", errorMessage);
|
|
1100
|
-
}
|
|
1071
|
+
await runHook({
|
|
1072
|
+
id,
|
|
1073
|
+
command,
|
|
1074
|
+
args,
|
|
1075
|
+
commandWithArgs,
|
|
1076
|
+
context,
|
|
1077
|
+
sink: {
|
|
1078
|
+
onStdout: logLevel$6 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1079
|
+
onStderr: logLevel$6 > logLevel.silent ? (s) => console.error(s) : void 0
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1101
1082
|
});
|
|
1102
1083
|
context.on("hook:end", ({ command, args }) => {
|
|
1103
|
-
if (logLevel <=
|
|
1104
|
-
const text = getMessage(`Hook ${
|
|
1084
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
1085
|
+
const text = getMessage(`Hook ${formatCommandWithArgs(command, args)} completed`);
|
|
1105
1086
|
console.log(text);
|
|
1106
1087
|
});
|
|
1107
1088
|
context.on("generation:summary", (config, { pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
|
|
@@ -1111,16 +1092,52 @@ const plainLogger = defineLogger({
|
|
|
1111
1092
|
config,
|
|
1112
1093
|
status,
|
|
1113
1094
|
hrStart,
|
|
1114
|
-
pluginTimings: logLevel >=
|
|
1095
|
+
pluginTimings: logLevel$6 >= logLevel.verbose ? pluginTimings : void 0
|
|
1115
1096
|
});
|
|
1116
|
-
console.log(
|
|
1097
|
+
console.log(SUMMARY_SEPARATOR);
|
|
1117
1098
|
console.log(summary.join("\n"));
|
|
1118
|
-
console.log(
|
|
1099
|
+
console.log(SUMMARY_SEPARATOR);
|
|
1119
1100
|
});
|
|
1120
1101
|
}
|
|
1121
1102
|
});
|
|
1122
1103
|
//#endregion
|
|
1123
1104
|
//#region src/loggers/utils.ts
|
|
1105
|
+
/**
|
|
1106
|
+
* Optionally prefix a message with a [HH:MM:SS] timestamp when logLevel >= verbose.
|
|
1107
|
+
* Shared across all logger adapters to avoid duplication.
|
|
1108
|
+
*/
|
|
1109
|
+
function formatMessage(message, logLevel$4) {
|
|
1110
|
+
if (logLevel$4 >= logLevel.verbose) return `${styleText("dim", `[${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
1111
|
+
hour12: false,
|
|
1112
|
+
hour: "2-digit",
|
|
1113
|
+
minute: "2-digit",
|
|
1114
|
+
second: "2-digit"
|
|
1115
|
+
})}]`)} ${message}`;
|
|
1116
|
+
return message;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Build the progress summary line shared by clack and GitHub Actions loggers.
|
|
1120
|
+
* Returns null when there is nothing to display.
|
|
1121
|
+
*/
|
|
1122
|
+
function buildProgressLine(state) {
|
|
1123
|
+
const parts = [];
|
|
1124
|
+
const duration = formatHrtime(state.hrStart);
|
|
1125
|
+
if (state.totalPlugins > 0) {
|
|
1126
|
+
const pluginStr = state.failedPlugins > 0 ? `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins} ${styleText("red", `(${state.failedPlugins} failed)`)}` : `Plugins ${styleText("green", state.completedPlugins.toString())}/${state.totalPlugins}`;
|
|
1127
|
+
parts.push(pluginStr);
|
|
1128
|
+
}
|
|
1129
|
+
if (state.totalFiles > 0) parts.push(`Files ${styleText("green", state.processedFiles.toString())}/${state.totalFiles}`);
|
|
1130
|
+
if (parts.length === 0) return null;
|
|
1131
|
+
parts.push(`${styleText("green", duration)} elapsed`);
|
|
1132
|
+
return parts.join(styleText("dim", " | "));
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Join a command and its optional args into a single display string.
|
|
1136
|
+
* e.g. ("prettier", ["--write", "."]) → "prettier --write ."
|
|
1137
|
+
*/
|
|
1138
|
+
function formatCommandWithArgs(command, args) {
|
|
1139
|
+
return args?.length ? `${command} ${args.join(" ")}` : command;
|
|
1140
|
+
}
|
|
1124
1141
|
function detectLogger() {
|
|
1125
1142
|
if (isGitHubActions()) return "github-actions";
|
|
1126
1143
|
if (canUseTTY()) return "clack";
|
|
@@ -1131,12 +1148,12 @@ const logMapper = {
|
|
|
1131
1148
|
plain: plainLogger,
|
|
1132
1149
|
"github-actions": githubActionsLogger
|
|
1133
1150
|
};
|
|
1134
|
-
async function setupLogger(context, { logLevel }) {
|
|
1151
|
+
async function setupLogger(context, { logLevel: logLevel$5 }) {
|
|
1135
1152
|
const type = detectLogger();
|
|
1136
1153
|
const logger = logMapper[type];
|
|
1137
1154
|
if (!logger) throw new Error(`Unknown adapter type: ${type}`);
|
|
1138
|
-
const cleanup = await logger.install(context, { logLevel });
|
|
1139
|
-
if (logLevel >=
|
|
1155
|
+
const cleanup = await logger.install(context, { logLevel: logLevel$5 });
|
|
1156
|
+
if (logLevel$5 >= logLevel.debug) await fileSystemLogger.install(context, { logLevel: logLevel$5 });
|
|
1140
1157
|
return cleanup;
|
|
1141
1158
|
}
|
|
1142
1159
|
//#endregion
|
|
@@ -1147,20 +1164,141 @@ async function executeHooks({ hooks, events }) {
|
|
|
1147
1164
|
const [cmd, ...args] = tokenize(command);
|
|
1148
1165
|
if (!cmd) continue;
|
|
1149
1166
|
const hookId = createHash("sha256").update(command).digest("hex");
|
|
1167
|
+
const hookEndPromise = new Promise((resolve, reject) => {
|
|
1168
|
+
const handler = ({ id, success, error }) => {
|
|
1169
|
+
if (id !== hookId) return;
|
|
1170
|
+
events.off("hook:end", handler);
|
|
1171
|
+
if (!success) {
|
|
1172
|
+
reject(error ?? /* @__PURE__ */ new Error(`Hook failed: ${command}`));
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
events.emit("success", `${styleText("dim", command)} successfully executed`).then(resolve).catch(reject);
|
|
1176
|
+
};
|
|
1177
|
+
events.on("hook:end", handler);
|
|
1178
|
+
});
|
|
1150
1179
|
await events.emit("hook:start", {
|
|
1151
1180
|
id: hookId,
|
|
1152
1181
|
command: cmd,
|
|
1153
1182
|
args
|
|
1154
1183
|
});
|
|
1155
|
-
await
|
|
1156
|
-
if (!success) throw error;
|
|
1157
|
-
await events.emit("success", `${styleText("dim", command)} successfully executed`);
|
|
1158
|
-
});
|
|
1184
|
+
await hookEndPromise;
|
|
1159
1185
|
}
|
|
1160
1186
|
}
|
|
1161
1187
|
//#endregion
|
|
1188
|
+
//#region src/utils/getCosmiConfig.ts
|
|
1189
|
+
const jiti = createJiti(import.meta.url, {
|
|
1190
|
+
jsx: {
|
|
1191
|
+
runtime: "automatic",
|
|
1192
|
+
importSource: "@kubb/react-fabric"
|
|
1193
|
+
},
|
|
1194
|
+
sourceMaps: true,
|
|
1195
|
+
interopDefault: true
|
|
1196
|
+
});
|
|
1197
|
+
const tsLoader = async (configFile) => {
|
|
1198
|
+
return await jiti.import(configFile, { default: true });
|
|
1199
|
+
};
|
|
1200
|
+
async function getCosmiConfig(moduleName, config) {
|
|
1201
|
+
let result;
|
|
1202
|
+
const searchPlaces = [
|
|
1203
|
+
"package.json",
|
|
1204
|
+
`.${moduleName}rc`,
|
|
1205
|
+
`.${moduleName}rc.json`,
|
|
1206
|
+
`.${moduleName}rc.yaml`,
|
|
1207
|
+
`.${moduleName}rc.yml`,
|
|
1208
|
+
`.${moduleName}rc.ts`,
|
|
1209
|
+
`.${moduleName}rc.js`,
|
|
1210
|
+
`.${moduleName}rc.mjs`,
|
|
1211
|
+
`.${moduleName}rc.cjs`,
|
|
1212
|
+
`${moduleName}.config.ts`,
|
|
1213
|
+
`${moduleName}.config.js`,
|
|
1214
|
+
`${moduleName}.config.mjs`,
|
|
1215
|
+
`${moduleName}.config.cjs`
|
|
1216
|
+
];
|
|
1217
|
+
const explorer = cosmiconfig(moduleName, {
|
|
1218
|
+
cache: false,
|
|
1219
|
+
searchPlaces: [
|
|
1220
|
+
...searchPlaces.map((searchPlace) => {
|
|
1221
|
+
return `.config/${searchPlace}`;
|
|
1222
|
+
}),
|
|
1223
|
+
...searchPlaces.map((searchPlace) => {
|
|
1224
|
+
return `configs/${searchPlace}`;
|
|
1225
|
+
}),
|
|
1226
|
+
...searchPlaces
|
|
1227
|
+
],
|
|
1228
|
+
loaders: { ".ts": tsLoader }
|
|
1229
|
+
});
|
|
1230
|
+
try {
|
|
1231
|
+
result = config ? await explorer.load(config) : await explorer.search();
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
throw new Error("Config failed loading", { cause: error });
|
|
1234
|
+
}
|
|
1235
|
+
if (result?.isEmpty || !result || !result.config) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
|
|
1236
|
+
return result;
|
|
1237
|
+
}
|
|
1238
|
+
//#endregion
|
|
1239
|
+
//#region src/utils/watcher.ts
|
|
1240
|
+
async function startWatcher(path, cb) {
|
|
1241
|
+
const { watch } = await import("chokidar");
|
|
1242
|
+
watch(path, {
|
|
1243
|
+
ignorePermissionErrors: true,
|
|
1244
|
+
ignored: WATCHER_IGNORED_PATHS
|
|
1245
|
+
}).on("all", async (type, file) => {
|
|
1246
|
+
console.log(styleText("yellow", styleText("bold", `Change detected: ${type} ${file}`)));
|
|
1247
|
+
try {
|
|
1248
|
+
await cb(path);
|
|
1249
|
+
} catch (_e) {
|
|
1250
|
+
console.log(styleText("red", "Watcher failed"));
|
|
1251
|
+
}
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
//#endregion
|
|
1162
1255
|
//#region src/runners/generate.ts
|
|
1163
|
-
async function
|
|
1256
|
+
async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel: logLevel$1, events, onStart, onEnd }) {
|
|
1257
|
+
await onStart();
|
|
1258
|
+
let resolvedTool = toolValue;
|
|
1259
|
+
if (resolvedTool === "auto") {
|
|
1260
|
+
const detected = await detect();
|
|
1261
|
+
if (!detected) await events.emit("warn", noToolMessage);
|
|
1262
|
+
else {
|
|
1263
|
+
resolvedTool = detected;
|
|
1264
|
+
await events.emit("info", `Auto-detected ${toolLabel}: ${styleText("dim", resolvedTool)}`);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
|
|
1268
|
+
const toolConfig = toolMap[resolvedTool];
|
|
1269
|
+
try {
|
|
1270
|
+
const hookId = createHash("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
|
|
1271
|
+
const hookEndPromise = new Promise((resolve, reject) => {
|
|
1272
|
+
const handler = ({ id, success, error }) => {
|
|
1273
|
+
if (id !== hookId) return;
|
|
1274
|
+
events.off("hook:end", handler);
|
|
1275
|
+
if (!success) {
|
|
1276
|
+
reject(error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
events.emit("success", [
|
|
1280
|
+
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1281
|
+
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1282
|
+
"successfully"
|
|
1283
|
+
].filter(Boolean).join(" ")).then(resolve).catch(reject);
|
|
1284
|
+
};
|
|
1285
|
+
events.on("hook:end", handler);
|
|
1286
|
+
});
|
|
1287
|
+
await events.emit("hook:start", {
|
|
1288
|
+
id: hookId,
|
|
1289
|
+
command: toolConfig.command,
|
|
1290
|
+
args: toolConfig.args(outputPath)
|
|
1291
|
+
});
|
|
1292
|
+
await hookEndPromise;
|
|
1293
|
+
} catch (caughtError) {
|
|
1294
|
+
const err = new Error(toolConfig.errorMessage);
|
|
1295
|
+
err.cause = caughtError;
|
|
1296
|
+
await events.emit("error", err);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
await onEnd();
|
|
1300
|
+
}
|
|
1301
|
+
async function generate({ input, config: userConfig, events, logLevel: logLevel$2 }) {
|
|
1164
1302
|
const inputPath = input ?? ("path" in userConfig.input ? userConfig.input.path : void 0);
|
|
1165
1303
|
const hrStart = process$1.hrtime();
|
|
1166
1304
|
const config = {
|
|
@@ -1196,16 +1334,15 @@ async function generate({ input, config: userConfig, events, logLevel }) {
|
|
|
1196
1334
|
});
|
|
1197
1335
|
await events.emit("info", "Load summary");
|
|
1198
1336
|
if (failedPlugins.size > 0 || error) {
|
|
1199
|
-
[error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean)
|
|
1200
|
-
|
|
1201
|
-
});
|
|
1337
|
+
const allErrors = [error, ...Array.from(failedPlugins).filter((it) => it.error).map((it) => it.error)].filter(Boolean);
|
|
1338
|
+
for (const err of allErrors) await events.emit("error", err);
|
|
1202
1339
|
await events.emit("generation:end", config, files, sources);
|
|
1203
1340
|
await events.emit("generation:summary", config, {
|
|
1204
1341
|
failedPlugins,
|
|
1205
1342
|
filesCreated: files.length,
|
|
1206
1343
|
status: "failed",
|
|
1207
1344
|
hrStart,
|
|
1208
|
-
pluginTimings: logLevel >=
|
|
1345
|
+
pluginTimings: logLevel$2 >= logLevel.verbose ? pluginTimings : void 0
|
|
1209
1346
|
});
|
|
1210
1347
|
await sendTelemetry(buildTelemetryEvent({
|
|
1211
1348
|
command: "generate",
|
|
@@ -1222,80 +1359,35 @@ async function generate({ input, config: userConfig, events, logLevel }) {
|
|
|
1222
1359
|
}
|
|
1223
1360
|
await events.emit("success", "Generation successfully", inputPath);
|
|
1224
1361
|
await events.emit("generation:end", config, files, sources);
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
} catch (caughtError) {
|
|
1255
|
-
const error = new Error(formatterConfig.errorMessage);
|
|
1256
|
-
error.cause = caughtError;
|
|
1257
|
-
await events.emit("error", error);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
await events.emit("format:end");
|
|
1261
|
-
}
|
|
1262
|
-
if (config.output.lint) {
|
|
1263
|
-
await events.emit("lint:start");
|
|
1264
|
-
let linter = config.output.lint;
|
|
1265
|
-
if (linter === "auto") {
|
|
1266
|
-
const detectedLinter = await detectLinter();
|
|
1267
|
-
if (!detectedLinter) await events.emit("warn", "No linter found (biome, oxlint, or eslint). Skipping linting.");
|
|
1268
|
-
else {
|
|
1269
|
-
linter = detectedLinter;
|
|
1270
|
-
await events.emit("info", `Auto-detected linter: ${styleText("dim", linter)}`);
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
if (linter && linter !== "auto" && linter in linters) {
|
|
1274
|
-
const linterConfig = linters[linter];
|
|
1275
|
-
const outputPath = path.resolve(config.root, config.output.path);
|
|
1276
|
-
try {
|
|
1277
|
-
const hookId = createHash("sha256").update([config.name, linter].filter(Boolean).join("-")).digest("hex");
|
|
1278
|
-
await events.emit("hook:start", {
|
|
1279
|
-
id: hookId,
|
|
1280
|
-
command: linterConfig.command,
|
|
1281
|
-
args: linterConfig.args(outputPath)
|
|
1282
|
-
});
|
|
1283
|
-
await events.onOnce("hook:end", async ({ success, error }) => {
|
|
1284
|
-
if (!success) throw error;
|
|
1285
|
-
await events.emit("success", [
|
|
1286
|
-
`Linting with ${styleText("dim", linter)}`,
|
|
1287
|
-
logLevel >= LogLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1288
|
-
"successfully"
|
|
1289
|
-
].filter(Boolean).join(" "));
|
|
1290
|
-
});
|
|
1291
|
-
} catch (caughtError) {
|
|
1292
|
-
const error = new Error(linterConfig.errorMessage);
|
|
1293
|
-
error.cause = caughtError;
|
|
1294
|
-
await events.emit("error", error);
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
await events.emit("lint:end");
|
|
1298
|
-
}
|
|
1362
|
+
const outputPath = path.resolve(config.root, config.output.path);
|
|
1363
|
+
if (config.output.format) await runToolPass({
|
|
1364
|
+
toolValue: config.output.format,
|
|
1365
|
+
detect: detectFormatter,
|
|
1366
|
+
toolMap: formatters,
|
|
1367
|
+
toolLabel: "formatter",
|
|
1368
|
+
successPrefix: "Formatting",
|
|
1369
|
+
noToolMessage: "No formatter found (biome, prettier, or oxfmt). Skipping formatting.",
|
|
1370
|
+
configName: config.name,
|
|
1371
|
+
outputPath,
|
|
1372
|
+
logLevel: logLevel$2,
|
|
1373
|
+
events,
|
|
1374
|
+
onStart: () => events.emit("format:start"),
|
|
1375
|
+
onEnd: () => events.emit("format:end")
|
|
1376
|
+
});
|
|
1377
|
+
if (config.output.lint) await runToolPass({
|
|
1378
|
+
toolValue: config.output.lint,
|
|
1379
|
+
detect: detectLinter,
|
|
1380
|
+
toolMap: linters,
|
|
1381
|
+
toolLabel: "linter",
|
|
1382
|
+
successPrefix: "Linting",
|
|
1383
|
+
noToolMessage: "No linter found (biome, oxlint, or eslint). Skipping linting.",
|
|
1384
|
+
configName: config.name,
|
|
1385
|
+
outputPath,
|
|
1386
|
+
logLevel: logLevel$2,
|
|
1387
|
+
events,
|
|
1388
|
+
onStart: () => events.emit("lint:start"),
|
|
1389
|
+
onEnd: () => events.emit("lint:end")
|
|
1390
|
+
});
|
|
1299
1391
|
if (config.hooks) {
|
|
1300
1392
|
await events.emit("hooks:start");
|
|
1301
1393
|
await executeHooks({
|
|
@@ -1304,11 +1396,10 @@ async function generate({ input, config: userConfig, events, logLevel }) {
|
|
|
1304
1396
|
});
|
|
1305
1397
|
await events.emit("hooks:end");
|
|
1306
1398
|
}
|
|
1307
|
-
const generationStatus = failedPlugins.size > 0 || error ? "failed" : "success";
|
|
1308
1399
|
await events.emit("generation:summary", config, {
|
|
1309
1400
|
failedPlugins,
|
|
1310
1401
|
filesCreated: files.length,
|
|
1311
|
-
status:
|
|
1402
|
+
status: "success",
|
|
1312
1403
|
hrStart,
|
|
1313
1404
|
pluginTimings
|
|
1314
1405
|
});
|
|
@@ -1321,183 +1412,59 @@ async function generate({ input, config: userConfig, events, logLevel }) {
|
|
|
1321
1412
|
})),
|
|
1322
1413
|
hrStart,
|
|
1323
1414
|
filesCreated: files.length,
|
|
1324
|
-
status:
|
|
1415
|
+
status: "success"
|
|
1325
1416
|
}));
|
|
1326
1417
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
importSource: "@kubb/react-fabric"
|
|
1334
|
-
},
|
|
1335
|
-
sourceMaps: true,
|
|
1336
|
-
interopDefault: true
|
|
1337
|
-
}).import(configFile, { default: true });
|
|
1338
|
-
};
|
|
1339
|
-
async function getCosmiConfig(moduleName, config) {
|
|
1340
|
-
let result;
|
|
1341
|
-
const searchPlaces = [
|
|
1342
|
-
"package.json",
|
|
1343
|
-
`.${moduleName}rc`,
|
|
1344
|
-
`.${moduleName}rc.json`,
|
|
1345
|
-
`.${moduleName}rc.yaml`,
|
|
1346
|
-
`.${moduleName}rc.yml`,
|
|
1347
|
-
`.${moduleName}rc.ts`,
|
|
1348
|
-
`.${moduleName}rc.js`,
|
|
1349
|
-
`.${moduleName}rc.mjs`,
|
|
1350
|
-
`.${moduleName}rc.cjs`,
|
|
1351
|
-
`${moduleName}.config.ts`,
|
|
1352
|
-
`${moduleName}.config.js`,
|
|
1353
|
-
`${moduleName}.config.mjs`,
|
|
1354
|
-
`${moduleName}.config.cjs`
|
|
1355
|
-
];
|
|
1356
|
-
const explorer = cosmiconfig(moduleName, {
|
|
1357
|
-
cache: false,
|
|
1358
|
-
searchPlaces: [
|
|
1359
|
-
...searchPlaces.map((searchPlace) => {
|
|
1360
|
-
return `.config/${searchPlace}`;
|
|
1361
|
-
}),
|
|
1362
|
-
...searchPlaces.map((searchPlace) => {
|
|
1363
|
-
return `configs/${searchPlace}`;
|
|
1364
|
-
}),
|
|
1365
|
-
...searchPlaces
|
|
1366
|
-
],
|
|
1367
|
-
loaders: { ".ts": tsLoader }
|
|
1368
|
-
});
|
|
1369
|
-
try {
|
|
1370
|
-
result = config ? await explorer.load(config) : await explorer.search();
|
|
1371
|
-
} catch (error) {
|
|
1372
|
-
throw new Error("Config failed loading", { cause: error });
|
|
1373
|
-
}
|
|
1374
|
-
if (result?.isEmpty || !result || !result.config) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
|
|
1375
|
-
return result;
|
|
1376
|
-
}
|
|
1377
|
-
//#endregion
|
|
1378
|
-
//#region src/utils/watcher.ts
|
|
1379
|
-
async function startWatcher(path, cb) {
|
|
1380
|
-
const { watch } = await import("chokidar");
|
|
1381
|
-
watch(path, {
|
|
1382
|
-
ignorePermissionErrors: true,
|
|
1383
|
-
ignored: "**/{.git,node_modules}/**"
|
|
1384
|
-
}).on("all", async (type, file) => {
|
|
1385
|
-
console.log(styleText("yellow", styleText("bold", `Change detected: ${type} ${file}`)));
|
|
1418
|
+
async function runGenerateCommand({ input, configPath, logLevel: logLevelKey, watch }) {
|
|
1419
|
+
const logLevel$3 = logLevel[logLevelKey] ?? logLevel.info;
|
|
1420
|
+
const events = new AsyncEventEmitter();
|
|
1421
|
+
const promiseManager = new PromiseManager();
|
|
1422
|
+
await setupLogger(events, { logLevel: logLevel$3 });
|
|
1423
|
+
await executeIfOnline(async () => {
|
|
1386
1424
|
try {
|
|
1387
|
-
await
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
}
|
|
1425
|
+
const latestVersion = (await (await fetch(KUBB_NPM_PACKAGE_URL)).json()).version;
|
|
1426
|
+
if (latestVersion && version < latestVersion) await events.emit("version:new", version, latestVersion);
|
|
1427
|
+
} catch {}
|
|
1391
1428
|
});
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
default: "info",
|
|
1411
|
-
valueHint: "silent|info|verbose|debug"
|
|
1412
|
-
},
|
|
1413
|
-
watch: {
|
|
1414
|
-
type: "boolean",
|
|
1415
|
-
description: "Watch mode based on the input file",
|
|
1416
|
-
alias: "w",
|
|
1417
|
-
default: false
|
|
1418
|
-
},
|
|
1419
|
-
debug: {
|
|
1420
|
-
type: "boolean",
|
|
1421
|
-
description: "Override logLevel to debug",
|
|
1422
|
-
alias: "d",
|
|
1423
|
-
default: false
|
|
1424
|
-
},
|
|
1425
|
-
verbose: {
|
|
1426
|
-
type: "boolean",
|
|
1427
|
-
description: "Override logLevel to verbose",
|
|
1428
|
-
alias: "v",
|
|
1429
|
-
default: false
|
|
1430
|
-
},
|
|
1431
|
-
silent: {
|
|
1432
|
-
type: "boolean",
|
|
1433
|
-
description: "Override logLevel to silent",
|
|
1434
|
-
alias: "s",
|
|
1435
|
-
default: false
|
|
1436
|
-
},
|
|
1437
|
-
help: {
|
|
1438
|
-
type: "boolean",
|
|
1439
|
-
description: "Show help",
|
|
1440
|
-
alias: "h",
|
|
1441
|
-
default: false
|
|
1442
|
-
}
|
|
1443
|
-
},
|
|
1444
|
-
async run(commandContext) {
|
|
1445
|
-
const { args } = commandContext;
|
|
1446
|
-
const input = args._[0];
|
|
1447
|
-
const events = new AsyncEventEmitter();
|
|
1448
|
-
const promiseManager = new PromiseManager();
|
|
1449
|
-
if (args.help) return showUsage(command);
|
|
1450
|
-
if (args.debug) args.logLevel = "debug";
|
|
1451
|
-
if (args.verbose) args.logLevel = "verbose";
|
|
1452
|
-
if (args.silent) args.logLevel = "silent";
|
|
1453
|
-
const logLevel = LogLevel[args.logLevel] || 3;
|
|
1454
|
-
await setupLogger(events, { logLevel });
|
|
1455
|
-
await executeIfOnline(async () => {
|
|
1456
|
-
try {
|
|
1457
|
-
const latestVersion = (await (await fetch("https://registry.npmjs.org/@kubb/cli/latest")).json()).version;
|
|
1458
|
-
if (latestVersion && version < latestVersion) await events.emit("version:new", version, latestVersion);
|
|
1459
|
-
} catch {}
|
|
1460
|
-
});
|
|
1461
|
-
try {
|
|
1462
|
-
const result = await getCosmiConfig("kubb", args.config);
|
|
1463
|
-
const configs = await getConfigs(result.config, args);
|
|
1464
|
-
await events.emit("config:start");
|
|
1465
|
-
await events.emit("info", "Config loaded", path.relative(process$2.cwd(), result.filepath));
|
|
1466
|
-
await events.emit("success", "Config loaded successfully", path.relative(process$2.cwd(), result.filepath));
|
|
1467
|
-
await events.emit("config:end", configs);
|
|
1468
|
-
await events.emit("lifecycle:start", version);
|
|
1469
|
-
const promises = configs.map((config) => {
|
|
1470
|
-
return async () => {
|
|
1471
|
-
if (isInputPath(config) && args.watch) {
|
|
1472
|
-
await startWatcher([input || config.input.path], async (paths) => {
|
|
1473
|
-
events.removeAll();
|
|
1474
|
-
await generate({
|
|
1475
|
-
input,
|
|
1476
|
-
config,
|
|
1477
|
-
logLevel,
|
|
1478
|
-
events
|
|
1479
|
-
});
|
|
1480
|
-
clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
1429
|
+
try {
|
|
1430
|
+
const result = await getCosmiConfig("kubb", configPath);
|
|
1431
|
+
const configs = await getConfigs(result.config, { input });
|
|
1432
|
+
await events.emit("config:start");
|
|
1433
|
+
await events.emit("info", "Config loaded", path.relative(process$1.cwd(), result.filepath));
|
|
1434
|
+
await events.emit("success", "Config loaded successfully", path.relative(process$1.cwd(), result.filepath));
|
|
1435
|
+
await events.emit("config:end", configs);
|
|
1436
|
+
await events.emit("lifecycle:start", version);
|
|
1437
|
+
const promises = configs.map((config) => {
|
|
1438
|
+
return async () => {
|
|
1439
|
+
if (isInputPath(config) && watch) {
|
|
1440
|
+
await startWatcher([input || config.input.path], async (paths) => {
|
|
1441
|
+
events.removeAll();
|
|
1442
|
+
await generate({
|
|
1443
|
+
input,
|
|
1444
|
+
config,
|
|
1445
|
+
logLevel: logLevel$3,
|
|
1446
|
+
events
|
|
1481
1447
|
});
|
|
1482
|
-
|
|
1483
|
-
}
|
|
1484
|
-
await generate({
|
|
1485
|
-
input,
|
|
1486
|
-
config,
|
|
1487
|
-
logLevel,
|
|
1488
|
-
events
|
|
1448
|
+
clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
1489
1449
|
});
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
await generate({
|
|
1453
|
+
input,
|
|
1454
|
+
config,
|
|
1455
|
+
logLevel: logLevel$3,
|
|
1456
|
+
events
|
|
1457
|
+
});
|
|
1458
|
+
};
|
|
1459
|
+
});
|
|
1460
|
+
await promiseManager.run("seq", promises);
|
|
1461
|
+
await events.emit("lifecycle:end");
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
await events.emit("error", toError(error));
|
|
1464
|
+
process$1.exit(1);
|
|
1498
1465
|
}
|
|
1499
|
-
}
|
|
1466
|
+
}
|
|
1500
1467
|
//#endregion
|
|
1501
|
-
export {
|
|
1468
|
+
export { runGenerateCommand };
|
|
1502
1469
|
|
|
1503
|
-
//# sourceMappingURL=generate-
|
|
1470
|
+
//# sourceMappingURL=generate-CAsV9wSx.js.map
|