@kubb/cli 5.0.0-beta.84 → 5.0.0-beta.86
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/{Telemetry-ugO-B77y.js → Telemetry-Cuzoes9Y.js} +6 -2
- package/dist/Telemetry-Cuzoes9Y.js.map +1 -0
- package/dist/{Telemetry-jtbchpQE.cjs → Telemetry-CwQYBgsg.cjs} +11 -1
- package/dist/Telemetry-CwQYBgsg.cjs.map +1 -0
- package/dist/{generate-DDgZnlMs.js → generate-BO6xVUEL.js} +34 -24
- package/dist/generate-BO6xVUEL.js.map +1 -0
- package/dist/{generate-Diob_zqj.cjs → generate-BW9yIfgS.cjs} +34 -23
- package/dist/generate-BW9yIfgS.cjs.map +1 -0
- package/dist/index.cjs +28 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +29 -193
- package/dist/index.js.map +1 -1
- package/dist/{init-uOQx7jSE.cjs → init-Cx4n_O5X.cjs} +9 -10
- package/dist/init-Cx4n_O5X.cjs.map +1 -0
- package/dist/{init-Cn3jZVkf.js → init-_NdYuc6u.js} +10 -10
- package/dist/init-_NdYuc6u.js.map +1 -0
- package/dist/{mcp-n-IOoFZL.js → mcp-BuhCkjE_.js} +6 -6
- package/dist/mcp-BuhCkjE_.js.map +1 -0
- package/dist/{mcp-BxhOXHGD.cjs → mcp-DJd2cm9I.cjs} +5 -6
- package/dist/mcp-DJd2cm9I.cjs.map +1 -0
- package/dist/{package-BBBOfxZz.cjs → package-Bar6zPkT.cjs} +2 -2
- package/dist/package-Bar6zPkT.cjs.map +1 -0
- package/dist/package-D24TC3pS.js +6 -0
- package/dist/package-D24TC3pS.js.map +1 -0
- package/dist/{run-DXEMoDFa.cjs → run-3qq_Q4Tg.cjs} +4 -4
- package/dist/run-3qq_Q4Tg.cjs.map +1 -0
- package/dist/{run-Bz6ZUrhp.cjs → run-B9FN0sHW.cjs} +2 -2
- package/dist/run-B9FN0sHW.cjs.map +1 -0
- package/dist/{run-CPBFfbI7.js → run-BFhNcn8b.js} +4 -10
- package/dist/run-BFhNcn8b.js.map +1 -0
- package/dist/{run-D8TRnpBB.js → run-BxMfDivH.js} +291 -333
- package/dist/run-BxMfDivH.js.map +1 -0
- package/dist/{run-BBLhhWZu.js → run-D0Gs_UzJ.js} +2 -2
- package/dist/run-D0Gs_UzJ.js.map +1 -0
- package/dist/{run-DYkciQ4u.cjs → run-DYzUPE7Z.cjs} +4 -10
- package/dist/run-DYzUPE7Z.cjs.map +1 -0
- package/dist/{run-ChSqYuc1.cjs → run-lAxAF-4t.cjs} +292 -333
- package/dist/run-lAxAF-4t.cjs.map +1 -0
- package/dist/{run-44Zxh8Ec.js → run-yMRylOST.js} +3 -3
- package/dist/run-yMRylOST.js.map +1 -0
- package/dist/{tools-D0UogMU3.js → tools-B23ltmWP.js} +3 -3
- package/dist/tools-B23ltmWP.js.map +1 -0
- package/dist/{tools-CZT9wSA6.cjs → tools-CeIABV0T.cjs} +3 -3
- package/dist/tools-CeIABV0T.cjs.map +1 -0
- package/dist/{validate-CYIieoc4.cjs → validate-D0doE06k.cjs} +8 -9
- package/dist/validate-D0doE06k.cjs.map +1 -0
- package/dist/{validate-BoG8ZZgE.js → validate-DZXin3M6.js} +9 -9
- package/dist/validate-DZXin3M6.js.map +1 -0
- package/package.json +8 -7
- package/dist/Telemetry-jtbchpQE.cjs.map +0 -1
- package/dist/Telemetry-ugO-B77y.js.map +0 -1
- package/dist/defineCommand-Bo3yZTWI.cjs +0 -36
- package/dist/defineCommand-Bo3yZTWI.cjs.map +0 -1
- package/dist/defineCommand-DMEeqliP.js +0 -31
- package/dist/defineCommand-DMEeqliP.js.map +0 -1
- package/dist/generate-DDgZnlMs.js.map +0 -1
- package/dist/generate-Diob_zqj.cjs.map +0 -1
- package/dist/init-Cn3jZVkf.js.map +0 -1
- package/dist/init-uOQx7jSE.cjs.map +0 -1
- package/dist/mcp-BxhOXHGD.cjs.map +0 -1
- package/dist/mcp-n-IOoFZL.js.map +0 -1
- package/dist/package-BBBOfxZz.cjs.map +0 -1
- package/dist/package-DKwwXnAz.js +0 -6
- package/dist/package-DKwwXnAz.js.map +0 -1
- package/dist/run-44Zxh8Ec.js.map +0 -1
- package/dist/run-BBLhhWZu.js.map +0 -1
- package/dist/run-Bz6ZUrhp.cjs.map +0 -1
- package/dist/run-CPBFfbI7.js.map +0 -1
- package/dist/run-ChSqYuc1.cjs.map +0 -1
- package/dist/run-D8TRnpBB.js.map +0 -1
- package/dist/run-DXEMoDFa.cjs.map +0 -1
- package/dist/run-DYkciQ4u.cjs.map +0 -1
- package/dist/tools-CZT9wSA6.cjs.map +0 -1
- package/dist/tools-D0UogMU3.js.map +0 -1
- package/dist/validate-BoG8ZZgE.js.map +0 -1
- package/dist/validate-CYIieoc4.cjs.map +0 -1
|
@@ -1,126 +1,17 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
+
import { a as WATCHER_IGNORED_PATHS, i as UPDATE_CHECK_TIMEOUT_MS, n as KUBB_NPM_PACKAGE_URL, o as canUseTTY, t as Telemetry } from "./Telemetry-Cuzoes9Y.js";
|
|
2
3
|
import { n as toCause, r as toError } from "./errors-Dc_d7BfX.js";
|
|
3
|
-
import {
|
|
4
|
-
import { i as linters, n as detectTool, r as formatters } from "./tools-
|
|
5
|
-
import { t as version } from "./package-DKwwXnAz.js";
|
|
4
|
+
import { t as version } from "./package-D24TC3pS.js";
|
|
5
|
+
import { i as linters, n as detectTool, r as formatters } from "./tools-B23ltmWP.js";
|
|
6
6
|
import { styleText } from "node:util";
|
|
7
|
-
import
|
|
8
|
-
import { hash } from "node:crypto";
|
|
7
|
+
import process$1 from "node:process";
|
|
9
8
|
import { existsSync } from "node:fs";
|
|
10
9
|
import path, { basename, dirname, relative, resolve } from "node:path";
|
|
11
|
-
import process$1 from "node:process";
|
|
12
10
|
import * as clack from "@clack/prompts";
|
|
13
|
-
import { Diagnostics, cliReporter, createKubb, logLevel } from "@kubb/core";
|
|
11
|
+
import { Diagnostics, Hookable, cliReporter, createKubb, logLevel } from "@kubb/core";
|
|
14
12
|
import { createJiti } from "jiti";
|
|
15
13
|
import { NonZeroExitError, x } from "tinyexec";
|
|
16
14
|
import { loadConfig } from "unconfig";
|
|
17
|
-
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
18
|
-
/**
|
|
19
|
-
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
20
|
-
* Wraps Node's `EventEmitter` with full TypeScript event-map inference.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* const emitter = new AsyncEventEmitter<{ build: [name: string] }>()
|
|
25
|
-
* emitter.on('build', async (name) => { console.log(name) })
|
|
26
|
-
* await emitter.emit('build', 'petstore') // all listeners awaited
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
var AsyncEventEmitter = class {
|
|
30
|
-
/**
|
|
31
|
-
* Maximum number of listeners per event before Node emits a memory-leak warning.
|
|
32
|
-
* @default 10
|
|
33
|
-
*/
|
|
34
|
-
constructor(maxListener = 10) {
|
|
35
|
-
this.#emitter.setMaxListeners(maxListener);
|
|
36
|
-
}
|
|
37
|
-
#emitter = new EventEmitter();
|
|
38
|
-
/**
|
|
39
|
-
* Emits `eventName` and awaits all registered listeners sequentially.
|
|
40
|
-
* Throws if any listener rejects, wrapping the cause with the event name and serialized arguments.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* await emitter.emit('build', 'petstore')
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
emit(eventName, ...eventArgs) {
|
|
48
|
-
const listeners = this.#emitter.listeners(eventName);
|
|
49
|
-
if (listeners.length === 0) return;
|
|
50
|
-
return this.#emitAll(eventName, listeners, eventArgs);
|
|
51
|
-
}
|
|
52
|
-
async #emitAll(eventName, listeners, eventArgs) {
|
|
53
|
-
for (const listener of listeners) try {
|
|
54
|
-
await listener(...eventArgs);
|
|
55
|
-
} catch (err) {
|
|
56
|
-
let serializedArgs;
|
|
57
|
-
try {
|
|
58
|
-
serializedArgs = JSON.stringify(eventArgs);
|
|
59
|
-
} catch {
|
|
60
|
-
serializedArgs = String(eventArgs);
|
|
61
|
-
}
|
|
62
|
-
throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Registers a persistent listener for `eventName`.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* emitter.on('build', async (name) => { console.log(name) })
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
on(eventName, handler) {
|
|
74
|
-
this.#emitter.on(eventName, handler);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Removes a previously registered listener.
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```ts
|
|
81
|
-
* emitter.off('build', handler)
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
off(eventName, handler) {
|
|
85
|
-
this.#emitter.off(eventName, handler);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Returns the number of listeners registered for `eventName`.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* emitter.on('build', handler)
|
|
93
|
-
* emitter.listenerCount('build') // 1
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
listenerCount(eventName) {
|
|
97
|
-
return this.#emitter.listenerCount(eventName);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Raises or lowers the per-event listener ceiling before Node warns about a memory leak.
|
|
101
|
-
* Set this above the expected listener count when many listeners attach by design.
|
|
102
|
-
*
|
|
103
|
-
* @example
|
|
104
|
-
* ```ts
|
|
105
|
-
* emitter.setMaxListeners(40)
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
setMaxListeners(max) {
|
|
109
|
-
this.#emitter.setMaxListeners(max);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Removes all listeners from every event channel.
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```ts
|
|
116
|
-
* emitter.removeAll()
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
removeAll() {
|
|
120
|
-
this.#emitter.removeAllListeners();
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
//#endregion
|
|
124
15
|
//#region ../../internals/utils/src/time.ts
|
|
125
16
|
/**
|
|
126
17
|
* Calculates elapsed time in milliseconds from a high-resolution `process.hrtime` start time.
|
|
@@ -265,6 +156,43 @@ function formatMsWithColor(ms) {
|
|
|
265
156
|
return styleText("red", formatted);
|
|
266
157
|
}
|
|
267
158
|
//#endregion
|
|
159
|
+
//#region ../../internals/utils/src/promise.ts
|
|
160
|
+
/**
|
|
161
|
+
* Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight
|
|
162
|
+
* marks it dirty and runs once more after it finishes, no matter how many triggers arrived.
|
|
163
|
+
* Useful for event-driven reruns (a file watcher, a queue drain) where bursts should
|
|
164
|
+
* coalesce into a single trailing run.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* const rebuild = createSerialRunner({
|
|
169
|
+
* run: () => build(),
|
|
170
|
+
* onError: (error) => log.error(error.message),
|
|
171
|
+
* })
|
|
172
|
+
* watcher.on('change', () => void rebuild())
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
function createSerialRunner({ run, onError }) {
|
|
176
|
+
let running = false;
|
|
177
|
+
let dirty = false;
|
|
178
|
+
return async () => {
|
|
179
|
+
if (running) {
|
|
180
|
+
dirty = true;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
running = true;
|
|
184
|
+
do {
|
|
185
|
+
dirty = false;
|
|
186
|
+
try {
|
|
187
|
+
await run();
|
|
188
|
+
} catch (error) {
|
|
189
|
+
onError(toError(error));
|
|
190
|
+
}
|
|
191
|
+
} while (dirty);
|
|
192
|
+
running = false;
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
268
196
|
//#region src/loggers/defineLogger.ts
|
|
269
197
|
/**
|
|
270
198
|
* Type-safe helper for authoring a {@link Logger}.
|
|
@@ -274,7 +202,7 @@ function formatMsWithColor(ms) {
|
|
|
274
202
|
* export const myLogger = defineLogger({
|
|
275
203
|
* name: 'my-logger',
|
|
276
204
|
* install(context) {
|
|
277
|
-
* context.
|
|
205
|
+
* context.hook('kubb:info', ({ message }) => console.log('ℹ', message))
|
|
278
206
|
* },
|
|
279
207
|
* })
|
|
280
208
|
* ```
|
|
@@ -326,8 +254,8 @@ const clackLogger = defineLogger({
|
|
|
326
254
|
function getMessage(message) {
|
|
327
255
|
return formatMessage(message, logLevel$5);
|
|
328
256
|
}
|
|
329
|
-
function onStep(
|
|
330
|
-
context.
|
|
257
|
+
function onStep(hook, message) {
|
|
258
|
+
context.hook(hook, () => {
|
|
331
259
|
if (logLevel$5 <= logLevel.silent) return;
|
|
332
260
|
clack.log.step(getMessage(message));
|
|
333
261
|
});
|
|
@@ -337,7 +265,7 @@ const clackLogger = defineLogger({
|
|
|
337
265
|
state.spinner.stop(text);
|
|
338
266
|
state.isSpinning = false;
|
|
339
267
|
}
|
|
340
|
-
context.
|
|
268
|
+
context.hook("kubb:info", ({ message, info = "" }) => {
|
|
341
269
|
if (logLevel$5 <= logLevel.silent) return;
|
|
342
270
|
const text = getMessage([
|
|
343
271
|
styleText("blue", "ℹ"),
|
|
@@ -350,7 +278,7 @@ const clackLogger = defineLogger({
|
|
|
350
278
|
}
|
|
351
279
|
clack.log.info(text);
|
|
352
280
|
});
|
|
353
|
-
context.
|
|
281
|
+
context.hook("kubb:success", ({ message, info = "" }) => {
|
|
354
282
|
if (logLevel$5 <= logLevel.silent) return;
|
|
355
283
|
const text = getMessage([
|
|
356
284
|
styleText("blue", "✓"),
|
|
@@ -363,7 +291,7 @@ const clackLogger = defineLogger({
|
|
|
363
291
|
}
|
|
364
292
|
clack.log.success(text);
|
|
365
293
|
});
|
|
366
|
-
context.
|
|
294
|
+
context.hook("kubb:warn", ({ message, info }) => {
|
|
367
295
|
if (logLevel$5 < logLevel.warn) return;
|
|
368
296
|
const text = getMessage([
|
|
369
297
|
styleText("yellow", "⚠"),
|
|
@@ -372,25 +300,23 @@ const clackLogger = defineLogger({
|
|
|
372
300
|
].filter(Boolean).join(" "));
|
|
373
301
|
clack.log.warn(text);
|
|
374
302
|
});
|
|
375
|
-
context.
|
|
376
|
-
const caused = toCause(error);
|
|
303
|
+
context.hook("kubb:error", ({ error }) => {
|
|
377
304
|
const text = [styleText("red", "✗"), error.message].join(" ");
|
|
378
305
|
if (state.isSpinning) {
|
|
379
306
|
stopSpinner(getMessage(text));
|
|
380
307
|
return;
|
|
381
308
|
}
|
|
382
309
|
clack.log.error(getMessage(text));
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
for (const frame of frames) clack.log.message(getMessage(styleText("dim", frame
|
|
386
|
-
if (
|
|
387
|
-
clack.log.message(styleText("dim",
|
|
388
|
-
const
|
|
389
|
-
for (const frame of frames) clack.log.message(getMessage(` ${styleText("dim", frame.trim())}`));
|
|
310
|
+
const frames = logLevel$5 >= logLevel.verbose ? formatErrorFrames(error) : null;
|
|
311
|
+
if (frames) {
|
|
312
|
+
for (const frame of frames.frames) clack.log.message(getMessage(styleText("dim", frame)));
|
|
313
|
+
if (frames.cause) {
|
|
314
|
+
clack.log.message(styleText("dim", frames.cause.header));
|
|
315
|
+
for (const frame of frames.cause.frames) clack.log.message(getMessage(` ${styleText("dim", frame)}`));
|
|
390
316
|
}
|
|
391
317
|
}
|
|
392
318
|
});
|
|
393
|
-
context.
|
|
319
|
+
context.hook("kubb:diagnostic", ({ diagnostic }) => {
|
|
394
320
|
if (logLevel$5 <= logLevel.silent && diagnostic.severity !== "error") return;
|
|
395
321
|
stopSpinner();
|
|
396
322
|
stopActiveProgress();
|
|
@@ -412,7 +338,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
412
338
|
secondarySymbol: ""
|
|
413
339
|
});
|
|
414
340
|
});
|
|
415
|
-
context.
|
|
341
|
+
context.hook("kubb:lifecycle:start", async ({ version }) => {
|
|
416
342
|
console.log(`\n${getIntro({
|
|
417
343
|
title: "The meta framework for code generation",
|
|
418
344
|
description: "Ready to start",
|
|
@@ -421,14 +347,14 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
421
347
|
})}\n`);
|
|
422
348
|
reset();
|
|
423
349
|
});
|
|
424
|
-
context.
|
|
350
|
+
context.hook("kubb:generation:start", ({ config }) => {
|
|
425
351
|
reset();
|
|
426
352
|
state.totalPlugins = config.plugins?.length ?? 0;
|
|
427
353
|
if (logLevel$5 <= logLevel.silent) return;
|
|
428
354
|
const text = getMessage(["Generation started", config.name ? `for ${styleText("dim", config.name)}` : void 0].filter(Boolean).join(" "));
|
|
429
355
|
clack.intro(text);
|
|
430
356
|
});
|
|
431
|
-
context.
|
|
357
|
+
context.hook("kubb:plugin:start", ({ plugin }) => {
|
|
432
358
|
if (logLevel$5 <= logLevel.silent) return;
|
|
433
359
|
stopSpinner();
|
|
434
360
|
state.runningPlugins.add(plugin.name);
|
|
@@ -446,7 +372,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
446
372
|
progressBar.advance(state.completedPlugins + state.failedPlugins, pluginProgressText());
|
|
447
373
|
state.activeProgress.set("plugins", { progressBar });
|
|
448
374
|
});
|
|
449
|
-
context.
|
|
375
|
+
context.hook("kubb:plugin:end", ({ plugin, success }) => {
|
|
450
376
|
stopSpinner();
|
|
451
377
|
const active = state.activeProgress.get("plugins");
|
|
452
378
|
if (!active || logLevel$5 === logLevel.silent) return;
|
|
@@ -459,7 +385,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
459
385
|
showProgressStep();
|
|
460
386
|
}
|
|
461
387
|
});
|
|
462
|
-
context.
|
|
388
|
+
context.hook("kubb:files:processing:start", ({ files }) => {
|
|
463
389
|
if (logLevel$5 <= logLevel.silent) return;
|
|
464
390
|
stopSpinner();
|
|
465
391
|
state.totalFiles = files.length;
|
|
@@ -470,11 +396,11 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
470
396
|
max: files.length,
|
|
471
397
|
size: 30
|
|
472
398
|
});
|
|
473
|
-
context.
|
|
399
|
+
context.callHook("kubb:info", { message: text });
|
|
474
400
|
progressBar.start(getMessage(text));
|
|
475
401
|
state.activeProgress.set("files", { progressBar });
|
|
476
402
|
});
|
|
477
|
-
context.
|
|
403
|
+
context.hook("kubb:files:processing:update", ({ files }) => {
|
|
478
404
|
if (logLevel$5 <= logLevel.silent) return;
|
|
479
405
|
stopSpinner();
|
|
480
406
|
const active = state.activeProgress.get("files");
|
|
@@ -483,7 +409,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
483
409
|
if (active) active.progressBar.advance(void 0, `Writing ${relative(config.root, file.path)}`);
|
|
484
410
|
}
|
|
485
411
|
});
|
|
486
|
-
context.
|
|
412
|
+
context.hook("kubb:files:processing:end", () => {
|
|
487
413
|
if (logLevel$5 <= logLevel.silent) return;
|
|
488
414
|
stopSpinner();
|
|
489
415
|
const text = getMessage("Files written successfully");
|
|
@@ -493,7 +419,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
493
419
|
state.activeProgress.delete("files");
|
|
494
420
|
showProgressStep();
|
|
495
421
|
});
|
|
496
|
-
context.
|
|
422
|
+
context.hook("kubb:generation:end", ({ config }) => {
|
|
497
423
|
stopSpinner();
|
|
498
424
|
const text = getMessage(config.name ? `Generation completed for ${styleText("dim", config.name)}` : "Generation completed");
|
|
499
425
|
clack.outro(text);
|
|
@@ -501,7 +427,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
501
427
|
onStep("kubb:format:start", "Formatting");
|
|
502
428
|
onStep("kubb:lint:start", "Linting");
|
|
503
429
|
onStep("kubb:hooks:start", "Running hooks");
|
|
504
|
-
context.
|
|
430
|
+
context.hook("kubb:hook:start", ({ id, command, args }) => {
|
|
505
431
|
if (logLevel$5 <= logLevel.silent || !id) return;
|
|
506
432
|
stopSpinner();
|
|
507
433
|
const title = getMessage(`Running ${styleText("dim", formatCommandWithArgs(command, args))}`);
|
|
@@ -511,10 +437,10 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
511
437
|
hrStart: process$1.hrtime()
|
|
512
438
|
});
|
|
513
439
|
});
|
|
514
|
-
if (logLevel$5 > logLevel.silent) context.
|
|
440
|
+
if (logLevel$5 > logLevel.silent) context.hook("kubb:hook:line", ({ id, line }) => {
|
|
515
441
|
state.activeHookLogs.get(id)?.taskLog.message(styleText("dim", line));
|
|
516
442
|
});
|
|
517
|
-
context.
|
|
443
|
+
context.hook("kubb:hook:end", ({ id, command, args, success, error, stdout, stderr }) => {
|
|
518
444
|
if (!id) return;
|
|
519
445
|
if (logLevel$5 <= logLevel.silent) {
|
|
520
446
|
if (!success) {
|
|
@@ -534,7 +460,7 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
534
460
|
active.taskLog.error(getMessage(`${styleText("dim", commandWithArgs)} failed${reason}`), { showLog: true });
|
|
535
461
|
}
|
|
536
462
|
});
|
|
537
|
-
context.
|
|
463
|
+
context.hook("kubb:lifecycle:end", () => {
|
|
538
464
|
reset();
|
|
539
465
|
});
|
|
540
466
|
}
|
|
@@ -552,13 +478,13 @@ const plainLogger = defineLogger({
|
|
|
552
478
|
function getMessage(message) {
|
|
553
479
|
return formatMessage(message, logLevel$4);
|
|
554
480
|
}
|
|
555
|
-
function onStep(
|
|
556
|
-
context.
|
|
481
|
+
function onStep(hook, message) {
|
|
482
|
+
context.hook(hook, () => {
|
|
557
483
|
if (logLevel$4 <= logLevel.silent) return;
|
|
558
484
|
console.log(getMessage(message));
|
|
559
485
|
});
|
|
560
486
|
}
|
|
561
|
-
context.
|
|
487
|
+
context.hook("kubb:info", ({ message, info }) => {
|
|
562
488
|
if (logLevel$4 <= logLevel.silent) return;
|
|
563
489
|
const text = getMessage([
|
|
564
490
|
"ℹ",
|
|
@@ -567,7 +493,7 @@ const plainLogger = defineLogger({
|
|
|
567
493
|
].join(" "));
|
|
568
494
|
console.log(text);
|
|
569
495
|
});
|
|
570
|
-
context.
|
|
496
|
+
context.hook("kubb:success", ({ message, info = "" }) => {
|
|
571
497
|
if (logLevel$4 <= logLevel.silent) return;
|
|
572
498
|
const text = getMessage([
|
|
573
499
|
"✓",
|
|
@@ -576,7 +502,7 @@ const plainLogger = defineLogger({
|
|
|
576
502
|
].filter(Boolean).join(" "));
|
|
577
503
|
console.log(text);
|
|
578
504
|
});
|
|
579
|
-
context.
|
|
505
|
+
context.hook("kubb:warn", ({ message, info }) => {
|
|
580
506
|
if (logLevel$4 < logLevel.warn) return;
|
|
581
507
|
const text = getMessage([
|
|
582
508
|
"⚠",
|
|
@@ -585,57 +511,55 @@ const plainLogger = defineLogger({
|
|
|
585
511
|
].filter(Boolean).join(" "));
|
|
586
512
|
console.log(text);
|
|
587
513
|
});
|
|
588
|
-
context.
|
|
589
|
-
const caused = toCause(error);
|
|
514
|
+
context.hook("kubb:error", ({ error }) => {
|
|
590
515
|
const text = getMessage(["✗", error.message].join(" "));
|
|
591
516
|
console.log(text);
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
for (const frame of frames) console.log(getMessage(frame
|
|
595
|
-
if (
|
|
596
|
-
console.log(
|
|
597
|
-
const
|
|
598
|
-
for (const frame of frames) console.log(getMessage(` ${frame.trim()}`));
|
|
517
|
+
const frames = logLevel$4 >= logLevel.verbose ? formatErrorFrames(error) : null;
|
|
518
|
+
if (frames) {
|
|
519
|
+
for (const frame of frames.frames) console.log(getMessage(frame));
|
|
520
|
+
if (frames.cause) {
|
|
521
|
+
console.log(frames.cause.header);
|
|
522
|
+
for (const frame of frames.cause.frames) console.log(getMessage(` ${frame}`));
|
|
599
523
|
}
|
|
600
524
|
}
|
|
601
525
|
});
|
|
602
|
-
context.
|
|
526
|
+
context.hook("kubb:diagnostic", ({ diagnostic }) => {
|
|
603
527
|
if (logLevel$4 <= logLevel.silent && diagnostic.severity !== "error") return;
|
|
604
528
|
console.log(getMessage(Diagnostics.formatLines(diagnostic).join("\n")));
|
|
605
529
|
});
|
|
606
|
-
context.
|
|
530
|
+
context.hook("kubb:lifecycle:start", ({ version }) => {
|
|
607
531
|
console.log(`Kubb CLI v${version}`);
|
|
608
532
|
});
|
|
609
|
-
context.
|
|
533
|
+
context.hook("kubb:generation:start", () => {
|
|
610
534
|
const text = getMessage("Generation started");
|
|
611
535
|
console.log(text);
|
|
612
536
|
});
|
|
613
|
-
context.
|
|
537
|
+
context.hook("kubb:plugin:start", ({ plugin }) => {
|
|
614
538
|
if (logLevel$4 <= logLevel.silent) return;
|
|
615
539
|
const text = getMessage(`Generating ${plugin.name}`);
|
|
616
540
|
console.log(text);
|
|
617
541
|
});
|
|
618
|
-
context.
|
|
542
|
+
context.hook("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
619
543
|
if (logLevel$4 <= logLevel.silent) return;
|
|
620
544
|
const durationStr = formatMs(duration);
|
|
621
545
|
const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`);
|
|
622
546
|
console.log(text);
|
|
623
547
|
});
|
|
624
|
-
context.
|
|
548
|
+
context.hook("kubb:files:processing:start", ({ files }) => {
|
|
625
549
|
if (logLevel$4 <= logLevel.silent) return;
|
|
626
550
|
const text = getMessage(`Writing ${files.length} files`);
|
|
627
551
|
console.log(text);
|
|
628
552
|
});
|
|
629
|
-
context.
|
|
553
|
+
context.hook("kubb:files:processing:update", ({ files }) => {
|
|
630
554
|
if (logLevel$4 <= logLevel.silent) return;
|
|
631
555
|
for (const { file, config } of files) console.log(getMessage(`Writing ${relative(config.root, file.path)}`));
|
|
632
556
|
});
|
|
633
|
-
context.
|
|
557
|
+
context.hook("kubb:files:processing:end", () => {
|
|
634
558
|
if (logLevel$4 <= logLevel.silent) return;
|
|
635
559
|
const text = getMessage("Files written successfully");
|
|
636
560
|
console.log(text);
|
|
637
561
|
});
|
|
638
|
-
context.
|
|
562
|
+
context.hook("kubb:generation:end", ({ config }) => {
|
|
639
563
|
const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
|
|
640
564
|
console.log(text);
|
|
641
565
|
});
|
|
@@ -645,13 +569,13 @@ const plainLogger = defineLogger({
|
|
|
645
569
|
onStep("kubb:lint:end", "Lint completed");
|
|
646
570
|
onStep("kubb:hooks:start", "Hooks started");
|
|
647
571
|
onStep("kubb:hooks:end", "Hooks completed");
|
|
648
|
-
context.
|
|
572
|
+
context.hook("kubb:hook:start", ({ id, command, args }) => {
|
|
649
573
|
if (logLevel$4 <= logLevel.silent) return;
|
|
650
574
|
if (id) hookTimer.start(id);
|
|
651
575
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
652
576
|
console.log(getMessage(`Hook ${commandWithArgs} started`));
|
|
653
577
|
});
|
|
654
|
-
context.
|
|
578
|
+
context.hook("kubb:hook:end", ({ id, command, args, success, error, stdout, stderr }) => {
|
|
655
579
|
if (logLevel$4 <= logLevel.silent) return;
|
|
656
580
|
const ms = id ? hookTimer.end(id) : void 0;
|
|
657
581
|
const durationStr = ms !== void 0 ? ` in ${formatMs(ms)}` : "";
|
|
@@ -682,6 +606,22 @@ function formatMessage(message, logLevel$3) {
|
|
|
682
606
|
return message;
|
|
683
607
|
}
|
|
684
608
|
/**
|
|
609
|
+
* First stack frames for verbose error output, including an optional `cause` chain.
|
|
610
|
+
*/
|
|
611
|
+
function formatErrorFrames(error) {
|
|
612
|
+
if (!error.stack) return null;
|
|
613
|
+
const frames = error.stack.split("\n").slice(1, 4).map((frame) => frame.trim());
|
|
614
|
+
const caused = toCause(error);
|
|
615
|
+
if (!caused?.stack) return { frames };
|
|
616
|
+
return {
|
|
617
|
+
frames,
|
|
618
|
+
cause: {
|
|
619
|
+
header: `└─ caused by ${caused.message}`,
|
|
620
|
+
frames: caused.stack.split("\n").slice(1, 4).map((frame) => frame.trim())
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
685
625
|
* Build the progress summary line shown by the clack logger.
|
|
686
626
|
* Returns null when there is nothing to display.
|
|
687
627
|
*/
|
|
@@ -742,9 +682,6 @@ function createHookTimer() {
|
|
|
742
682
|
if (!hrStart) return;
|
|
743
683
|
starts.delete(id);
|
|
744
684
|
return getElapsedMs(hrStart);
|
|
745
|
-
},
|
|
746
|
-
clear() {
|
|
747
|
-
starts.clear();
|
|
748
685
|
}
|
|
749
686
|
};
|
|
750
687
|
}
|
|
@@ -757,20 +694,12 @@ function createHookTimer() {
|
|
|
757
694
|
function formatCommandWithArgs(command, args) {
|
|
758
695
|
return args?.length ? `${command} ${args.join(" ")}` : command;
|
|
759
696
|
}
|
|
760
|
-
function detectLogger() {
|
|
761
|
-
if (canUseTTY()) return "clack";
|
|
762
|
-
return "plain";
|
|
763
|
-
}
|
|
764
|
-
const logMapper = {
|
|
765
|
-
clack: clackLogger,
|
|
766
|
-
plain: plainLogger
|
|
767
|
-
};
|
|
768
697
|
/**
|
|
769
|
-
* Bridges a {@link Reporter} onto the run's
|
|
698
|
+
* Bridges a {@link Reporter} onto the run's hook emitter: calls `report` with each config's
|
|
770
699
|
* {@link GenerationResult} on `kubb:generation:end`. The reporter never touches the emitter.
|
|
771
700
|
*/
|
|
772
701
|
function installReporter(context, reporter, ctx) {
|
|
773
|
-
context.
|
|
702
|
+
context.hook("kubb:generation:end", async ({ config, diagnostics = [], filesCreated = 0, status = "success", hrStart = process$1.hrtime() }) => {
|
|
774
703
|
await reporter.report({
|
|
775
704
|
config,
|
|
776
705
|
diagnostics,
|
|
@@ -779,7 +708,7 @@ function installReporter(context, reporter, ctx) {
|
|
|
779
708
|
hrStart
|
|
780
709
|
}, ctx);
|
|
781
710
|
});
|
|
782
|
-
if (reporter.drain) context.
|
|
711
|
+
if (reporter.drain) context.hook("kubb:lifecycle:end", () => reporter.drain?.(ctx));
|
|
783
712
|
}
|
|
784
713
|
/**
|
|
785
714
|
* Installs the live logger (the TUI view) and the given reporters (the output). The reporters are
|
|
@@ -798,10 +727,7 @@ async function setupReporters(context, { logLevel, reporters }) {
|
|
|
798
727
|
for (const reporter of reporters) {
|
|
799
728
|
if (reporter.name === "cli") {
|
|
800
729
|
if (hasJson) continue;
|
|
801
|
-
|
|
802
|
-
const logger = logMapper[type];
|
|
803
|
-
if (!logger) throw new Error(`Unknown adapter type: ${type}`);
|
|
804
|
-
await logger.install(context, { logLevel });
|
|
730
|
+
await (canUseTTY() ? clackLogger : plainLogger).install(context, { logLevel });
|
|
805
731
|
}
|
|
806
732
|
installReporter(context, reporter, ctx);
|
|
807
733
|
}
|
|
@@ -912,6 +838,34 @@ async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
|
912
838
|
}))
|
|
913
839
|
};
|
|
914
840
|
}
|
|
841
|
+
let hookSequence = 0;
|
|
842
|
+
/**
|
|
843
|
+
* Returns a process-unique id that correlates a hook's `kubb:hook:start` and `kubb:hook:end`
|
|
844
|
+
* emissions, which loggers use to key their per-hook state.
|
|
845
|
+
*/
|
|
846
|
+
function createHookId() {
|
|
847
|
+
hookSequence += 1;
|
|
848
|
+
return `hook-${hookSequence}`;
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Returns `true` when `latest` is a newer semver version than `current`. Compares each numeric
|
|
852
|
+
* part, so `5.10.0` beats `5.9.0` where a plain string comparison would not. Prerelease
|
|
853
|
+
* suffixes are ignored, and a malformed version never reports an update.
|
|
854
|
+
*
|
|
855
|
+
* @example Double-digit minor
|
|
856
|
+
* `isNewerVersion('5.9.0', '5.10.0') // true`
|
|
857
|
+
*
|
|
858
|
+
* @example String comparison would get this wrong the other way
|
|
859
|
+
* `isNewerVersion('5.10.0', '5.9.0') // false`
|
|
860
|
+
*/
|
|
861
|
+
function isNewerVersion(current, latest) {
|
|
862
|
+
const release = (value) => value.split("-")[0] ?? "";
|
|
863
|
+
const isNumeric = (value) => /^\d+(\.\d+)*$/.test(value);
|
|
864
|
+
const currentRelease = release(current);
|
|
865
|
+
const latestRelease = release(latest);
|
|
866
|
+
if (!isNumeric(currentRelease) || !isNumeric(latestRelease)) return false;
|
|
867
|
+
return currentRelease.localeCompare(latestRelease, void 0, { numeric: true }) < 0;
|
|
868
|
+
}
|
|
915
869
|
/**
|
|
916
870
|
* Tokenizes a shell command string, respecting single and double quotes.
|
|
917
871
|
*
|
|
@@ -925,65 +879,74 @@ function tokenize(command) {
|
|
|
925
879
|
return (command.match(/[^\s"']+|"([^"]*)"|'([^']*)'/g) ?? []).map((token) => token.replace(/^["']|["']$/g, ""));
|
|
926
880
|
}
|
|
927
881
|
/**
|
|
928
|
-
* Runs the `done` hooks defined in a Kubb config in sequence
|
|
882
|
+
* Runs the `done` hooks defined in a Kubb config in sequence and returns each hook's outcome,
|
|
883
|
+
* so the caller can turn failures into diagnostics.
|
|
929
884
|
*/
|
|
930
885
|
async function executeHooks({ configHooks, hooks }) {
|
|
931
886
|
const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
|
|
887
|
+
const results = [];
|
|
932
888
|
for (const command of commands) {
|
|
933
889
|
const [cmd, ...args] = tokenize(command);
|
|
934
890
|
if (!cmd) continue;
|
|
935
|
-
const hookId =
|
|
891
|
+
const hookId = createHookId();
|
|
936
892
|
const commandWithArgs = [cmd, ...args].join(" ");
|
|
937
|
-
await hooks.
|
|
893
|
+
await hooks.callHook("kubb:hook:start", {
|
|
938
894
|
id: hookId,
|
|
939
895
|
command: cmd,
|
|
940
896
|
args
|
|
941
897
|
});
|
|
942
|
-
await runHook({
|
|
898
|
+
results.push(await runHook({
|
|
943
899
|
id: hookId,
|
|
944
900
|
command: cmd,
|
|
945
901
|
args,
|
|
946
902
|
commandWithArgs,
|
|
947
903
|
hooks
|
|
948
|
-
});
|
|
904
|
+
}));
|
|
949
905
|
}
|
|
906
|
+
return results;
|
|
950
907
|
}
|
|
951
908
|
/**
|
|
952
|
-
* Spawns a hook command and
|
|
953
|
-
* A non-zero exit
|
|
909
|
+
* Spawns a hook command and returns its outcome, mirroring it through `kubb:hook:end` for the
|
|
910
|
+
* loggers. A non-zero exit returns `success: false` rather than throwing, so the caller can turn
|
|
954
911
|
* it into a diagnostic. Other spawn errors do the same. Output is streamed through `kubb:hook:line`
|
|
955
912
|
* only while a listener is attached.
|
|
956
913
|
*/
|
|
957
914
|
async function runHook({ id, command, args, commandWithArgs, hooks }) {
|
|
958
|
-
const emitEnd = (
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
915
|
+
const emitEnd = async (result) => {
|
|
916
|
+
await hooks.callHook("kubb:hook:end", {
|
|
917
|
+
command,
|
|
918
|
+
args,
|
|
919
|
+
id,
|
|
920
|
+
...result
|
|
921
|
+
});
|
|
922
|
+
return result;
|
|
923
|
+
};
|
|
966
924
|
const stream = hooks.listenerCount("kubb:hook:line") > 0;
|
|
967
925
|
try {
|
|
968
926
|
const proc = x(command, [...args ?? []], {
|
|
969
927
|
nodeOptions: { detached: process$1.platform !== "win32" },
|
|
970
928
|
throwOnError: true
|
|
971
929
|
});
|
|
972
|
-
if (stream) for await (const line of proc) await hooks.
|
|
930
|
+
if (stream) for await (const line of proc) await hooks.callHook("kubb:hook:line", {
|
|
973
931
|
id,
|
|
974
932
|
line
|
|
975
933
|
});
|
|
976
934
|
await proc;
|
|
977
|
-
await hooks.
|
|
978
|
-
|
|
935
|
+
await hooks.callHook("kubb:success", { message: `${styleText("dim", commandWithArgs)} successfully executed` });
|
|
936
|
+
return emitEnd({
|
|
937
|
+
success: true,
|
|
938
|
+
error: null
|
|
939
|
+
});
|
|
979
940
|
} catch (err) {
|
|
980
|
-
if (!(err instanceof NonZeroExitError)) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
}
|
|
941
|
+
if (!(err instanceof NonZeroExitError)) return emitEnd({
|
|
942
|
+
success: false,
|
|
943
|
+
error: toError(err)
|
|
944
|
+
});
|
|
984
945
|
const stderr = err.output?.stderr ?? "";
|
|
985
946
|
const stdout = err.output?.stdout ?? "";
|
|
986
|
-
|
|
947
|
+
return emitEnd({
|
|
948
|
+
success: false,
|
|
949
|
+
error: /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`),
|
|
987
950
|
stdout,
|
|
988
951
|
stderr
|
|
989
952
|
});
|
|
@@ -991,7 +954,9 @@ async function runHook({ id, command, args, commandWithArgs, hooks }) {
|
|
|
991
954
|
}
|
|
992
955
|
/**
|
|
993
956
|
* Starts a file watcher on the given paths and calls `cb` on any change.
|
|
994
|
-
* Ignores `.git` and `node_modules` directories.
|
|
957
|
+
* Ignores `.git` and `node_modules` directories. Event bursts (an editor save emits several)
|
|
958
|
+
* are debounced into one build, and builds never overlap: changes during a build queue exactly
|
|
959
|
+
* one rebuild.
|
|
995
960
|
*/
|
|
996
961
|
async function startWatcher(path, cb, log = {
|
|
997
962
|
info: console.log,
|
|
@@ -1000,7 +965,8 @@ async function startWatcher(path, cb, log = {
|
|
|
1000
965
|
const { watch } = await import("chokidar");
|
|
1001
966
|
const watcher = watch(path, {
|
|
1002
967
|
ignorePermissionErrors: true,
|
|
1003
|
-
ignored: WATCHER_IGNORED_PATHS
|
|
968
|
+
ignored: WATCHER_IGNORED_PATHS,
|
|
969
|
+
ignoreInitial: true
|
|
1004
970
|
});
|
|
1005
971
|
process$1.once("SIGINT", () => {
|
|
1006
972
|
watcher.close();
|
|
@@ -1008,78 +974,70 @@ async function startWatcher(path, cb, log = {
|
|
|
1008
974
|
process$1.once("SIGTERM", () => {
|
|
1009
975
|
watcher.close();
|
|
1010
976
|
});
|
|
1011
|
-
|
|
977
|
+
const runBuild = createSerialRunner({
|
|
978
|
+
run: () => cb(path),
|
|
979
|
+
onError: () => log.error(styleText("red", "Watcher failed"))
|
|
980
|
+
});
|
|
981
|
+
let debounceTimer = null;
|
|
982
|
+
watcher.on("all", (type, file) => {
|
|
1012
983
|
log.info(styleText("yellow", styleText("bold", `Change detected: ${type} ${file}`)));
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
}
|
|
984
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
985
|
+
debounceTimer = setTimeout(() => {
|
|
986
|
+
debounceTimer = null;
|
|
987
|
+
runBuild();
|
|
988
|
+
}, 100);
|
|
1018
989
|
});
|
|
1019
990
|
}
|
|
1020
991
|
//#endregion
|
|
1021
992
|
//#region src/runners/generate/run.ts
|
|
1022
993
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
* so
|
|
994
|
+
* Runs one formatter or linter pass over the output directory. Returns the failure instead of
|
|
995
|
+
* throwing, so the caller can turn it into a coded diagnostic. Failures never render here:
|
|
996
|
+
* the caller emits them through `Diagnostics.emit`, like every other diagnostic.
|
|
1025
997
|
*/
|
|
1026
|
-
function
|
|
1027
|
-
return new Promise((resolve, reject) => {
|
|
1028
|
-
const handler = (ctx) => {
|
|
1029
|
-
if (ctx.id !== hookId) return;
|
|
1030
|
-
hooks.off("kubb:hook:end", handler);
|
|
1031
|
-
if (!ctx.success) {
|
|
1032
|
-
reject(ctx.error ?? new Error(fallbackErrorMessage));
|
|
1033
|
-
return;
|
|
1034
|
-
}
|
|
1035
|
-
Promise.resolve(onSuccess()).then(resolve).catch(reject);
|
|
1036
|
-
};
|
|
1037
|
-
hooks.on("kubb:hook:end", handler);
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel: logLevel$1, hooks, onStart, onEnd }) {
|
|
998
|
+
async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, outputPath, logLevel: logLevel$1, hooks, onStart, onEnd }) {
|
|
1041
999
|
await onStart();
|
|
1042
1000
|
let resolvedTool = toolValue;
|
|
1043
1001
|
if (resolvedTool === "auto") {
|
|
1044
1002
|
const detected = await detect();
|
|
1045
|
-
if (!detected) await hooks.
|
|
1003
|
+
if (!detected) await hooks.callHook("kubb:warn", { message: noToolMessage });
|
|
1046
1004
|
else {
|
|
1047
1005
|
resolvedTool = detected;
|
|
1048
|
-
await hooks.
|
|
1006
|
+
await hooks.callHook("kubb:info", { message: `Auto-detected ${toolLabel}: ${styleText("dim", resolvedTool)}` });
|
|
1049
1007
|
}
|
|
1050
1008
|
}
|
|
1051
|
-
let toolError;
|
|
1009
|
+
let toolError = null;
|
|
1052
1010
|
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap && existsSync(outputPath)) {
|
|
1053
1011
|
const toolConfig = toolMap[resolvedTool];
|
|
1054
|
-
const hookId = hash("sha256", [configName, resolvedTool].filter(Boolean).join("-"), "hex");
|
|
1055
1012
|
const successMessage = [
|
|
1056
1013
|
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1057
1014
|
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1058
1015
|
"successfully"
|
|
1059
1016
|
].filter(Boolean).join(" ");
|
|
1060
1017
|
try {
|
|
1018
|
+
const hookId = createHookId();
|
|
1061
1019
|
const hookArgs = toolConfig.args(outputPath);
|
|
1062
1020
|
const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
|
|
1063
|
-
|
|
1064
|
-
await hooks.emit("kubb:hook:start", {
|
|
1021
|
+
await hooks.callHook("kubb:hook:start", {
|
|
1065
1022
|
id: hookId,
|
|
1066
1023
|
command: toolConfig.command,
|
|
1067
1024
|
args: hookArgs
|
|
1068
1025
|
});
|
|
1069
|
-
runHook({
|
|
1026
|
+
const result = await runHook({
|
|
1070
1027
|
id: hookId,
|
|
1071
1028
|
command: toolConfig.command,
|
|
1072
1029
|
args: hookArgs,
|
|
1073
1030
|
commandWithArgs,
|
|
1074
1031
|
hooks
|
|
1075
|
-
})
|
|
1076
|
-
await
|
|
1032
|
+
});
|
|
1033
|
+
if (result.success) await hooks.callHook("kubb:success", { message: successMessage });
|
|
1034
|
+
else toolError = result.error ?? new Error(toolConfig.errorMessage);
|
|
1077
1035
|
} catch (caughtError) {
|
|
1078
1036
|
toolError = toError(caughtError);
|
|
1079
1037
|
}
|
|
1080
1038
|
}
|
|
1081
1039
|
await onEnd();
|
|
1082
|
-
|
|
1040
|
+
return toolError;
|
|
1083
1041
|
}
|
|
1084
1042
|
async function generate(options) {
|
|
1085
1043
|
const { input, hooks, logLevel } = options;
|
|
@@ -1090,22 +1048,21 @@ async function generate(options) {
|
|
|
1090
1048
|
input: inputPath ? {
|
|
1091
1049
|
...options.config.input,
|
|
1092
1050
|
path: inputPath
|
|
1093
|
-
} : options.config.input
|
|
1094
|
-
...options.config.output
|
|
1051
|
+
} : options.config.input
|
|
1095
1052
|
};
|
|
1096
1053
|
const kubb = createKubb(config, { hooks });
|
|
1097
|
-
await hooks.
|
|
1098
|
-
await hooks.
|
|
1054
|
+
await hooks.callHook("kubb:generation:start", { config });
|
|
1055
|
+
await hooks.callHook("kubb:info", {
|
|
1099
1056
|
message: config.name ? `Setup generation ${styleText("bold", config.name)}` : "Setup generation",
|
|
1100
1057
|
info: inputPath
|
|
1101
1058
|
});
|
|
1102
1059
|
await kubb.setup();
|
|
1103
|
-
await hooks.
|
|
1060
|
+
await hooks.callHook("kubb:info", {
|
|
1104
1061
|
message: config.name ? `Build generation ${styleText("bold", config.name)}` : "Build generation",
|
|
1105
1062
|
info: inputPath
|
|
1106
1063
|
});
|
|
1107
1064
|
const { files, diagnostics, driver } = await kubb.safeBuild();
|
|
1108
|
-
await hooks.
|
|
1065
|
+
await hooks.callHook("kubb:info", { message: "Load summary" });
|
|
1109
1066
|
const telemetryPlugins = Array.from(driver.plugins.values(), (p) => ({
|
|
1110
1067
|
name: p.name,
|
|
1111
1068
|
options: p.options
|
|
@@ -1121,11 +1078,11 @@ async function generate(options) {
|
|
|
1121
1078
|
for (const diagnostic of diagnostics) {
|
|
1122
1079
|
if (!Diagnostics.isProblem(diagnostic)) continue;
|
|
1123
1080
|
const unknown = Diagnostics.narrow(diagnostic, Diagnostics.code.unknown);
|
|
1124
|
-
if (unknown) await hooks.
|
|
1081
|
+
if (unknown) await hooks.callHook("kubb:error", { error: unknown.cause ?? new Error(unknown.message) });
|
|
1125
1082
|
else await Diagnostics.emit(hooks, diagnostic);
|
|
1126
1083
|
}
|
|
1127
1084
|
if (Diagnostics.hasError(diagnostics)) {
|
|
1128
|
-
await hooks.
|
|
1085
|
+
await hooks.callHook("kubb:generation:end", {
|
|
1129
1086
|
config,
|
|
1130
1087
|
storage: kubb.storage,
|
|
1131
1088
|
diagnostics,
|
|
@@ -1138,77 +1095,70 @@ async function generate(options) {
|
|
|
1138
1095
|
}
|
|
1139
1096
|
const outputPath = path.resolve(config.root, config.output.path);
|
|
1140
1097
|
const outputDiagnostics = [];
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
"
|
|
1160
|
-
"biome",
|
|
1161
|
-
"eslint"
|
|
1162
|
-
]),
|
|
1163
|
-
toolMap: linters,
|
|
1164
|
-
toolLabel: "linter",
|
|
1165
|
-
successPrefix: "Linting",
|
|
1166
|
-
noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
|
|
1167
|
-
onStart: () => hooks.emit("kubb:lint:start"),
|
|
1168
|
-
onEnd: () => hooks.emit("kubb:lint:end")
|
|
1169
|
-
}].filter(Boolean);
|
|
1170
|
-
for (const { code, ...pass } of toolPasses) try {
|
|
1171
|
-
await runToolPass({
|
|
1172
|
-
...pass,
|
|
1173
|
-
configName: config.name,
|
|
1098
|
+
const reportOutputFailure = async (code, label, error) => {
|
|
1099
|
+
const diagnostic = outputDiagnostic(code, label, error);
|
|
1100
|
+
outputDiagnostics.push(diagnostic);
|
|
1101
|
+
await Diagnostics.emit(hooks, diagnostic);
|
|
1102
|
+
};
|
|
1103
|
+
if (config.output.format) {
|
|
1104
|
+
const error = await runToolPass({
|
|
1105
|
+
toolValue: config.output.format,
|
|
1106
|
+
detect: () => detectTool([
|
|
1107
|
+
"oxfmt",
|
|
1108
|
+
"biome",
|
|
1109
|
+
"prettier"
|
|
1110
|
+
]),
|
|
1111
|
+
toolMap: formatters,
|
|
1112
|
+
toolLabel: "formatter",
|
|
1113
|
+
successPrefix: "Formatting",
|
|
1114
|
+
noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
|
|
1115
|
+
onStart: () => hooks.callHook("kubb:format:start"),
|
|
1116
|
+
onEnd: () => hooks.callHook("kubb:format:end"),
|
|
1174
1117
|
outputPath,
|
|
1175
1118
|
logLevel,
|
|
1176
1119
|
hooks
|
|
1177
1120
|
});
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
await
|
|
1121
|
+
if (error) await reportOutputFailure(Diagnostics.code.formatFailed, "formatter", error);
|
|
1122
|
+
}
|
|
1123
|
+
if (config.output.lint) {
|
|
1124
|
+
const error = await runToolPass({
|
|
1125
|
+
toolValue: config.output.lint,
|
|
1126
|
+
detect: () => detectTool([
|
|
1127
|
+
"oxlint",
|
|
1128
|
+
"biome",
|
|
1129
|
+
"eslint"
|
|
1130
|
+
]),
|
|
1131
|
+
toolMap: linters,
|
|
1132
|
+
toolLabel: "linter",
|
|
1133
|
+
successPrefix: "Linting",
|
|
1134
|
+
noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
|
|
1135
|
+
onStart: () => hooks.callHook("kubb:lint:start"),
|
|
1136
|
+
onEnd: () => hooks.callHook("kubb:lint:end"),
|
|
1137
|
+
outputPath,
|
|
1138
|
+
logLevel,
|
|
1139
|
+
hooks
|
|
1140
|
+
});
|
|
1141
|
+
if (error) await reportOutputFailure(Diagnostics.code.lintFailed, "linter", error);
|
|
1182
1142
|
}
|
|
1183
1143
|
if (config.hooks) {
|
|
1184
|
-
await hooks.
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
};
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
await
|
|
1192
|
-
configHooks: config.hooks,
|
|
1193
|
-
hooks
|
|
1194
|
-
});
|
|
1195
|
-
} finally {
|
|
1196
|
-
hooks.off("kubb:hook:end", onHookEnd);
|
|
1197
|
-
}
|
|
1198
|
-
for (const error of hookFailures) {
|
|
1199
|
-
const diagnostic = outputDiagnostic(Diagnostics.code.hookFailed, "Post-generate hook", error);
|
|
1200
|
-
outputDiagnostics.push(diagnostic);
|
|
1201
|
-
await Diagnostics.emit(hooks, diagnostic);
|
|
1144
|
+
await hooks.callHook("kubb:hooks:start");
|
|
1145
|
+
const hookResults = await executeHooks({
|
|
1146
|
+
configHooks: config.hooks,
|
|
1147
|
+
hooks
|
|
1148
|
+
});
|
|
1149
|
+
for (const result of hookResults) {
|
|
1150
|
+
if (result.success) continue;
|
|
1151
|
+
await reportOutputFailure(Diagnostics.code.hookFailed, "Post-generate hook", result.error ?? /* @__PURE__ */ new Error("Post-generate hook failed"));
|
|
1202
1152
|
}
|
|
1203
|
-
await hooks.
|
|
1153
|
+
await hooks.callHook("kubb:hooks:end");
|
|
1204
1154
|
}
|
|
1205
1155
|
const finalDiagnostics = [...diagnostics, ...outputDiagnostics];
|
|
1206
1156
|
const failed = Diagnostics.hasError(outputDiagnostics);
|
|
1207
|
-
if (!failed) await hooks.
|
|
1157
|
+
if (!failed) await hooks.callHook("kubb:success", {
|
|
1208
1158
|
message: "Generation succeeded",
|
|
1209
1159
|
info: inputPath
|
|
1210
1160
|
});
|
|
1211
|
-
await hooks.
|
|
1161
|
+
await hooks.callHook("kubb:generation:end", {
|
|
1212
1162
|
config,
|
|
1213
1163
|
storage: kubb.storage,
|
|
1214
1164
|
diagnostics: finalDiagnostics,
|
|
@@ -1235,8 +1185,8 @@ function outputDiagnostic(code, label, caughtError) {
|
|
|
1235
1185
|
}
|
|
1236
1186
|
async function checkForUpdate(hooks) {
|
|
1237
1187
|
try {
|
|
1238
|
-
const data = await (await fetch(KUBB_NPM_PACKAGE_URL)).json();
|
|
1239
|
-
if (data.version && version
|
|
1188
|
+
const data = await (await fetch(KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(UPDATE_CHECK_TIMEOUT_MS) })).json();
|
|
1189
|
+
if (data.version && isNewerVersion(version, data.version)) await Diagnostics.emit(hooks, Diagnostics.update({
|
|
1240
1190
|
currentVersion: version,
|
|
1241
1191
|
latestVersion: data.version
|
|
1242
1192
|
}));
|
|
@@ -1249,7 +1199,7 @@ async function checkForUpdate(hooks) {
|
|
|
1249
1199
|
*/
|
|
1250
1200
|
async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters }) {
|
|
1251
1201
|
const logLevel$2 = logLevel[logLevelKey] ?? logLevel.info;
|
|
1252
|
-
const hooks = new
|
|
1202
|
+
const hooks = new Hookable();
|
|
1253
1203
|
let configs;
|
|
1254
1204
|
let resolvedConfigPath;
|
|
1255
1205
|
try {
|
|
@@ -1266,7 +1216,7 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
1266
1216
|
logLevel: logLevel$2,
|
|
1267
1217
|
reporters: [cliReporter]
|
|
1268
1218
|
});
|
|
1269
|
-
await hooks.
|
|
1219
|
+
await hooks.callHook("kubb:error", { error: toError(error) });
|
|
1270
1220
|
process$1.exit(1);
|
|
1271
1221
|
}
|
|
1272
1222
|
const requestedNames = cliReporters?.length ? cliReporters : ["cli"];
|
|
@@ -1274,32 +1224,40 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
1274
1224
|
logLevel: logLevel$2,
|
|
1275
1225
|
reporters: selectReporters(configs[0]?.reporters ?? [], requestedNames)
|
|
1276
1226
|
});
|
|
1277
|
-
await hooks.
|
|
1227
|
+
await hooks.callHook("kubb:lifecycle:start", { version });
|
|
1278
1228
|
await checkForUpdate(hooks);
|
|
1279
1229
|
try {
|
|
1280
1230
|
const relativeConfigPath = path.relative(process$1.cwd(), resolvedConfigPath);
|
|
1281
|
-
await hooks.
|
|
1231
|
+
await hooks.callHook("kubb:info", {
|
|
1282
1232
|
message: "Config loaded",
|
|
1283
1233
|
info: relativeConfigPath
|
|
1284
1234
|
});
|
|
1285
|
-
await hooks.
|
|
1235
|
+
await hooks.callHook("kubb:success", {
|
|
1286
1236
|
message: "Config loaded successfully",
|
|
1287
1237
|
info: relativeConfigPath
|
|
1288
1238
|
});
|
|
1289
1239
|
let anyFailed = false;
|
|
1290
|
-
for (const config of configs) if (config.input && "path" in config.input && watch)
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1240
|
+
for (const config of configs) if (config.input && "path" in config.input && watch) {
|
|
1241
|
+
const watchedPaths = [input || config.input.path];
|
|
1242
|
+
const build = async (paths) => {
|
|
1243
|
+
await generate({
|
|
1244
|
+
input,
|
|
1245
|
+
config,
|
|
1246
|
+
logLevel: logLevel$2,
|
|
1247
|
+
hooks
|
|
1248
|
+
});
|
|
1249
|
+
clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
1250
|
+
};
|
|
1251
|
+
try {
|
|
1252
|
+
await build(watchedPaths);
|
|
1253
|
+
} catch (buildError) {
|
|
1254
|
+
await hooks.callHook("kubb:error", { error: toError(buildError) });
|
|
1255
|
+
}
|
|
1256
|
+
await startWatcher(watchedPaths, build, {
|
|
1257
|
+
info: (msg) => clack.log.info(msg),
|
|
1258
|
+
error: (msg) => clack.log.error(msg)
|
|
1296
1259
|
});
|
|
1297
|
-
|
|
1298
|
-
}, {
|
|
1299
|
-
info: (msg) => clack.log.info(msg),
|
|
1300
|
-
error: (msg) => clack.log.error(msg)
|
|
1301
|
-
});
|
|
1302
|
-
else try {
|
|
1260
|
+
} else try {
|
|
1303
1261
|
if (!await generate({
|
|
1304
1262
|
input,
|
|
1305
1263
|
config,
|
|
@@ -1307,17 +1265,17 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
1307
1265
|
hooks
|
|
1308
1266
|
})) anyFailed = true;
|
|
1309
1267
|
} catch (configError) {
|
|
1310
|
-
await hooks.
|
|
1268
|
+
await hooks.callHook("kubb:error", { error: toError(configError) });
|
|
1311
1269
|
anyFailed = true;
|
|
1312
1270
|
}
|
|
1313
|
-
await hooks.
|
|
1271
|
+
await hooks.callHook("kubb:lifecycle:end");
|
|
1314
1272
|
if (anyFailed) process$1.exit(1);
|
|
1315
1273
|
} catch (error) {
|
|
1316
|
-
await hooks.
|
|
1274
|
+
await hooks.callHook("kubb:error", { error: toError(error) });
|
|
1317
1275
|
process$1.exit(1);
|
|
1318
1276
|
}
|
|
1319
1277
|
}
|
|
1320
1278
|
//#endregion
|
|
1321
1279
|
export { run };
|
|
1322
1280
|
|
|
1323
|
-
//# sourceMappingURL=run-
|
|
1281
|
+
//# sourceMappingURL=run-BxMfDivH.js.map
|