@kubb/cli 5.0.0-beta.4 → 5.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +198 -36
- package/dist/agent-DQerNyd8.cjs +70 -0
- package/dist/agent-DQerNyd8.cjs.map +1 -0
- package/dist/agent-ZKJkTTGN.js +68 -0
- package/dist/agent-ZKJkTTGN.js.map +1 -0
- package/dist/{chunk--u3MIqq1.js → chunk-CRm0XQPb.js} +1 -0
- package/dist/constants-84a47qA-.js +35 -0
- package/dist/constants-84a47qA-.js.map +1 -0
- package/dist/constants-AHhyFH15.cjs +139 -0
- package/dist/constants-AHhyFH15.cjs.map +1 -0
- package/dist/constants-BtmponZ3.cjs +58 -0
- package/dist/constants-BtmponZ3.cjs.map +1 -0
- package/dist/constants-C94RKp3A.js +116 -0
- package/dist/constants-C94RKp3A.js.map +1 -0
- package/dist/{define-Bdn8j5VM.cjs → define-C4AB3POr.cjs} +2 -2
- package/dist/{define-Bdn8j5VM.cjs.map → define-C4AB3POr.cjs.map} +1 -1
- package/dist/{define-Ctii4bel.js → define-DNG1U8ha.js} +2 -2
- package/dist/{define-Ctii4bel.js.map → define-DNG1U8ha.js.map} +1 -1
- package/dist/{errors-CjPmyZHy.js → errors-CoxrNXaA.js} +2 -2
- package/dist/{errors-CjPmyZHy.js.map → errors-CoxrNXaA.js.map} +1 -1
- package/dist/{errors-CLCjoSg0.cjs → errors-DykI11xo.cjs} +2 -2
- package/dist/{errors-CLCjoSg0.cjs.map → errors-DykI11xo.cjs.map} +1 -1
- package/dist/generate-40x9PP4o.js +77 -0
- package/dist/generate-40x9PP4o.js.map +1 -0
- package/dist/generate-DQLvFw4z.cjs +76 -0
- package/dist/generate-DQLvFw4z.cjs.map +1 -0
- package/dist/index.cjs +23 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +23 -14
- package/dist/index.js.map +1 -1
- package/dist/init-CT9RChdK.js +53 -0
- package/dist/init-CT9RChdK.js.map +1 -0
- package/dist/init-sEaUN7Dj.cjs +53 -0
- package/dist/init-sEaUN7Dj.cjs.map +1 -0
- package/dist/mcp-Siyb6fTT.cjs +39 -0
- package/dist/mcp-Siyb6fTT.cjs.map +1 -0
- package/dist/mcp-cjPrOeot.js +39 -0
- package/dist/mcp-cjPrOeot.js.map +1 -0
- package/dist/{package-BapVyQ-w.cjs → package-BJ6qam2Y.cjs} +2 -2
- package/dist/package-BJ6qam2Y.cjs.map +1 -0
- package/dist/package-CR5vEK4K.js +6 -0
- package/dist/package-CR5vEK4K.js.map +1 -0
- package/dist/{agent-sdYBBgrd.js → run-BQ3Qj0xB.js} +46 -43
- package/dist/run-BQ3Qj0xB.js.map +1 -0
- package/dist/run-BQzoaxjR.js +32 -0
- package/dist/run-BQzoaxjR.js.map +1 -0
- package/dist/run-CGf0KEts.js +51 -0
- package/dist/run-CGf0KEts.js.map +1 -0
- package/dist/{generate-CNrRLY4n.js → run-CHZKHTv0.js} +832 -828
- package/dist/run-CHZKHTv0.js.map +1 -0
- package/dist/{init-CZ5Xq2Hd.cjs → run-C_NMctua.cjs} +107 -149
- package/dist/run-C_NMctua.cjs.map +1 -0
- package/dist/{generate-B1Pa2ho-.cjs → run-CcQawFNK.cjs} +784 -780
- package/dist/run-CcQawFNK.cjs.map +1 -0
- package/dist/run-CkTpemme.cjs +52 -0
- package/dist/run-CkTpemme.cjs.map +1 -0
- package/dist/run-Cl4SrSob.cjs +33 -0
- package/dist/run-Cl4SrSob.cjs.map +1 -0
- package/dist/{agent-B4cAAab2.cjs → run-D-s2LdlW.cjs} +46 -43
- package/dist/run-D-s2LdlW.cjs.map +1 -0
- package/dist/{init-eNRlotJK.js → run-D8dCWepS.js} +107 -149
- package/dist/run-D8dCWepS.js.map +1 -0
- package/dist/{shell-DLzN4fRo.js → shell-BrqyJdB7.js} +2 -2
- package/dist/{shell-DLzN4fRo.js.map → shell-BrqyJdB7.js.map} +1 -1
- package/dist/{shell-475fQKaX.cjs → shell-Lh-vLWwH.cjs} +2 -2
- package/dist/{shell-475fQKaX.cjs.map → shell-Lh-vLWwH.cjs.map} +1 -1
- package/dist/validate-8pgfxUTy.js +26 -0
- package/dist/validate-8pgfxUTy.js.map +1 -0
- package/dist/validate-CstV7Pc2.cjs +26 -0
- package/dist/validate-CstV7Pc2.cjs.map +1 -0
- package/package.json +16 -15
- package/src/commands/agent/start.ts +10 -7
- package/src/commands/agent.ts +3 -1
- package/src/commands/generate.ts +21 -13
- package/src/commands/init.ts +34 -3
- package/src/commands/mcp.ts +28 -4
- package/src/commands/validate.ts +6 -4
- package/src/constants.ts +3 -74
- package/src/index.ts +6 -4
- package/src/loggers/clackLogger.ts +143 -181
- package/src/loggers/githubActionsLogger.ts +119 -121
- package/src/loggers/plainLogger.ts +50 -100
- package/src/loggers/types.ts +6 -0
- package/src/loggers/utils.ts +190 -18
- package/src/runners/agent/run.ts +113 -0
- package/src/runners/agent/utils.ts +98 -0
- package/src/runners/generate/run.ts +411 -0
- package/src/runners/generate/utils.ts +222 -0
- package/src/runners/init/run.ts +212 -0
- package/src/{utils/packageManager.ts → runners/init/utils.ts} +12 -2
- package/src/runners/mcp/run.ts +37 -0
- package/src/runners/validate/run.ts +63 -0
- package/dist/agent-B4cAAab2.cjs.map +0 -1
- package/dist/agent-CR6Z96og.js +0 -56
- package/dist/agent-CR6Z96og.js.map +0 -1
- package/dist/agent-Dmxzqg4d.cjs +0 -58
- package/dist/agent-Dmxzqg4d.cjs.map +0 -1
- package/dist/agent-sdYBBgrd.js.map +0 -1
- package/dist/constants-CnDXa1R6.cjs +0 -148
- package/dist/constants-CnDXa1R6.cjs.map +0 -1
- package/dist/constants-aL3CP_Wq.js +0 -95
- package/dist/constants-aL3CP_Wq.js.map +0 -1
- package/dist/generate-B1Pa2ho-.cjs.map +0 -1
- package/dist/generate-BDGOOsBM.cjs +0 -65
- package/dist/generate-BDGOOsBM.cjs.map +0 -1
- package/dist/generate-CNrRLY4n.js.map +0 -1
- package/dist/generate-DuhxPLGr.js +0 -66
- package/dist/generate-DuhxPLGr.js.map +0 -1
- package/dist/init-CZ5Xq2Hd.cjs.map +0 -1
- package/dist/init-CnZXHrbq.js +0 -25
- package/dist/init-CnZXHrbq.js.map +0 -1
- package/dist/init-NYJSZJSb.cjs +0 -25
- package/dist/init-NYJSZJSb.cjs.map +0 -1
- package/dist/init-eNRlotJK.js.map +0 -1
- package/dist/mcp-CYOgxB82.cjs +0 -47
- package/dist/mcp-CYOgxB82.cjs.map +0 -1
- package/dist/mcp-CdFWyrwi.cjs +0 -16
- package/dist/mcp-CdFWyrwi.cjs.map +0 -1
- package/dist/mcp-DhSxuDMD.js +0 -16
- package/dist/mcp-DhSxuDMD.js.map +0 -1
- package/dist/mcp-DmJm3TrU.js +0 -46
- package/dist/mcp-DmJm3TrU.js.map +0 -1
- package/dist/package-BapVyQ-w.cjs.map +0 -1
- package/dist/package-DyJE-qNq.js +0 -6
- package/dist/package-DyJE-qNq.js.map +0 -1
- package/dist/telemetry-DN95_2pF.cjs +0 -282
- package/dist/telemetry-DN95_2pF.cjs.map +0 -1
- package/dist/telemetry-LgT_sdPe.js +0 -245
- package/dist/telemetry-LgT_sdPe.js.map +0 -1
- package/dist/validate-C6npXzel.cjs +0 -25
- package/dist/validate-C6npXzel.cjs.map +0 -1
- package/dist/validate-kLJoT_hi.js +0 -33
- package/dist/validate-kLJoT_hi.js.map +0 -1
- package/dist/validate-n38Rh-Y7.js +0 -25
- package/dist/validate-n38Rh-Y7.js.map +0 -1
- package/dist/validate-yKKzqEZ5.cjs +0 -34
- package/dist/validate-yKKzqEZ5.cjs.map +0 -1
- package/src/loggers/fileSystemLogger.ts +0 -138
- package/src/runners/agent.ts +0 -155
- package/src/runners/generate.ts +0 -333
- package/src/runners/init.ts +0 -296
- package/src/runners/mcp.ts +0 -51
- package/src/runners/validate.ts +0 -39
- package/src/types.ts +0 -11
- package/src/utils/Writables.ts +0 -17
- package/src/utils/executeHooks.ts +0 -45
- package/src/utils/flags.ts +0 -9
- package/src/utils/getConfig.ts +0 -10
- package/src/utils/getCosmiConfig.ts +0 -80
- package/src/utils/getSummary.ts +0 -68
- package/src/utils/runHook.ts +0 -91
- package/src/utils/telemetry.ts +0 -273
- package/src/utils/watcher.ts +0 -19
- /package/dist/{chunk-ByKO4r7w.cjs → chunk-Bx3C2hgW.cjs} +0 -0
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import "./chunk
|
|
2
|
-
import { n as toCause, r as toError } from "./errors-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
6
|
-
import { a as SUMMARY_SEPARATOR, n as KUBB_NPM_PACKAGE_URL, o as WATCHER_IGNORED_PATHS } from "./constants-aL3CP_Wq.js";
|
|
1
|
+
import "./chunk-CRm0XQPb.js";
|
|
2
|
+
import { n as toCause, r as toError } from "./errors-CoxrNXaA.js";
|
|
3
|
+
import { n as tokenize } from "./shell-BrqyJdB7.js";
|
|
4
|
+
import { t as version } from "./package-CR5vEK4K.js";
|
|
5
|
+
import { r as WATCHER_IGNORED_PATHS, t as KUBB_NPM_PACKAGE_URL } from "./constants-84a47qA-.js";
|
|
7
6
|
import { styleText } from "node:util";
|
|
8
7
|
import { EventEmitter } from "node:events";
|
|
9
8
|
import { createHash } from "node:crypto";
|
|
10
9
|
import { spawn } from "node:child_process";
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import path, { relative } from "node:path";
|
|
12
|
+
import { promises } from "node:dns";
|
|
13
|
+
import { Diagnostics, Telemetry, cliReporter, createKubb, defineLogger, logLevel, selectReporters } from "@kubb/core";
|
|
14
14
|
import process$1 from "node:process";
|
|
15
15
|
import * as clack from "@clack/prompts";
|
|
16
|
-
import { createKubb, defineLogger, isInputPath, logLevel } from "@kubb/core";
|
|
17
|
-
import { NonZeroExitError, x } from "tinyexec";
|
|
18
|
-
import { Writable } from "node:stream";
|
|
19
16
|
import { cosmiconfig } from "cosmiconfig";
|
|
20
|
-
import {
|
|
17
|
+
import { createJiti } from "jiti";
|
|
18
|
+
import { NonZeroExitError, x } from "tinyexec";
|
|
21
19
|
//#region ../../internals/utils/src/asyncEventEmitter.ts
|
|
22
20
|
/**
|
|
23
21
|
* Typed `EventEmitter` that awaits all async listeners before resolving.
|
|
@@ -48,9 +46,12 @@ var AsyncEventEmitter = class {
|
|
|
48
46
|
* await emitter.emit('build', 'petstore')
|
|
49
47
|
* ```
|
|
50
48
|
*/
|
|
51
|
-
|
|
49
|
+
emit(eventName, ...eventArgs) {
|
|
52
50
|
const listeners = this.#emitter.listeners(eventName);
|
|
53
51
|
if (listeners.length === 0) return;
|
|
52
|
+
return this.#emitAll(eventName, listeners, eventArgs);
|
|
53
|
+
}
|
|
54
|
+
async #emitAll(eventName, listeners, eventArgs) {
|
|
54
55
|
for (const listener of listeners) try {
|
|
55
56
|
await listener(...eventArgs);
|
|
56
57
|
} catch (err) {
|
|
@@ -113,6 +114,24 @@ var AsyncEventEmitter = class {
|
|
|
113
114
|
return this.#emitter.listenerCount(eventName);
|
|
114
115
|
}
|
|
115
116
|
/**
|
|
117
|
+
* Raises or lowers the per-event listener ceiling before Node warns about a memory leak.
|
|
118
|
+
* Set this above the expected listener count when many listeners attach by design.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* emitter.setMaxListeners(40)
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
setMaxListeners(max) {
|
|
126
|
+
this.#emitter.setMaxListeners(max);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Returns the current per-event listener ceiling.
|
|
130
|
+
*/
|
|
131
|
+
getMaxListeners() {
|
|
132
|
+
return this.#emitter.getMaxListeners();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
116
135
|
* Removes all listeners from every event channel.
|
|
117
136
|
*
|
|
118
137
|
* @example
|
|
@@ -265,32 +284,6 @@ function getIntro({ title, description, version, areEyesOpen }) {
|
|
|
265
284
|
`;
|
|
266
285
|
}
|
|
267
286
|
/**
|
|
268
|
-
* ANSI color names used by {@link randomCliColor} for deterministic terminal coloring.
|
|
269
|
-
*/
|
|
270
|
-
const randomColors = [
|
|
271
|
-
"black",
|
|
272
|
-
"red",
|
|
273
|
-
"green",
|
|
274
|
-
"yellow",
|
|
275
|
-
"blue",
|
|
276
|
-
"white",
|
|
277
|
-
"magenta",
|
|
278
|
-
"cyan",
|
|
279
|
-
"gray"
|
|
280
|
-
];
|
|
281
|
-
/**
|
|
282
|
-
* Wraps `text` in a deterministic ANSI color derived from the text's SHA-256 hash.
|
|
283
|
-
*
|
|
284
|
-
* @example
|
|
285
|
-
* ```ts
|
|
286
|
-
* randomCliColor('petstore') // '\x1b[33m' + 'petstore' + '\x1b[39m' (always the same color for 'petstore')
|
|
287
|
-
* ```
|
|
288
|
-
*/
|
|
289
|
-
function randomCliColor(text) {
|
|
290
|
-
if (!text) return "";
|
|
291
|
-
return styleText(randomColors[createHash("sha256").update(text).digest().readUInt32BE(0) % randomColors.length] ?? "white", text);
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
287
|
* Formats a millisecond duration with a threshold-based ANSI color.
|
|
295
288
|
* `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.
|
|
296
289
|
*
|
|
@@ -308,6 +301,55 @@ function formatMsWithColor(ms) {
|
|
|
308
301
|
return styleText("red", formatted);
|
|
309
302
|
}
|
|
310
303
|
//#endregion
|
|
304
|
+
//#region ../../internals/utils/src/env.ts
|
|
305
|
+
/**
|
|
306
|
+
* Returns `true` when running inside a GitHub Actions workflow.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```ts
|
|
310
|
+
* if (isGitHubActions()) {
|
|
311
|
+
* core.setOutput('result', 'ok')
|
|
312
|
+
* }
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
function isGitHubActions() {
|
|
316
|
+
return !!process.env.GITHUB_ACTIONS;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Returns `true` when the process is running in a CI environment.
|
|
320
|
+
* Covers GitHub Actions, GitLab CI, CircleCI, Travis CI, Jenkins, Bitbucket,
|
|
321
|
+
* TeamCity, Buildkite, and Azure Pipelines.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* if (isCIEnvironment()) {
|
|
326
|
+
* logger.level = 'error'
|
|
327
|
+
* }
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
function isCIEnvironment() {
|
|
331
|
+
return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.BITBUCKET_BUILD_NUMBER || process.env.JENKINS_URL || process.env.CIRCLECI || process.env.TRAVIS || process.env.TEAMCITY_VERSION || process.env.BUILDKITE || process.env.TF_BUILD);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Returns `true` when the process has an interactive TTY with a valid terminal
|
|
335
|
+
* width and is not running in CI.
|
|
336
|
+
*
|
|
337
|
+
* Some IDE-embedded terminals report `isTTY = true` but set `columns` to `0`,
|
|
338
|
+
* which breaks clack's box-drawing helpers (they call `String.prototype.repeat`
|
|
339
|
+
* with a negative count and throw a `RangeError`). We therefore require a
|
|
340
|
+
* positive column count before declaring the TTY usable.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```ts
|
|
344
|
+
* if (canUseTTY()) {
|
|
345
|
+
* renderProgressBar()
|
|
346
|
+
* }
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
function canUseTTY() {
|
|
350
|
+
return !!process.stdout.isTTY && (process.stdout.columns ?? 0) > 0 && !isCIEnvironment();
|
|
351
|
+
}
|
|
352
|
+
//#endregion
|
|
311
353
|
//#region ../../internals/utils/src/formatters.ts
|
|
312
354
|
/**
|
|
313
355
|
* CLI command descriptors for each supported code formatter.
|
|
@@ -372,62 +414,8 @@ async function detectFormatter() {
|
|
|
372
414
|
return null;
|
|
373
415
|
}
|
|
374
416
|
//#endregion
|
|
375
|
-
//#region ../../internals/utils/src/fs.ts
|
|
376
|
-
/**
|
|
377
|
-
* Writes `data` to `path`, trimming leading/trailing whitespace before saving.
|
|
378
|
-
* Skips the write when the trimmed content is empty or identical to what is already on disk.
|
|
379
|
-
* Creates any missing parent directories automatically.
|
|
380
|
-
* When `sanity` is `true`, re-reads the file after writing and throws if the content does not match.
|
|
381
|
-
*
|
|
382
|
-
* @example
|
|
383
|
-
* ```ts
|
|
384
|
-
* await write('./src/Pet.ts', source) // writes and returns trimmed content
|
|
385
|
-
* await write('./src/Pet.ts', source) // null — file unchanged
|
|
386
|
-
* await write('./src/Pet.ts', ' ') // null — empty content skipped
|
|
387
|
-
* ```
|
|
388
|
-
*/
|
|
389
|
-
async function write(path, data, options = {}) {
|
|
390
|
-
const trimmed = data.trim();
|
|
391
|
-
if (trimmed === "") return null;
|
|
392
|
-
const resolved = resolve(path);
|
|
393
|
-
if (typeof Bun !== "undefined") {
|
|
394
|
-
const file = Bun.file(resolved);
|
|
395
|
-
if ((await file.exists() ? await file.text() : null) === trimmed) return null;
|
|
396
|
-
await Bun.write(resolved, trimmed);
|
|
397
|
-
return trimmed;
|
|
398
|
-
}
|
|
399
|
-
try {
|
|
400
|
-
if (await readFile(resolved, { encoding: "utf-8" }) === trimmed) return null;
|
|
401
|
-
} catch {}
|
|
402
|
-
await mkdir(dirname(resolved), { recursive: true });
|
|
403
|
-
await writeFile(resolved, trimmed, { encoding: "utf-8" });
|
|
404
|
-
if (options.sanity) {
|
|
405
|
-
const savedData = await readFile(resolved, { encoding: "utf-8" });
|
|
406
|
-
if (savedData !== trimmed) throw new Error(`Sanity check failed for ${path}\n\nData[${data.length}]:\n${data}\n\nSaved[${savedData.length}]:\n${savedData}\n`);
|
|
407
|
-
return savedData;
|
|
408
|
-
}
|
|
409
|
-
return trimmed;
|
|
410
|
-
}
|
|
411
|
-
//#endregion
|
|
412
417
|
//#region ../../internals/utils/src/linters.ts
|
|
413
418
|
/**
|
|
414
|
-
* Collects all files under `dir` recursively using Node's built-in fs APIs.
|
|
415
|
-
*
|
|
416
|
-
* Passing explicit file paths to oxlint (instead of a directory) bypasses
|
|
417
|
-
* oxlint's `.gitignore`-aware directory traversal, which would otherwise skip
|
|
418
|
-
* files that are listed in `.gitignore` (e.g. generated output directories).
|
|
419
|
-
*/
|
|
420
|
-
function findLintableFiles(dir) {
|
|
421
|
-
try {
|
|
422
|
-
return readdirSync(dir, {
|
|
423
|
-
withFileTypes: true,
|
|
424
|
-
recursive: true
|
|
425
|
-
}).filter((d) => d.isFile()).map((d) => `${d.parentPath}/${d.name}`);
|
|
426
|
-
} catch {
|
|
427
|
-
return [];
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
419
|
* CLI command descriptors for each supported linter.
|
|
432
420
|
*
|
|
433
421
|
* Each entry contains the executable `command`, an `args` factory that maps an
|
|
@@ -451,7 +439,11 @@ const linters = {
|
|
|
451
439
|
},
|
|
452
440
|
oxlint: {
|
|
453
441
|
command: "oxlint",
|
|
454
|
-
args: (outputPath) => [
|
|
442
|
+
args: (outputPath) => [
|
|
443
|
+
"--fix",
|
|
444
|
+
"--no-ignore",
|
|
445
|
+
outputPath
|
|
446
|
+
],
|
|
455
447
|
errorMessage: "Oxlint not found"
|
|
456
448
|
}
|
|
457
449
|
};
|
|
@@ -486,112 +478,51 @@ async function detectLinter() {
|
|
|
486
478
|
return null;
|
|
487
479
|
}
|
|
488
480
|
//#endregion
|
|
489
|
-
//#region
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
summaryLines.push(`${labels.pluginTimings}`);
|
|
516
|
-
sortedTimings.forEach(([name, time]) => {
|
|
517
|
-
const timeStr = time >= 1e3 ? `${(time / 1e3).toFixed(2)}s` : `${Math.round(time)}ms`;
|
|
518
|
-
const barLength = Math.min(Math.ceil(time / 100), 10);
|
|
519
|
-
const bar = styleText("dim", "█".repeat(barLength));
|
|
520
|
-
summaryLines.push(`${styleText("dim", "•")} ${name.padEnd(maxLength + 1)}${bar} ${timeStr}`);
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
summaryLines.push(`${labels.output.padEnd(maxLength + 2)} ${meta.output}`);
|
|
524
|
-
return summaryLines;
|
|
481
|
+
//#region ../../internals/utils/src/network.ts
|
|
482
|
+
/**
|
|
483
|
+
* Well-known stable domains used as DNS probes to check internet connectivity.
|
|
484
|
+
*/
|
|
485
|
+
const TEST_DOMAINS = [
|
|
486
|
+
"dns.google.com",
|
|
487
|
+
"cloudflare.com",
|
|
488
|
+
"one.one.one.one"
|
|
489
|
+
];
|
|
490
|
+
/**
|
|
491
|
+
* Returns `true` when the system has internet connectivity.
|
|
492
|
+
* Probes DNS resolution against well-known stable domains.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```ts
|
|
496
|
+
* if (await isOnline()) {
|
|
497
|
+
* await fetchLatestVersion()
|
|
498
|
+
* }
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
async function isOnline() {
|
|
502
|
+
for (const domain of TEST_DOMAINS) try {
|
|
503
|
+
await promises.resolve(domain);
|
|
504
|
+
return true;
|
|
505
|
+
} catch {}
|
|
506
|
+
return false;
|
|
525
507
|
}
|
|
526
|
-
//#endregion
|
|
527
|
-
//#region src/utils/runHook.ts
|
|
528
508
|
/**
|
|
529
|
-
* Executes
|
|
509
|
+
* Executes `fn` only when the system is online. Returns `null` when offline or on error.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```ts
|
|
513
|
+
* const version = await executeIfOnline(() => fetchLatestVersion('kubb'))
|
|
514
|
+
* // null when offline
|
|
515
|
+
* ```
|
|
530
516
|
*/
|
|
531
|
-
async function
|
|
517
|
+
async function executeIfOnline(fn) {
|
|
518
|
+
if (!await isOnline()) return null;
|
|
532
519
|
try {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
});
|
|
537
|
-
if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
|
|
538
|
-
const result = await proc;
|
|
539
|
-
await context.emit("kubb:debug", {
|
|
540
|
-
date: /* @__PURE__ */ new Date(),
|
|
541
|
-
logs: [result.stdout.trimEnd()]
|
|
542
|
-
});
|
|
543
|
-
await context.emit("kubb:hook:end", {
|
|
544
|
-
command,
|
|
545
|
-
args,
|
|
546
|
-
id,
|
|
547
|
-
success: true,
|
|
548
|
-
error: null
|
|
549
|
-
});
|
|
550
|
-
} catch (err) {
|
|
551
|
-
if (!(err instanceof NonZeroExitError)) {
|
|
552
|
-
await context.emit("kubb:hook:end", {
|
|
553
|
-
command,
|
|
554
|
-
args,
|
|
555
|
-
id,
|
|
556
|
-
success: false,
|
|
557
|
-
error: toError(err)
|
|
558
|
-
});
|
|
559
|
-
await context.emit("kubb:error", { error: toError(err) });
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
const stderr = err.output?.stderr ?? "";
|
|
563
|
-
const stdout = err.output?.stdout ?? "";
|
|
564
|
-
await context.emit("kubb:debug", {
|
|
565
|
-
date: /* @__PURE__ */ new Date(),
|
|
566
|
-
logs: [stdout, stderr].filter(Boolean)
|
|
567
|
-
});
|
|
568
|
-
if (stderr) sink?.onStderr?.(stderr);
|
|
569
|
-
if (stdout) sink?.onStdout?.(stdout);
|
|
570
|
-
const errorMessage = /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`);
|
|
571
|
-
await context.emit("kubb:hook:end", {
|
|
572
|
-
command,
|
|
573
|
-
args,
|
|
574
|
-
id,
|
|
575
|
-
success: false,
|
|
576
|
-
error: errorMessage
|
|
577
|
-
});
|
|
578
|
-
await context.emit("kubb:error", { error: errorMessage });
|
|
520
|
+
return await fn();
|
|
521
|
+
} catch {
|
|
522
|
+
return null;
|
|
579
523
|
}
|
|
580
524
|
}
|
|
581
525
|
//#endregion
|
|
582
|
-
//#region src/utils/Writables.ts
|
|
583
|
-
var ClackWritable = class extends Writable {
|
|
584
|
-
taskLog;
|
|
585
|
-
constructor(taskLog, opts) {
|
|
586
|
-
super(opts);
|
|
587
|
-
this.taskLog = taskLog;
|
|
588
|
-
}
|
|
589
|
-
_write(chunk, _encoding, callback) {
|
|
590
|
-
this.taskLog.message(`${styleText("dim", chunk.toString())}`);
|
|
591
|
-
callback();
|
|
592
|
-
}
|
|
593
|
-
};
|
|
594
|
-
//#endregion
|
|
595
526
|
//#region src/loggers/clackLogger.ts
|
|
596
527
|
/**
|
|
597
528
|
* TTY logger with beautiful UI and progress indicators for local development.
|
|
@@ -599,84 +530,101 @@ var ClackWritable = class extends Writable {
|
|
|
599
530
|
const clackLogger = defineLogger({
|
|
600
531
|
name: "clack",
|
|
601
532
|
install(context, options) {
|
|
602
|
-
const logLevel$
|
|
533
|
+
const logLevel$6 = options?.logLevel ?? logLevel.info;
|
|
603
534
|
const state = {
|
|
604
|
-
|
|
605
|
-
completedPlugins: 0,
|
|
606
|
-
failedPlugins: 0,
|
|
607
|
-
totalFiles: 0,
|
|
608
|
-
processedFiles: 0,
|
|
609
|
-
hrStart: process$1.hrtime(),
|
|
535
|
+
...createProgressCounters(),
|
|
610
536
|
spinner: clack.spinner(),
|
|
611
537
|
isSpinning: false,
|
|
612
|
-
|
|
538
|
+
runningPlugins: /* @__PURE__ */ new Set(),
|
|
539
|
+
activeProgress: /* @__PURE__ */ new Map(),
|
|
540
|
+
activeHookLogs: /* @__PURE__ */ new Map()
|
|
613
541
|
};
|
|
614
|
-
function
|
|
615
|
-
for (const [
|
|
542
|
+
function stopActiveProgress() {
|
|
543
|
+
for (const [, active] of state.activeProgress) {
|
|
616
544
|
if (active.interval) clearInterval(active.interval);
|
|
617
545
|
active.progressBar?.stop();
|
|
618
546
|
}
|
|
619
|
-
state.
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
state
|
|
624
|
-
state.hrStart = process$1.hrtime();
|
|
547
|
+
state.activeProgress.clear();
|
|
548
|
+
}
|
|
549
|
+
function reset() {
|
|
550
|
+
stopActiveProgress();
|
|
551
|
+
resetProgressCounters(state);
|
|
625
552
|
state.spinner = clack.spinner();
|
|
626
553
|
state.isSpinning = false;
|
|
627
|
-
state.
|
|
554
|
+
state.runningPlugins.clear();
|
|
555
|
+
state.activeHookLogs.clear();
|
|
556
|
+
}
|
|
557
|
+
function pluginProgressText() {
|
|
558
|
+
const running = [...state.runningPlugins].map((name) => styleText("bold", name));
|
|
559
|
+
return getMessage(running.length > 0 ? `Generating ${running.join(", ")}` : "Generating plugins");
|
|
628
560
|
}
|
|
629
561
|
function showProgressStep() {
|
|
630
|
-
if (logLevel$
|
|
562
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
631
563
|
const line = buildProgressLine(state);
|
|
632
564
|
if (line) clack.log.step(getMessage(line));
|
|
633
565
|
}
|
|
634
566
|
function getMessage(message) {
|
|
635
|
-
return formatMessage(message, logLevel$
|
|
567
|
+
return formatMessage(message, logLevel$6);
|
|
568
|
+
}
|
|
569
|
+
function onStep(event, message) {
|
|
570
|
+
context.on(event, () => {
|
|
571
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
572
|
+
clack.log.step(getMessage(message));
|
|
573
|
+
});
|
|
636
574
|
}
|
|
637
575
|
function startSpinner(text) {
|
|
638
576
|
state.spinner.start(text);
|
|
639
577
|
state.isSpinning = true;
|
|
640
578
|
}
|
|
641
579
|
function stopSpinner(text) {
|
|
580
|
+
if (!state.isSpinning) return;
|
|
642
581
|
state.spinner.stop(text);
|
|
643
582
|
state.isSpinning = false;
|
|
644
583
|
}
|
|
645
584
|
context.on("kubb:info", ({ message, info = "" }) => {
|
|
646
|
-
if (logLevel$
|
|
585
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
647
586
|
const text = getMessage([
|
|
648
587
|
styleText("blue", "ℹ"),
|
|
649
588
|
message,
|
|
650
|
-
styleText("dim", info)
|
|
651
|
-
].join(" "));
|
|
652
|
-
if (state.isSpinning)
|
|
653
|
-
|
|
589
|
+
info ? styleText("dim", info) : void 0
|
|
590
|
+
].filter(Boolean).join(" "));
|
|
591
|
+
if (state.isSpinning) {
|
|
592
|
+
state.spinner.message(text);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
clack.log.info(text);
|
|
654
596
|
});
|
|
655
597
|
context.on("kubb:success", ({ message, info = "" }) => {
|
|
656
|
-
if (logLevel$
|
|
598
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
657
599
|
const text = getMessage([
|
|
658
600
|
styleText("blue", "✓"),
|
|
659
601
|
message,
|
|
660
|
-
logLevel$
|
|
602
|
+
logLevel$6 >= logLevel.info ? styleText("dim", info) : void 0
|
|
661
603
|
].filter(Boolean).join(" "));
|
|
662
|
-
if (state.isSpinning)
|
|
663
|
-
|
|
604
|
+
if (state.isSpinning) {
|
|
605
|
+
stopSpinner(text);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
clack.log.success(text);
|
|
664
609
|
});
|
|
665
610
|
context.on("kubb:warn", ({ message, info }) => {
|
|
666
|
-
if (logLevel$
|
|
611
|
+
if (logLevel$6 < logLevel.warn) return;
|
|
667
612
|
const text = getMessage([
|
|
668
613
|
styleText("yellow", "⚠"),
|
|
669
614
|
message,
|
|
670
|
-
logLevel$
|
|
615
|
+
logLevel$6 >= logLevel.info && info ? styleText("dim", info) : void 0
|
|
671
616
|
].filter(Boolean).join(" "));
|
|
672
617
|
clack.log.warn(text);
|
|
673
618
|
});
|
|
674
619
|
context.on("kubb:error", ({ error }) => {
|
|
675
620
|
const caused = toCause(error);
|
|
676
621
|
const text = [styleText("red", "✗"), error.message].join(" ");
|
|
677
|
-
if (state.isSpinning)
|
|
678
|
-
|
|
679
|
-
|
|
622
|
+
if (state.isSpinning) {
|
|
623
|
+
stopSpinner(getMessage(text));
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
clack.log.error(getMessage(text));
|
|
627
|
+
if (logLevel$6 >= logLevel.verbose && error.stack) {
|
|
680
628
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
681
629
|
for (const frame of frames) clack.log.message(getMessage(styleText("dim", frame.trim())));
|
|
682
630
|
if (caused?.stack) {
|
|
@@ -686,10 +634,12 @@ const clackLogger = defineLogger({
|
|
|
686
634
|
}
|
|
687
635
|
}
|
|
688
636
|
});
|
|
689
|
-
context.on("kubb:
|
|
690
|
-
if (logLevel$
|
|
691
|
-
|
|
692
|
-
|
|
637
|
+
context.on("kubb:diagnostic", ({ diagnostic }) => {
|
|
638
|
+
if (logLevel$6 <= logLevel.silent && diagnostic.severity !== "error") return;
|
|
639
|
+
stopSpinner();
|
|
640
|
+
stopActiveProgress();
|
|
641
|
+
if (Diagnostics.isUpdate(diagnostic)) {
|
|
642
|
+
clack.box(`\`v${diagnostic.currentVersion}\` → \`v${diagnostic.latestVersion}\`
|
|
693
643
|
Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
694
644
|
width: "auto",
|
|
695
645
|
formatBorder: (s) => styleText("yellow", s),
|
|
@@ -698,14 +648,14 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
698
648
|
contentAlign: "center",
|
|
699
649
|
titleAlign: "center"
|
|
700
650
|
});
|
|
701
|
-
|
|
702
|
-
console.log(`Update available for Kubb: v${currentVersion} → v${latestVersion}`);
|
|
703
|
-
console.log("Run `npm install -g @kubb/cli` to update");
|
|
651
|
+
return;
|
|
704
652
|
}
|
|
653
|
+
const { symbol, headline, details } = Diagnostics.format(diagnostic);
|
|
654
|
+
clack.log.message([headline, ...details], { symbol });
|
|
705
655
|
});
|
|
706
656
|
context.on("kubb:lifecycle:start", async ({ version }) => {
|
|
707
657
|
console.log(`\n${getIntro({
|
|
708
|
-
title: "The
|
|
658
|
+
title: "The meta framework for code generation",
|
|
709
659
|
description: "Ready to start",
|
|
710
660
|
version,
|
|
711
661
|
areEyesOpen: true
|
|
@@ -713,55 +663,56 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
713
663
|
reset();
|
|
714
664
|
});
|
|
715
665
|
context.on("kubb:config:start", () => {
|
|
716
|
-
if (logLevel$
|
|
666
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
717
667
|
const text = getMessage("Configuration started");
|
|
718
668
|
clack.intro(text);
|
|
719
669
|
startSpinner(getMessage("Configuration loading"));
|
|
720
670
|
});
|
|
721
671
|
context.on("kubb:config:end", () => {
|
|
722
|
-
if (logLevel$
|
|
672
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
723
673
|
const text = getMessage("Configuration completed");
|
|
724
674
|
clack.outro(text);
|
|
725
675
|
});
|
|
726
676
|
context.on("kubb:generation:start", ({ config }) => {
|
|
727
677
|
reset();
|
|
728
678
|
state.totalPlugins = config.plugins?.length ?? 0;
|
|
679
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
729
680
|
const text = getMessage(["Generation started", config.name ? `for ${styleText("dim", config.name)}` : void 0].filter(Boolean).join(" "));
|
|
730
681
|
clack.intro(text);
|
|
731
682
|
});
|
|
732
683
|
context.on("kubb:plugin:start", ({ plugin }) => {
|
|
733
|
-
if (logLevel$
|
|
684
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
734
685
|
stopSpinner();
|
|
686
|
+
state.runningPlugins.add(plugin.name);
|
|
687
|
+
const active = state.activeProgress.get("plugins");
|
|
688
|
+
if (active) {
|
|
689
|
+
active.progressBar.advance(0, pluginProgressText());
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
735
692
|
const progressBar = clack.progress({
|
|
736
693
|
style: "block",
|
|
737
|
-
max:
|
|
694
|
+
max: Math.max(state.totalPlugins, 1),
|
|
738
695
|
size: 30
|
|
739
696
|
});
|
|
740
|
-
|
|
741
|
-
progressBar.
|
|
742
|
-
|
|
743
|
-
progressBar.advance();
|
|
744
|
-
}, 100);
|
|
745
|
-
state.activeProgress.set(plugin.name, {
|
|
746
|
-
progressBar,
|
|
747
|
-
interval
|
|
748
|
-
});
|
|
697
|
+
progressBar.start(pluginProgressText());
|
|
698
|
+
progressBar.advance(state.completedPlugins + state.failedPlugins, pluginProgressText());
|
|
699
|
+
state.activeProgress.set("plugins", { progressBar });
|
|
749
700
|
});
|
|
750
|
-
context.on("kubb:plugin:end", ({ plugin,
|
|
701
|
+
context.on("kubb:plugin:end", ({ plugin, success }) => {
|
|
751
702
|
stopSpinner();
|
|
752
|
-
const active = state.activeProgress.get(
|
|
753
|
-
if (!active || logLevel$
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
703
|
+
const active = state.activeProgress.get("plugins");
|
|
704
|
+
if (!active || logLevel$6 === logLevel.silent) return;
|
|
705
|
+
state.runningPlugins.delete(plugin.name);
|
|
706
|
+
recordPluginResult(state, success);
|
|
707
|
+
active.progressBar.advance(1, pluginProgressText());
|
|
708
|
+
if (state.runningPlugins.size === 0) {
|
|
709
|
+
active.progressBar.stop(getMessage("Plugins generated"));
|
|
710
|
+
state.activeProgress.delete("plugins");
|
|
711
|
+
showProgressStep();
|
|
712
|
+
}
|
|
762
713
|
});
|
|
763
714
|
context.on("kubb:files:processing:start", ({ files }) => {
|
|
764
|
-
if (logLevel$
|
|
715
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
765
716
|
stopSpinner();
|
|
766
717
|
state.totalFiles = files.length;
|
|
767
718
|
state.processedFiles = 0;
|
|
@@ -775,17 +726,17 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
775
726
|
progressBar.start(getMessage(text));
|
|
776
727
|
state.activeProgress.set("files", { progressBar });
|
|
777
728
|
});
|
|
778
|
-
context.on("kubb:
|
|
779
|
-
if (logLevel$
|
|
729
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
730
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
780
731
|
stopSpinner();
|
|
781
|
-
state.processedFiles++;
|
|
782
|
-
const text = `Writing ${relative(config.root, file.path)}`;
|
|
783
732
|
const active = state.activeProgress.get("files");
|
|
784
|
-
|
|
785
|
-
|
|
733
|
+
for (const { file, config } of files) {
|
|
734
|
+
state.processedFiles++;
|
|
735
|
+
if (active) active.progressBar.advance(void 0, `Writing ${relative(config.root, file.path)}`);
|
|
736
|
+
}
|
|
786
737
|
});
|
|
787
738
|
context.on("kubb:files:processing:end", () => {
|
|
788
|
-
if (logLevel$
|
|
739
|
+
if (logLevel$6 <= logLevel.silent) return;
|
|
789
740
|
stopSpinner();
|
|
790
741
|
const text = getMessage("Files written successfully");
|
|
791
742
|
const active = state.activeProgress.get("files");
|
|
@@ -795,202 +746,54 @@ Run \`npm install -g @kubb/cli\` to update`, "Update available for `Kubb`", {
|
|
|
795
746
|
showProgressStep();
|
|
796
747
|
});
|
|
797
748
|
context.on("kubb:generation:end", ({ config }) => {
|
|
749
|
+
stopSpinner();
|
|
798
750
|
const text = getMessage(config.name ? `Generation completed for ${styleText("dim", config.name)}` : "Generation completed");
|
|
799
751
|
clack.outro(text);
|
|
800
752
|
});
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
if (logLevel$8 <= logLevel.silent) return;
|
|
813
|
-
const text = getMessage("Lint started");
|
|
814
|
-
clack.intro(text);
|
|
815
|
-
});
|
|
816
|
-
context.on("kubb:lint:end", () => {
|
|
817
|
-
if (logLevel$8 <= logLevel.silent) return;
|
|
818
|
-
const text = getMessage("Lint completed");
|
|
819
|
-
clack.outro(text);
|
|
820
|
-
});
|
|
821
|
-
context.on("kubb:hook:start", async ({ id, command, args }) => {
|
|
822
|
-
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
823
|
-
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} started`);
|
|
824
|
-
if (!id) return;
|
|
825
|
-
if (logLevel$8 <= logLevel.silent) {
|
|
826
|
-
await runHook({
|
|
827
|
-
id,
|
|
828
|
-
command,
|
|
829
|
-
args,
|
|
830
|
-
commandWithArgs,
|
|
831
|
-
context,
|
|
832
|
-
sink: {
|
|
833
|
-
onStderr: (s) => console.error(s),
|
|
834
|
-
onStdout: (s) => console.log(s)
|
|
835
|
-
}
|
|
836
|
-
});
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
clack.intro(text);
|
|
840
|
-
const logger = clack.taskLog({ title: getMessage(["Executing hook", logLevel$8 >= logLevel.info ? styleText("dim", commandWithArgs) : void 0].filter(Boolean).join(" ")) });
|
|
841
|
-
const writable = new ClackWritable(logger);
|
|
842
|
-
await runHook({
|
|
843
|
-
id,
|
|
844
|
-
command,
|
|
845
|
-
args,
|
|
846
|
-
commandWithArgs,
|
|
847
|
-
context,
|
|
848
|
-
stream: true,
|
|
849
|
-
sink: {
|
|
850
|
-
onLine: (line) => writable.write(line),
|
|
851
|
-
onStderr: (s) => logger.error(s),
|
|
852
|
-
onStdout: (s) => logger.message(s)
|
|
853
|
-
}
|
|
753
|
+
onStep("kubb:format:start", "Formatting");
|
|
754
|
+
onStep("kubb:lint:start", "Linting");
|
|
755
|
+
onStep("kubb:hooks:start", "Running hooks");
|
|
756
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
757
|
+
if (logLevel$6 <= logLevel.silent || !id) return;
|
|
758
|
+
stopSpinner();
|
|
759
|
+
const title = getMessage(`Running ${styleText("dim", formatCommandWithArgs(command, args))}`);
|
|
760
|
+
const taskLog = clack.taskLog({ title });
|
|
761
|
+
state.activeHookLogs.set(id, {
|
|
762
|
+
taskLog,
|
|
763
|
+
hrStart: process$1.hrtime()
|
|
854
764
|
});
|
|
855
765
|
});
|
|
856
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
857
|
-
if (logLevel$
|
|
858
|
-
const
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
hrStart,
|
|
868
|
-
pluginTimings: logLevel$8 >= logLevel.verbose ? pluginTimings : void 0
|
|
869
|
-
});
|
|
870
|
-
const title = config.name || "";
|
|
871
|
-
summary.unshift("\n");
|
|
872
|
-
summary.push("\n");
|
|
873
|
-
const borderColor = status === "success" ? "green" : "red";
|
|
874
|
-
try {
|
|
875
|
-
clack.box(summary.join("\n"), getMessage(title), {
|
|
876
|
-
width: "auto",
|
|
877
|
-
formatBorder: (s) => styleText(borderColor, s),
|
|
878
|
-
rounded: true,
|
|
879
|
-
withGuide: false,
|
|
880
|
-
contentAlign: "left",
|
|
881
|
-
titleAlign: "center"
|
|
882
|
-
});
|
|
883
|
-
} catch {
|
|
884
|
-
console.log(summary.join("\n"));
|
|
766
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
767
|
+
if (logLevel$6 <= logLevel.silent || !id) return;
|
|
768
|
+
const active = state.activeHookLogs.get(id);
|
|
769
|
+
if (!active) return;
|
|
770
|
+
state.activeHookLogs.delete(id);
|
|
771
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
772
|
+
const duration = formatMsWithColor(getElapsedMs(active.hrStart));
|
|
773
|
+
if (success) active.taskLog.success(getMessage(`${styleText("dim", commandWithArgs)} completed in ${duration}`));
|
|
774
|
+
else {
|
|
775
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
776
|
+
active.taskLog.error(getMessage(`${styleText("dim", commandWithArgs)} failed${reason}`), { showLog: true });
|
|
885
777
|
}
|
|
886
778
|
});
|
|
887
779
|
context.on("kubb:lifecycle:end", () => {
|
|
888
780
|
reset();
|
|
889
781
|
});
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
};
|
|
905
|
-
function reset() {
|
|
906
|
-
state.cachedLogs = /* @__PURE__ */ new Set();
|
|
907
|
-
state.startDate = Date.now();
|
|
908
|
-
}
|
|
909
|
-
async function writeLogs(name) {
|
|
910
|
-
if (state.cachedLogs.size === 0) return [];
|
|
911
|
-
const files = {};
|
|
912
|
-
for (const log of state.cachedLogs) {
|
|
913
|
-
const baseName = log.fileName || `${[
|
|
914
|
-
"kubb",
|
|
915
|
-
name,
|
|
916
|
-
state.startDate
|
|
917
|
-
].filter(Boolean).join("-")}.log`;
|
|
918
|
-
const pathName = resolve(process$1.cwd(), ".kubb", baseName);
|
|
919
|
-
if (!files[pathName]) files[pathName] = [];
|
|
920
|
-
if (log.logs.length > 0) {
|
|
921
|
-
const timestamp = log.date.toLocaleString();
|
|
922
|
-
files[pathName].push(`[${timestamp}]\n${log.logs.join("\n")}`);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
for (const [fileName, logs] of Object.entries(files)) await write(fileName, logs.join("\n\n"));
|
|
926
|
-
return Object.keys(files);
|
|
927
|
-
}
|
|
928
|
-
context.on("kubb:info", ({ message, info }) => {
|
|
929
|
-
state.cachedLogs.add({
|
|
930
|
-
date: /* @__PURE__ */ new Date(),
|
|
931
|
-
logs: [`ℹ ${message} ${info}`]
|
|
932
|
-
});
|
|
933
|
-
});
|
|
934
|
-
context.on("kubb:success", ({ message, info }) => {
|
|
935
|
-
state.cachedLogs.add({
|
|
936
|
-
date: /* @__PURE__ */ new Date(),
|
|
937
|
-
logs: [`✓ ${message} ${info}`]
|
|
938
|
-
});
|
|
939
|
-
});
|
|
940
|
-
context.on("kubb:warn", ({ message, info }) => {
|
|
941
|
-
state.cachedLogs.add({
|
|
942
|
-
date: /* @__PURE__ */ new Date(),
|
|
943
|
-
logs: [`⚠ ${message} ${info}`]
|
|
944
|
-
});
|
|
945
|
-
});
|
|
946
|
-
context.on("kubb:error", ({ error }) => {
|
|
947
|
-
state.cachedLogs.add({
|
|
948
|
-
date: /* @__PURE__ */ new Date(),
|
|
949
|
-
logs: [`✗ ${error.message}`, error.stack || "unknown stack"]
|
|
950
|
-
});
|
|
951
|
-
});
|
|
952
|
-
context.on("kubb:debug", (message) => {
|
|
953
|
-
state.cachedLogs.add({
|
|
954
|
-
date: /* @__PURE__ */ new Date(),
|
|
955
|
-
logs: message.logs
|
|
956
|
-
});
|
|
957
|
-
});
|
|
958
|
-
context.on("kubb:plugin:start", ({ plugin }) => {
|
|
959
|
-
state.cachedLogs.add({
|
|
960
|
-
date: /* @__PURE__ */ new Date(),
|
|
961
|
-
logs: [`Generating ${plugin.name}`]
|
|
962
|
-
});
|
|
963
|
-
});
|
|
964
|
-
context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
965
|
-
const durationStr = formatMs(duration);
|
|
966
|
-
state.cachedLogs.add({
|
|
967
|
-
date: /* @__PURE__ */ new Date(),
|
|
968
|
-
logs: [success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`]
|
|
969
|
-
});
|
|
970
|
-
});
|
|
971
|
-
context.on("kubb:files:processing:start", ({ files }) => {
|
|
972
|
-
state.cachedLogs.add({
|
|
973
|
-
date: /* @__PURE__ */ new Date(),
|
|
974
|
-
logs: [`Start ${files.length} writing:`, ...files.map((file) => file.path)]
|
|
975
|
-
});
|
|
976
|
-
});
|
|
977
|
-
context.on("kubb:generation:end", async ({ config }) => {
|
|
978
|
-
const writtenFilePaths = await writeLogs(config.name);
|
|
979
|
-
if (writtenFilePaths.length > 0) {
|
|
980
|
-
const files = writtenFilePaths.map((f) => relative(process$1.cwd(), f));
|
|
981
|
-
await context.emit("kubb:info", {
|
|
982
|
-
message: "Debug files written to:",
|
|
983
|
-
info: files.join(", ")
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
reset();
|
|
987
|
-
});
|
|
988
|
-
const exitHandler = () => {
|
|
989
|
-
if (state.cachedLogs.size > 0) writeLogs().catch(() => {});
|
|
782
|
+
return (_commandWithArgs, hookId) => {
|
|
783
|
+
if (logLevel$6 <= logLevel.silent) return {
|
|
784
|
+
onStdout: (s) => console.log(s),
|
|
785
|
+
onStderr: (s) => console.error(s)
|
|
786
|
+
};
|
|
787
|
+
const active = state.activeHookLogs.get(hookId);
|
|
788
|
+
if (!active) return null;
|
|
789
|
+
const { taskLog } = active;
|
|
790
|
+
return {
|
|
791
|
+
stream: true,
|
|
792
|
+
onLine: (line) => taskLog.message(styleText("dim", line)),
|
|
793
|
+
onStdout: (s) => taskLog.message(s),
|
|
794
|
+
onStderr: (s) => taskLog.message(styleText("red", s))
|
|
795
|
+
};
|
|
990
796
|
};
|
|
991
|
-
process$1.once("exit", exitHandler);
|
|
992
|
-
process$1.once("SIGINT", exitHandler);
|
|
993
|
-
process$1.once("SIGTERM", exitHandler);
|
|
994
797
|
}
|
|
995
798
|
});
|
|
996
799
|
//#endregion
|
|
@@ -1001,41 +804,57 @@ const fileSystemLogger = defineLogger({
|
|
|
1001
804
|
const githubActionsLogger = defineLogger({
|
|
1002
805
|
name: "github-actions",
|
|
1003
806
|
install(context, options) {
|
|
1004
|
-
const logLevel$
|
|
807
|
+
const logLevel$5 = options?.logLevel ?? logLevel.info;
|
|
1005
808
|
const state = {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
totalFiles: 0,
|
|
1010
|
-
processedFiles: 0,
|
|
1011
|
-
hrStart: process.hrtime(),
|
|
1012
|
-
currentConfigs: []
|
|
809
|
+
...createProgressCounters(),
|
|
810
|
+
currentConfigs: [],
|
|
811
|
+
openGroupDepth: 0
|
|
1013
812
|
};
|
|
813
|
+
const hookTimer = createHookTimer();
|
|
1014
814
|
function reset() {
|
|
1015
|
-
|
|
1016
|
-
state
|
|
1017
|
-
state.failedPlugins = 0;
|
|
1018
|
-
state.totalFiles = 0;
|
|
1019
|
-
state.processedFiles = 0;
|
|
1020
|
-
state.hrStart = process.hrtime();
|
|
815
|
+
closeAllGroups();
|
|
816
|
+
resetProgressCounters(state);
|
|
1021
817
|
state.currentConfigs = [];
|
|
818
|
+
hookTimer.clear();
|
|
1022
819
|
}
|
|
1023
820
|
function showProgressStep() {
|
|
1024
|
-
if (logLevel$
|
|
821
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1025
822
|
const line = buildProgressLine(state);
|
|
1026
823
|
if (line) console.log(getMessage(line));
|
|
1027
824
|
}
|
|
1028
825
|
function getMessage(message) {
|
|
1029
|
-
return formatMessage(message, logLevel$
|
|
826
|
+
return formatMessage(message, logLevel$5);
|
|
1030
827
|
}
|
|
1031
828
|
function openGroup(name) {
|
|
1032
829
|
console.log(`::group::${name}`);
|
|
830
|
+
state.openGroupDepth++;
|
|
1033
831
|
}
|
|
1034
832
|
function closeGroup(_name) {
|
|
1035
833
|
console.log("::endgroup::");
|
|
834
|
+
if (state.openGroupDepth > 0) state.openGroupDepth--;
|
|
835
|
+
}
|
|
836
|
+
function closeAllGroups() {
|
|
837
|
+
while (state.openGroupDepth > 0) {
|
|
838
|
+
console.log("::endgroup::");
|
|
839
|
+
state.openGroupDepth--;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function onGroupStart(event, message, group) {
|
|
843
|
+
context.on(event, () => {
|
|
844
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
845
|
+
if (state.currentConfigs.length === 1) openGroup(group);
|
|
846
|
+
console.log(getMessage(message));
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function onGroupEnd(event, message, group) {
|
|
850
|
+
context.on(event, () => {
|
|
851
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
852
|
+
console.log(getMessage(message));
|
|
853
|
+
if (state.currentConfigs.length === 1) closeGroup(group);
|
|
854
|
+
});
|
|
1036
855
|
}
|
|
1037
856
|
context.on("kubb:info", ({ message, info = "" }) => {
|
|
1038
|
-
if (logLevel$
|
|
857
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1039
858
|
const text = getMessage([
|
|
1040
859
|
styleText("blue", "ℹ"),
|
|
1041
860
|
message,
|
|
@@ -1044,29 +863,29 @@ const githubActionsLogger = defineLogger({
|
|
|
1044
863
|
console.log(text);
|
|
1045
864
|
});
|
|
1046
865
|
context.on("kubb:success", ({ message, info = "" }) => {
|
|
1047
|
-
if (logLevel$
|
|
866
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1048
867
|
const text = getMessage([
|
|
1049
868
|
styleText("blue", "✓"),
|
|
1050
869
|
message,
|
|
1051
|
-
logLevel$
|
|
870
|
+
logLevel$5 >= logLevel.info ? styleText("dim", info) : void 0
|
|
1052
871
|
].filter(Boolean).join(" "));
|
|
1053
872
|
console.log(text);
|
|
1054
873
|
});
|
|
1055
874
|
context.on("kubb:warn", ({ message, info = "" }) => {
|
|
1056
|
-
if (logLevel$
|
|
875
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1057
876
|
const text = getMessage([
|
|
1058
877
|
styleText("yellow", "⚠"),
|
|
1059
878
|
message,
|
|
1060
|
-
logLevel$
|
|
879
|
+
logLevel$5 >= logLevel.info ? styleText("dim", info) : void 0
|
|
1061
880
|
].filter(Boolean).join(" "));
|
|
1062
881
|
console.warn(`::warning::${text}`);
|
|
1063
882
|
});
|
|
1064
883
|
context.on("kubb:error", ({ error }) => {
|
|
1065
884
|
const caused = toCause(error);
|
|
1066
|
-
|
|
885
|
+
closeAllGroups();
|
|
1067
886
|
const message = error.message || String(error);
|
|
1068
887
|
console.error(`::error::${message}`);
|
|
1069
|
-
if (logLevel$
|
|
888
|
+
if (logLevel$5 >= logLevel.verbose && error.stack) {
|
|
1070
889
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
1071
890
|
for (const frame of frames) console.log(getMessage(styleText("dim", frame.trim())));
|
|
1072
891
|
if (caused?.stack) {
|
|
@@ -1076,19 +895,33 @@ const githubActionsLogger = defineLogger({
|
|
|
1076
895
|
}
|
|
1077
896
|
}
|
|
1078
897
|
});
|
|
898
|
+
context.on("kubb:diagnostic", ({ diagnostic }) => {
|
|
899
|
+
closeAllGroups();
|
|
900
|
+
if (logLevel$5 <= logLevel.silent && diagnostic.severity !== "error") return;
|
|
901
|
+
if (!Diagnostics.isProblem(diagnostic)) {
|
|
902
|
+
console.log(`::notice::${diagnostic.message}`);
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const parts = [`${diagnostic.code} ${diagnostic.message}`];
|
|
906
|
+
if (diagnostic.location && "pointer" in diagnostic.location) parts.push(`(at ${diagnostic.location.pointer})`);
|
|
907
|
+
if (diagnostic.plugin) parts.push(`[plugin: ${diagnostic.plugin}]`);
|
|
908
|
+
if (diagnostic.help) parts.push(`help: ${diagnostic.help}`);
|
|
909
|
+
if (diagnostic.code !== Diagnostics.code.unknown) parts.push(`docs: ${Diagnostics.docsUrl(diagnostic.code)}`);
|
|
910
|
+
console.error(`::error::${parts.join(" ")}`);
|
|
911
|
+
});
|
|
1079
912
|
context.on("kubb:lifecycle:start", ({ version }) => {
|
|
1080
913
|
console.log(styleText("yellow", `Kubb ${version} 🧩`));
|
|
1081
914
|
reset();
|
|
1082
915
|
});
|
|
1083
916
|
context.on("kubb:config:start", () => {
|
|
1084
|
-
if (logLevel$
|
|
917
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1085
918
|
const text = getMessage("Configuration started");
|
|
1086
919
|
openGroup("Configuration");
|
|
1087
920
|
console.log(text);
|
|
1088
921
|
});
|
|
1089
922
|
context.on("kubb:config:end", ({ configs }) => {
|
|
1090
923
|
state.currentConfigs = configs;
|
|
1091
|
-
if (logLevel$
|
|
924
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1092
925
|
const text = getMessage("Configuration completed");
|
|
1093
926
|
console.log(text);
|
|
1094
927
|
closeGroup("Configuration");
|
|
@@ -1101,15 +934,14 @@ const githubActionsLogger = defineLogger({
|
|
|
1101
934
|
if (state.currentConfigs.length === 1) console.log(getMessage(text));
|
|
1102
935
|
});
|
|
1103
936
|
context.on("kubb:plugin:start", ({ plugin }) => {
|
|
1104
|
-
if (logLevel$
|
|
937
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1105
938
|
const text = getMessage(`Generating ${styleText("bold", plugin.name)}`);
|
|
1106
939
|
if (state.currentConfigs.length === 1) openGroup(`Plugin: ${plugin.name}`);
|
|
1107
940
|
console.log(text);
|
|
1108
941
|
});
|
|
1109
942
|
context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
1110
|
-
if (logLevel$
|
|
1111
|
-
|
|
1112
|
-
else state.failedPlugins++;
|
|
943
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
944
|
+
recordPluginResult(state, success);
|
|
1113
945
|
const durationStr = formatMsWithColor(duration);
|
|
1114
946
|
const text = getMessage(success ? `${styleText("bold", plugin.name)} completed in ${durationStr}` : `${styleText("bold", plugin.name)} failed in ${styleText("red", formatMs(duration))}`);
|
|
1115
947
|
console.log(text);
|
|
@@ -1118,7 +950,7 @@ const githubActionsLogger = defineLogger({
|
|
|
1118
950
|
showProgressStep();
|
|
1119
951
|
});
|
|
1120
952
|
context.on("kubb:files:processing:start", ({ files }) => {
|
|
1121
|
-
if (logLevel$
|
|
953
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1122
954
|
state.totalFiles = files.length;
|
|
1123
955
|
state.processedFiles = 0;
|
|
1124
956
|
if (state.currentConfigs.length === 1) openGroup("File Generation");
|
|
@@ -1126,82 +958,54 @@ const githubActionsLogger = defineLogger({
|
|
|
1126
958
|
console.log(text);
|
|
1127
959
|
});
|
|
1128
960
|
context.on("kubb:files:processing:end", () => {
|
|
1129
|
-
if (logLevel$
|
|
961
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
1130
962
|
const text = getMessage("Files written successfully");
|
|
1131
963
|
console.log(text);
|
|
1132
964
|
if (state.currentConfigs.length === 1) closeGroup("File Generation");
|
|
1133
965
|
showProgressStep();
|
|
1134
966
|
});
|
|
1135
|
-
context.on("kubb:
|
|
1136
|
-
if (logLevel$
|
|
1137
|
-
state.processedFiles
|
|
967
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
968
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
969
|
+
state.processedFiles += files.length;
|
|
1138
970
|
});
|
|
1139
971
|
context.on("kubb:generation:end", ({ config }) => {
|
|
1140
972
|
const text = getMessage(config.name ? `${styleText("blue", "✓")} Generation completed for ${styleText("dim", config.name)}` : `${styleText("blue", "✓")} Generation completed`);
|
|
1141
973
|
console.log(text);
|
|
974
|
+
if (state.currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${styleText("bold", config.name)}` : "Generation");
|
|
1142
975
|
});
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
context.on("kubb:
|
|
1150
|
-
if (logLevel$
|
|
1151
|
-
|
|
1152
|
-
console.log(text);
|
|
1153
|
-
if (state.currentConfigs.length === 1) closeGroup("Formatting");
|
|
1154
|
-
});
|
|
1155
|
-
context.on("kubb:lint:start", () => {
|
|
1156
|
-
if (logLevel$7 <= logLevel.silent) return;
|
|
1157
|
-
const text = getMessage("Lint started");
|
|
1158
|
-
if (state.currentConfigs.length === 1) openGroup("Linting");
|
|
1159
|
-
console.log(text);
|
|
1160
|
-
});
|
|
1161
|
-
context.on("kubb:lint:end", () => {
|
|
1162
|
-
if (logLevel$7 <= logLevel.silent) return;
|
|
1163
|
-
const text = getMessage("Lint completed");
|
|
1164
|
-
console.log(text);
|
|
1165
|
-
if (state.currentConfigs.length === 1) closeGroup("Linting");
|
|
1166
|
-
});
|
|
1167
|
-
context.on("kubb:hook:start", async ({ id, command, args }) => {
|
|
976
|
+
onGroupStart("kubb:format:start", "Format started", "Formatting");
|
|
977
|
+
onGroupEnd("kubb:format:end", "Format completed", "Formatting");
|
|
978
|
+
onGroupStart("kubb:lint:start", "Lint started", "Linting");
|
|
979
|
+
onGroupEnd("kubb:lint:end", "Lint completed", "Linting");
|
|
980
|
+
onGroupStart("kubb:hooks:start", "Hooks started", "Hooks");
|
|
981
|
+
onGroupEnd("kubb:hooks:end", "Hooks completed", "Hooks");
|
|
982
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
983
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
984
|
+
if (id) hookTimer.start(id);
|
|
1168
985
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1169
986
|
const text = getMessage(`Hook ${styleText("dim", commandWithArgs)} started`);
|
|
1170
|
-
if (
|
|
1171
|
-
|
|
1172
|
-
console.log(text);
|
|
1173
|
-
}
|
|
1174
|
-
if (!id) return;
|
|
1175
|
-
await runHook({
|
|
1176
|
-
id,
|
|
1177
|
-
command,
|
|
1178
|
-
args,
|
|
1179
|
-
commandWithArgs,
|
|
1180
|
-
context,
|
|
1181
|
-
sink: {
|
|
1182
|
-
onStdout: logLevel$7 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1183
|
-
onStderr: logLevel$7 > logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
|
|
1184
|
-
}
|
|
1185
|
-
});
|
|
987
|
+
if (state.currentConfigs.length === 1) openGroup(`Hook ${commandWithArgs}`);
|
|
988
|
+
console.log(text);
|
|
1186
989
|
});
|
|
1187
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
1188
|
-
if (logLevel$
|
|
990
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
991
|
+
if (logLevel$5 <= logLevel.silent) return;
|
|
992
|
+
const ms = id ? hookTimer.end(id) : void 0;
|
|
993
|
+
const durationStr = ms !== void 0 ? ` in ${formatMsWithColor(ms)}` : "";
|
|
1189
994
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1190
|
-
|
|
1191
|
-
|
|
995
|
+
if (success) console.log(getMessage(`${styleText("green", "✓")} Hook ${styleText("dim", commandWithArgs)} completed${durationStr}`));
|
|
996
|
+
else {
|
|
997
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
998
|
+
console.log(`::error::Hook ${commandWithArgs} failed${durationStr}${reason}`);
|
|
999
|
+
}
|
|
1192
1000
|
if (state.currentConfigs.length === 1) closeGroup(`Hook ${commandWithArgs}`);
|
|
1193
1001
|
});
|
|
1194
|
-
context.on("kubb:generation:summary", ({ config, status, hrStart, failedPlugins }) => {
|
|
1195
|
-
const pluginsCount = config.plugins?.length ?? 0;
|
|
1196
|
-
const successCount = pluginsCount - failedPlugins.size;
|
|
1197
|
-
const duration = formatHrtime(hrStart);
|
|
1198
|
-
if (state.currentConfigs.length > 1) console.log(" ");
|
|
1199
|
-
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)}`);
|
|
1200
|
-
if (state.currentConfigs.length > 1) closeGroup(config.name ? `Generation for ${styleText("bold", config.name)}` : "Generation");
|
|
1201
|
-
});
|
|
1202
1002
|
context.on("kubb:lifecycle:end", () => {
|
|
1203
1003
|
reset();
|
|
1204
1004
|
});
|
|
1005
|
+
return (_commandWithArgs, _hookId) => ({
|
|
1006
|
+
onStdout: logLevel$5 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1007
|
+
onStderr: logLevel$5 > logLevel.silent ? (s) => console.error(`::error::${s}`) : void 0
|
|
1008
|
+
});
|
|
1205
1009
|
}
|
|
1206
1010
|
});
|
|
1207
1011
|
//#endregion
|
|
@@ -1212,12 +1016,19 @@ const githubActionsLogger = defineLogger({
|
|
|
1212
1016
|
const plainLogger = defineLogger({
|
|
1213
1017
|
name: "plain",
|
|
1214
1018
|
install(context, options) {
|
|
1215
|
-
const logLevel$
|
|
1019
|
+
const logLevel$4 = options?.logLevel ?? logLevel.info;
|
|
1020
|
+
const hookTimer = createHookTimer();
|
|
1216
1021
|
function getMessage(message) {
|
|
1217
|
-
return formatMessage(message, logLevel$
|
|
1022
|
+
return formatMessage(message, logLevel$4);
|
|
1023
|
+
}
|
|
1024
|
+
function onStep(event, message) {
|
|
1025
|
+
context.on(event, () => {
|
|
1026
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1027
|
+
console.log(getMessage(message));
|
|
1028
|
+
});
|
|
1218
1029
|
}
|
|
1219
1030
|
context.on("kubb:info", ({ message, info }) => {
|
|
1220
|
-
if (logLevel$
|
|
1031
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1221
1032
|
const text = getMessage([
|
|
1222
1033
|
"ℹ",
|
|
1223
1034
|
message,
|
|
@@ -1226,20 +1037,20 @@ const plainLogger = defineLogger({
|
|
|
1226
1037
|
console.log(text);
|
|
1227
1038
|
});
|
|
1228
1039
|
context.on("kubb:success", ({ message, info = "" }) => {
|
|
1229
|
-
if (logLevel$
|
|
1040
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1230
1041
|
const text = getMessage([
|
|
1231
1042
|
"✓",
|
|
1232
1043
|
message,
|
|
1233
|
-
logLevel$
|
|
1044
|
+
logLevel$4 >= logLevel.info ? info : void 0
|
|
1234
1045
|
].filter(Boolean).join(" "));
|
|
1235
1046
|
console.log(text);
|
|
1236
1047
|
});
|
|
1237
1048
|
context.on("kubb:warn", ({ message, info }) => {
|
|
1238
|
-
if (logLevel$
|
|
1049
|
+
if (logLevel$4 < logLevel.warn) return;
|
|
1239
1050
|
const text = getMessage([
|
|
1240
1051
|
"⚠",
|
|
1241
1052
|
message,
|
|
1242
|
-
logLevel$
|
|
1053
|
+
logLevel$4 >= logLevel.info ? info : void 0
|
|
1243
1054
|
].filter(Boolean).join(" "));
|
|
1244
1055
|
console.log(text);
|
|
1245
1056
|
});
|
|
@@ -1247,7 +1058,7 @@ const plainLogger = defineLogger({
|
|
|
1247
1058
|
const caused = toCause(error);
|
|
1248
1059
|
const text = getMessage(["✗", error.message].join(" "));
|
|
1249
1060
|
console.log(text);
|
|
1250
|
-
if (logLevel$
|
|
1061
|
+
if (logLevel$4 >= logLevel.verbose && error.stack) {
|
|
1251
1062
|
const frames = error.stack.split("\n").slice(1, 4);
|
|
1252
1063
|
for (const frame of frames) console.log(getMessage(frame.trim()));
|
|
1253
1064
|
if (caused?.stack) {
|
|
@@ -1257,46 +1068,41 @@ const plainLogger = defineLogger({
|
|
|
1257
1068
|
}
|
|
1258
1069
|
}
|
|
1259
1070
|
});
|
|
1260
|
-
context.on("kubb:
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
context.on("kubb:config:start", () => {
|
|
1264
|
-
if (logLevel$6 <= logLevel.silent) return;
|
|
1265
|
-
const text = getMessage("Configuration started");
|
|
1266
|
-
console.log(text);
|
|
1071
|
+
context.on("kubb:diagnostic", ({ diagnostic }) => {
|
|
1072
|
+
if (logLevel$4 <= logLevel.silent && diagnostic.severity !== "error") return;
|
|
1073
|
+
console.log(getMessage(Diagnostics.formatLines(diagnostic).join("\n")));
|
|
1267
1074
|
});
|
|
1268
|
-
context.on("kubb:
|
|
1269
|
-
|
|
1270
|
-
const text = getMessage("Configuration completed");
|
|
1271
|
-
console.log(text);
|
|
1075
|
+
context.on("kubb:lifecycle:start", ({ version }) => {
|
|
1076
|
+
console.log(`Kubb CLI v${version}`);
|
|
1272
1077
|
});
|
|
1078
|
+
onStep("kubb:config:start", "Configuration started");
|
|
1079
|
+
onStep("kubb:config:end", "Configuration completed");
|
|
1273
1080
|
context.on("kubb:generation:start", () => {
|
|
1274
1081
|
const text = getMessage("Generation started");
|
|
1275
1082
|
console.log(text);
|
|
1276
1083
|
});
|
|
1277
1084
|
context.on("kubb:plugin:start", ({ plugin }) => {
|
|
1278
|
-
if (logLevel$
|
|
1085
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1279
1086
|
const text = getMessage(`Generating ${plugin.name}`);
|
|
1280
1087
|
console.log(text);
|
|
1281
1088
|
});
|
|
1282
1089
|
context.on("kubb:plugin:end", ({ plugin, duration, success }) => {
|
|
1283
|
-
if (logLevel$
|
|
1090
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1284
1091
|
const durationStr = formatMs(duration);
|
|
1285
1092
|
const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`);
|
|
1286
1093
|
console.log(text);
|
|
1287
1094
|
});
|
|
1288
1095
|
context.on("kubb:files:processing:start", ({ files }) => {
|
|
1289
|
-
if (logLevel$
|
|
1096
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1290
1097
|
const text = getMessage(`Writing ${files.length} files`);
|
|
1291
1098
|
console.log(text);
|
|
1292
1099
|
});
|
|
1293
|
-
context.on("kubb:
|
|
1294
|
-
if (logLevel$
|
|
1295
|
-
const
|
|
1296
|
-
console.log(text);
|
|
1100
|
+
context.on("kubb:files:processing:update", ({ files }) => {
|
|
1101
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1102
|
+
for (const { file, config } of files) console.log(getMessage(`Writing ${relative(config.root, file.path)}`));
|
|
1297
1103
|
});
|
|
1298
1104
|
context.on("kubb:files:processing:end", () => {
|
|
1299
|
-
if (logLevel$
|
|
1105
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1300
1106
|
const text = getMessage("Files written successfully");
|
|
1301
1107
|
console.log(text);
|
|
1302
1108
|
});
|
|
@@ -1304,60 +1110,32 @@ const plainLogger = defineLogger({
|
|
|
1304
1110
|
const text = getMessage(config.name ? `Generation completed for ${config.name}` : "Generation completed");
|
|
1305
1111
|
console.log(text);
|
|
1306
1112
|
});
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
});
|
|
1317
|
-
context.on("kubb:lint:start", () => {
|
|
1318
|
-
if (logLevel$6 <= logLevel.silent) return;
|
|
1319
|
-
const text = getMessage("Lint started");
|
|
1320
|
-
console.log(text);
|
|
1321
|
-
});
|
|
1322
|
-
context.on("kubb:lint:end", () => {
|
|
1323
|
-
if (logLevel$6 <= logLevel.silent) return;
|
|
1324
|
-
const text = getMessage("Lint completed");
|
|
1325
|
-
console.log(text);
|
|
1326
|
-
});
|
|
1327
|
-
context.on("kubb:hook:start", async ({ id, command, args }) => {
|
|
1113
|
+
onStep("kubb:format:start", "Format started");
|
|
1114
|
+
onStep("kubb:format:end", "Format completed");
|
|
1115
|
+
onStep("kubb:lint:start", "Lint started");
|
|
1116
|
+
onStep("kubb:lint:end", "Lint completed");
|
|
1117
|
+
onStep("kubb:hooks:start", "Hooks started");
|
|
1118
|
+
onStep("kubb:hooks:end", "Hooks completed");
|
|
1119
|
+
context.on("kubb:hook:start", ({ id, command, args }) => {
|
|
1120
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1121
|
+
if (id) hookTimer.start(id);
|
|
1328
1122
|
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1329
|
-
|
|
1330
|
-
if (logLevel$6 > logLevel.silent) console.log(text);
|
|
1331
|
-
if (!id) return;
|
|
1332
|
-
await runHook({
|
|
1333
|
-
id,
|
|
1334
|
-
command,
|
|
1335
|
-
args,
|
|
1336
|
-
commandWithArgs,
|
|
1337
|
-
context,
|
|
1338
|
-
sink: {
|
|
1339
|
-
onStdout: logLevel$6 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1340
|
-
onStderr: logLevel$6 > logLevel.silent ? (s) => console.error(s) : void 0
|
|
1341
|
-
}
|
|
1342
|
-
});
|
|
1123
|
+
console.log(getMessage(`Hook ${commandWithArgs} started`));
|
|
1343
1124
|
});
|
|
1344
|
-
context.on("kubb:hook:end", ({ command, args }) => {
|
|
1345
|
-
if (logLevel$
|
|
1346
|
-
const
|
|
1347
|
-
|
|
1125
|
+
context.on("kubb:hook:end", ({ id, command, args, success, error }) => {
|
|
1126
|
+
if (logLevel$4 <= logLevel.silent) return;
|
|
1127
|
+
const ms = id ? hookTimer.end(id) : void 0;
|
|
1128
|
+
const durationStr = ms !== void 0 ? ` in ${formatMs(ms)}` : "";
|
|
1129
|
+
const commandWithArgs = formatCommandWithArgs(command, args);
|
|
1130
|
+
if (success) console.log(getMessage(`✓ Hook ${commandWithArgs} completed${durationStr}`));
|
|
1131
|
+
else {
|
|
1132
|
+
const reason = error?.message ? ` (${error.message})` : "";
|
|
1133
|
+
console.log(getMessage(`✗ Hook ${commandWithArgs} failed${durationStr}${reason}`));
|
|
1134
|
+
}
|
|
1348
1135
|
});
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
filesCreated,
|
|
1353
|
-
config,
|
|
1354
|
-
status,
|
|
1355
|
-
hrStart,
|
|
1356
|
-
pluginTimings: logLevel$6 >= logLevel.verbose ? pluginTimings : void 0
|
|
1357
|
-
});
|
|
1358
|
-
console.log(SUMMARY_SEPARATOR);
|
|
1359
|
-
console.log(summary.join("\n"));
|
|
1360
|
-
console.log(SUMMARY_SEPARATOR);
|
|
1136
|
+
return (_commandWithArgs, _hookId) => ({
|
|
1137
|
+
onStdout: logLevel$4 > logLevel.silent ? (s) => console.log(s) : void 0,
|
|
1138
|
+
onStderr: logLevel$4 > logLevel.silent ? (s) => console.error(s) : void 0
|
|
1361
1139
|
});
|
|
1362
1140
|
}
|
|
1363
1141
|
});
|
|
@@ -1367,8 +1145,8 @@ const plainLogger = defineLogger({
|
|
|
1367
1145
|
* Optionally prefix a message with a [HH:MM:SS] timestamp when logLevel >= verbose.
|
|
1368
1146
|
* Shared across all logger adapters to avoid duplication.
|
|
1369
1147
|
*/
|
|
1370
|
-
function formatMessage(message, logLevel$
|
|
1371
|
-
if (logLevel$
|
|
1148
|
+
function formatMessage(message, logLevel$3) {
|
|
1149
|
+
if (logLevel$3 >= logLevel.verbose) return `${styleText("dim", `[${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
|
|
1372
1150
|
hour12: false,
|
|
1373
1151
|
hour: "2-digit",
|
|
1374
1152
|
minute: "2-digit",
|
|
@@ -1393,6 +1171,57 @@ function buildProgressLine(state) {
|
|
|
1393
1171
|
return parts.join(styleText("dim", " | "));
|
|
1394
1172
|
}
|
|
1395
1173
|
/**
|
|
1174
|
+
* Creates the per-run progress counters shared by the clack and GitHub Actions loggers.
|
|
1175
|
+
*/
|
|
1176
|
+
function createProgressCounters() {
|
|
1177
|
+
return {
|
|
1178
|
+
totalPlugins: 0,
|
|
1179
|
+
completedPlugins: 0,
|
|
1180
|
+
failedPlugins: 0,
|
|
1181
|
+
totalFiles: 0,
|
|
1182
|
+
processedFiles: 0,
|
|
1183
|
+
hrStart: process$1.hrtime()
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Resets the progress counters in place at the start/end of a generation run.
|
|
1188
|
+
*/
|
|
1189
|
+
function resetProgressCounters(state) {
|
|
1190
|
+
state.totalPlugins = 0;
|
|
1191
|
+
state.completedPlugins = 0;
|
|
1192
|
+
state.failedPlugins = 0;
|
|
1193
|
+
state.totalFiles = 0;
|
|
1194
|
+
state.processedFiles = 0;
|
|
1195
|
+
state.hrStart = process$1.hrtime();
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Records a finished plugin against the progress counters.
|
|
1199
|
+
*/
|
|
1200
|
+
function recordPluginResult(state, success) {
|
|
1201
|
+
if (success) state.completedPlugins++;
|
|
1202
|
+
else state.failedPlugins++;
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Creates a {@link HookTimer} backed by a private `id → hrtime` map.
|
|
1206
|
+
*/
|
|
1207
|
+
function createHookTimer() {
|
|
1208
|
+
const starts = /* @__PURE__ */ new Map();
|
|
1209
|
+
return {
|
|
1210
|
+
start(id) {
|
|
1211
|
+
starts.set(id, process$1.hrtime());
|
|
1212
|
+
},
|
|
1213
|
+
end(id) {
|
|
1214
|
+
const hrStart = starts.get(id);
|
|
1215
|
+
if (!hrStart) return;
|
|
1216
|
+
starts.delete(id);
|
|
1217
|
+
return getElapsedMs(hrStart);
|
|
1218
|
+
},
|
|
1219
|
+
clear() {
|
|
1220
|
+
starts.clear();
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1396
1225
|
* Join a command and its optional args into a single display string.
|
|
1397
1226
|
* e.g. ("prettier", ["--write", "."]) → "prettier --write ."
|
|
1398
1227
|
*/
|
|
@@ -1409,129 +1238,233 @@ const logMapper = {
|
|
|
1409
1238
|
plain: plainLogger,
|
|
1410
1239
|
"github-actions": githubActionsLogger
|
|
1411
1240
|
};
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1241
|
+
/**
|
|
1242
|
+
* Bridges a {@link Reporter} onto the run's event emitter: calls `report` with each config's
|
|
1243
|
+
* {@link GenerationResult} on `kubb:generation:end`. The reporter never touches the emitter.
|
|
1244
|
+
*/
|
|
1245
|
+
function installReporter(context, reporter, ctx) {
|
|
1246
|
+
context.on("kubb:generation:end", async ({ config, diagnostics = [], filesCreated = 0, status = "success", hrStart = process$1.hrtime() }) => {
|
|
1247
|
+
await reporter.report({
|
|
1248
|
+
config,
|
|
1249
|
+
diagnostics,
|
|
1250
|
+
filesCreated,
|
|
1251
|
+
status,
|
|
1252
|
+
hrStart
|
|
1253
|
+
}, ctx);
|
|
1254
|
+
});
|
|
1255
|
+
if (reporter.drain) context.on("kubb:lifecycle:end", () => reporter.drain?.(ctx));
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Installs the live logger (the TUI view) and the given reporters (the output), returning the
|
|
1259
|
+
* terminal logger's hook sink when one was installed. The reporters are already selected by the
|
|
1260
|
+
* caller (the CLI maps `--reporter` to names via `selectReporters`); this only wires them.
|
|
1261
|
+
*
|
|
1262
|
+
* Loggers and reporters are independent: the `cli` reporter also activates the env logger summary.
|
|
1263
|
+
* The `json` reporter owns stdout, so the live logger and the `cli` summary are suppressed whenever
|
|
1264
|
+
* `json` is among the reporters, even if `cli` is also listed.
|
|
1265
|
+
*/
|
|
1266
|
+
async function setupReporters(context, { logLevel, reporters }) {
|
|
1267
|
+
const hasJson = reporters.some((reporter) => reporter.name === "json");
|
|
1268
|
+
const ctx = { logLevel };
|
|
1269
|
+
let makeSink = null;
|
|
1270
|
+
for (const reporter of reporters) {
|
|
1271
|
+
if (reporter.name === "cli") {
|
|
1272
|
+
if (hasJson) continue;
|
|
1273
|
+
const type = detectLogger();
|
|
1274
|
+
const logger = logMapper[type];
|
|
1275
|
+
if (!logger) throw new Error(`Unknown adapter type: ${type}`);
|
|
1276
|
+
const sink = await logger.install(context, { logLevel });
|
|
1277
|
+
makeSink = typeof sink === "function" ? sink : null;
|
|
1278
|
+
}
|
|
1279
|
+
installReporter(context, reporter, ctx);
|
|
1280
|
+
}
|
|
1281
|
+
return makeSink;
|
|
1419
1282
|
}
|
|
1420
1283
|
//#endregion
|
|
1421
|
-
//#region src/utils
|
|
1422
|
-
|
|
1284
|
+
//#region src/runners/generate/utils.ts
|
|
1285
|
+
const jiti = createJiti(import.meta.url, {
|
|
1286
|
+
jsx: {
|
|
1287
|
+
runtime: "automatic",
|
|
1288
|
+
importSource: "@kubb/renderer-jsx"
|
|
1289
|
+
},
|
|
1290
|
+
moduleCache: false
|
|
1291
|
+
});
|
|
1292
|
+
const tsLoader = (configFile) => jiti.import(configFile, { default: true });
|
|
1293
|
+
const MODULE_NAME = "kubb";
|
|
1294
|
+
const BASE_SEARCH_PLACES = [
|
|
1295
|
+
"package.json",
|
|
1296
|
+
`.${MODULE_NAME}rc`,
|
|
1297
|
+
`.${MODULE_NAME}rc.json`,
|
|
1298
|
+
`.${MODULE_NAME}rc.yaml`,
|
|
1299
|
+
`.${MODULE_NAME}rc.yml`,
|
|
1300
|
+
`.${MODULE_NAME}rc.ts`,
|
|
1301
|
+
`.${MODULE_NAME}rc.mts`,
|
|
1302
|
+
`.${MODULE_NAME}rc.cts`,
|
|
1303
|
+
`.${MODULE_NAME}rc.js`,
|
|
1304
|
+
`.${MODULE_NAME}rc.mjs`,
|
|
1305
|
+
`.${MODULE_NAME}rc.cjs`,
|
|
1306
|
+
`${MODULE_NAME}.config.ts`,
|
|
1307
|
+
`${MODULE_NAME}.config.mts`,
|
|
1308
|
+
`${MODULE_NAME}.config.cts`,
|
|
1309
|
+
`${MODULE_NAME}.config.js`,
|
|
1310
|
+
`${MODULE_NAME}.config.mjs`,
|
|
1311
|
+
`${MODULE_NAME}.config.cjs`
|
|
1312
|
+
];
|
|
1313
|
+
const SEARCH_PLACES = [
|
|
1314
|
+
"",
|
|
1315
|
+
".config/",
|
|
1316
|
+
"configs/"
|
|
1317
|
+
].flatMap((prefix) => BASE_SEARCH_PLACES.map((p) => `${prefix}${p}`));
|
|
1318
|
+
async function getCosmiConfig(configFile) {
|
|
1319
|
+
const explorer = cosmiconfig(MODULE_NAME, {
|
|
1320
|
+
cache: false,
|
|
1321
|
+
searchPlaces: SEARCH_PLACES,
|
|
1322
|
+
loaders: {
|
|
1323
|
+
".ts": tsLoader,
|
|
1324
|
+
".mts": tsLoader,
|
|
1325
|
+
".cts": tsLoader
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
let result;
|
|
1329
|
+
try {
|
|
1330
|
+
result = configFile ? await explorer.load(configFile) : await explorer.search();
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
throw new Error("Config failed loading", { cause: error });
|
|
1333
|
+
}
|
|
1334
|
+
if (!result?.config || result.isEmpty) throw new Error("Config not defined, create a kubb.config.js or pass through your config with the option --config");
|
|
1335
|
+
return result;
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Discovers the Kubb config via cosmiconfig and resolves it into a normalized array of configs.
|
|
1339
|
+
* Every config in the result is guaranteed to have a `plugins` array.
|
|
1340
|
+
*/
|
|
1341
|
+
async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
1342
|
+
const result = await getCosmiConfig(configPath);
|
|
1343
|
+
const cli = {
|
|
1344
|
+
config: configPath,
|
|
1345
|
+
input,
|
|
1346
|
+
watch,
|
|
1347
|
+
logLevel
|
|
1348
|
+
};
|
|
1349
|
+
const resolved = await (typeof result.config === "function" ? result.config(cli) : result.config);
|
|
1350
|
+
const userConfigs = Array.isArray(resolved) ? resolved : [resolved];
|
|
1351
|
+
return {
|
|
1352
|
+
configPath: result.filepath,
|
|
1353
|
+
configs: userConfigs.map((item) => ({
|
|
1354
|
+
...item,
|
|
1355
|
+
plugins: item.plugins ?? []
|
|
1356
|
+
}))
|
|
1357
|
+
};
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Runs the `done` hooks defined in a Kubb config in sequence.
|
|
1361
|
+
*/
|
|
1362
|
+
async function executeHooks({ configHooks, hooks, makeSink }) {
|
|
1423
1363
|
const commands = Array.isArray(configHooks.done) ? configHooks.done : [configHooks.done].filter(Boolean);
|
|
1424
1364
|
for (const command of commands) {
|
|
1425
1365
|
const [cmd, ...args] = tokenize(command);
|
|
1426
1366
|
if (!cmd) continue;
|
|
1427
1367
|
const hookId = createHash("sha256").update(command).digest("hex");
|
|
1428
|
-
const
|
|
1429
|
-
const handler = (ctx) => {
|
|
1430
|
-
if (ctx.id !== hookId) return;
|
|
1431
|
-
hooks.off("kubb:hook:end", handler);
|
|
1432
|
-
if (!ctx.success) {
|
|
1433
|
-
reject(ctx.error ?? /* @__PURE__ */ new Error(`Hook failed: ${command}`));
|
|
1434
|
-
return;
|
|
1435
|
-
}
|
|
1436
|
-
hooks.emit("kubb:success", { message: `${styleText("dim", command)} successfully executed` }).then(resolve).catch(reject);
|
|
1437
|
-
};
|
|
1438
|
-
hooks.on("kubb:hook:end", handler);
|
|
1439
|
-
});
|
|
1368
|
+
const commandWithArgs = [cmd, ...args].join(" ");
|
|
1440
1369
|
await hooks.emit("kubb:hook:start", {
|
|
1441
1370
|
id: hookId,
|
|
1442
1371
|
command: cmd,
|
|
1443
1372
|
args
|
|
1444
1373
|
});
|
|
1445
|
-
|
|
1374
|
+
const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
|
|
1375
|
+
await runHook({
|
|
1376
|
+
id: hookId,
|
|
1377
|
+
command: cmd,
|
|
1378
|
+
args,
|
|
1379
|
+
commandWithArgs,
|
|
1380
|
+
hooks,
|
|
1381
|
+
stream,
|
|
1382
|
+
sink: {
|
|
1383
|
+
onLine,
|
|
1384
|
+
onStdout,
|
|
1385
|
+
onStderr
|
|
1386
|
+
}
|
|
1387
|
+
});
|
|
1446
1388
|
}
|
|
1447
1389
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
}));
|
|
1456
|
-
}
|
|
1457
|
-
//#endregion
|
|
1458
|
-
//#region src/utils/getCosmiConfig.ts
|
|
1459
|
-
const unrunInputOptions = { transform: { jsx: {
|
|
1460
|
-
runtime: "automatic",
|
|
1461
|
-
importSource: "@kubb/renderer-jsx"
|
|
1462
|
-
} } };
|
|
1463
|
-
const tsLoader = async (configFile) => {
|
|
1464
|
-
const { module } = await unrun({
|
|
1465
|
-
path: configFile,
|
|
1466
|
-
inputOptions: unrunInputOptions
|
|
1467
|
-
});
|
|
1468
|
-
return module;
|
|
1469
|
-
};
|
|
1470
|
-
async function getCosmiConfig(moduleName, config) {
|
|
1471
|
-
let result;
|
|
1472
|
-
const searchPlaces = [
|
|
1473
|
-
"package.json",
|
|
1474
|
-
`.${moduleName}rc`,
|
|
1475
|
-
`.${moduleName}rc.json`,
|
|
1476
|
-
`.${moduleName}rc.yaml`,
|
|
1477
|
-
`.${moduleName}rc.yml`,
|
|
1478
|
-
`.${moduleName}rc.ts`,
|
|
1479
|
-
`.${moduleName}rc.mts`,
|
|
1480
|
-
`.${moduleName}rc.cts`,
|
|
1481
|
-
`.${moduleName}rc.js`,
|
|
1482
|
-
`.${moduleName}rc.mjs`,
|
|
1483
|
-
`.${moduleName}rc.cjs`,
|
|
1484
|
-
`${moduleName}.config.ts`,
|
|
1485
|
-
`${moduleName}.config.mts`,
|
|
1486
|
-
`${moduleName}.config.cts`,
|
|
1487
|
-
`${moduleName}.config.js`,
|
|
1488
|
-
`${moduleName}.config.mjs`,
|
|
1489
|
-
`${moduleName}.config.cjs`
|
|
1490
|
-
];
|
|
1491
|
-
const explorer = cosmiconfig(moduleName, {
|
|
1492
|
-
cache: false,
|
|
1493
|
-
searchPlaces: [
|
|
1494
|
-
...searchPlaces.map((searchPlace) => {
|
|
1495
|
-
return `.config/${searchPlace}`;
|
|
1496
|
-
}),
|
|
1497
|
-
...searchPlaces.map((searchPlace) => {
|
|
1498
|
-
return `configs/${searchPlace}`;
|
|
1499
|
-
}),
|
|
1500
|
-
...searchPlaces
|
|
1501
|
-
],
|
|
1502
|
-
loaders: {
|
|
1503
|
-
".ts": tsLoader,
|
|
1504
|
-
".mts": tsLoader,
|
|
1505
|
-
".cts": tsLoader
|
|
1506
|
-
}
|
|
1390
|
+
async function runHook({ id, command, args, commandWithArgs, hooks, stream = false, sink }) {
|
|
1391
|
+
const emitEnd = (success, error) => hooks.emit("kubb:hook:end", {
|
|
1392
|
+
command,
|
|
1393
|
+
args,
|
|
1394
|
+
id,
|
|
1395
|
+
success,
|
|
1396
|
+
error
|
|
1507
1397
|
});
|
|
1508
1398
|
try {
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1399
|
+
const proc = x(command, [...args ?? []], {
|
|
1400
|
+
nodeOptions: { detached: process.platform !== "win32" },
|
|
1401
|
+
throwOnError: true
|
|
1402
|
+
});
|
|
1403
|
+
if (stream && sink?.onLine) for await (const line of proc) sink.onLine(line);
|
|
1404
|
+
await proc;
|
|
1405
|
+
await hooks.emit("kubb:success", { message: `${styleText("dim", commandWithArgs)} successfully executed` });
|
|
1406
|
+
await emitEnd(true, null);
|
|
1407
|
+
} catch (err) {
|
|
1408
|
+
if (!(err instanceof NonZeroExitError)) {
|
|
1409
|
+
await emitEnd(false, toError(err));
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
const stderr = err.output?.stderr ?? "";
|
|
1413
|
+
const stdout = err.output?.stdout ?? "";
|
|
1414
|
+
if (stderr) sink?.onStderr?.(stderr);
|
|
1415
|
+
if (stdout) sink?.onStdout?.(stdout);
|
|
1416
|
+
await emitEnd(false, /* @__PURE__ */ new Error(`Hook execute failed: ${commandWithArgs}`));
|
|
1512
1417
|
}
|
|
1513
|
-
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");
|
|
1514
|
-
return result;
|
|
1515
1418
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1419
|
+
/**
|
|
1420
|
+
* Starts a file watcher on the given paths and calls `cb` on any change.
|
|
1421
|
+
* Ignores `.git` and `node_modules` directories.
|
|
1422
|
+
*/
|
|
1423
|
+
async function startWatcher(path, cb, log = {
|
|
1424
|
+
info: console.log,
|
|
1425
|
+
error: console.log
|
|
1426
|
+
}) {
|
|
1519
1427
|
const { watch } = await import("chokidar");
|
|
1520
|
-
watch(path, {
|
|
1428
|
+
const watcher = watch(path, {
|
|
1521
1429
|
ignorePermissionErrors: true,
|
|
1522
1430
|
ignored: WATCHER_IGNORED_PATHS
|
|
1523
|
-
})
|
|
1524
|
-
|
|
1431
|
+
});
|
|
1432
|
+
process.once("SIGINT", () => {
|
|
1433
|
+
watcher.close();
|
|
1434
|
+
});
|
|
1435
|
+
process.once("SIGTERM", () => {
|
|
1436
|
+
watcher.close();
|
|
1437
|
+
});
|
|
1438
|
+
watcher.on("all", async (type, file) => {
|
|
1439
|
+
log.info(styleText("yellow", styleText("bold", `Change detected: ${type} ${file}`)));
|
|
1525
1440
|
try {
|
|
1526
1441
|
await cb(path);
|
|
1527
1442
|
} catch (_e) {
|
|
1528
|
-
|
|
1443
|
+
log.error(styleText("red", "Watcher failed"));
|
|
1529
1444
|
}
|
|
1530
1445
|
});
|
|
1531
1446
|
}
|
|
1532
1447
|
//#endregion
|
|
1533
|
-
//#region src/runners/generate.ts
|
|
1534
|
-
|
|
1448
|
+
//#region src/runners/generate/run.ts
|
|
1449
|
+
/**
|
|
1450
|
+
* Registers a one-shot `kubb:hook:end` listener for `hookId` BEFORE the caller emits `kubb:hook:start`,
|
|
1451
|
+
* avoiding the race where a synchronous emitter fires end before the listener is attached.
|
|
1452
|
+
*/
|
|
1453
|
+
function waitForHookEnd(hooks, hookId, onSuccess, fallbackErrorMessage) {
|
|
1454
|
+
return new Promise((resolve, reject) => {
|
|
1455
|
+
const handler = (ctx) => {
|
|
1456
|
+
if (ctx.id !== hookId) return;
|
|
1457
|
+
hooks.off("kubb:hook:end", handler);
|
|
1458
|
+
if (!ctx.success) {
|
|
1459
|
+
reject(ctx.error ?? new Error(fallbackErrorMessage));
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
Promise.resolve(onSuccess()).then(resolve).catch(reject);
|
|
1463
|
+
};
|
|
1464
|
+
hooks.on("kubb:hook:end", handler);
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefix, noToolMessage, configName, outputPath, logLevel: logLevel$1, hooks, makeSink, onStart, onEnd }) {
|
|
1535
1468
|
await onStart();
|
|
1536
1469
|
let resolvedTool = toolValue;
|
|
1537
1470
|
if (resolvedTool === "auto") {
|
|
@@ -1543,43 +1476,47 @@ async function runToolPass({ toolValue, detect, toolMap, toolLabel, successPrefi
|
|
|
1543
1476
|
}
|
|
1544
1477
|
}
|
|
1545
1478
|
let toolError;
|
|
1546
|
-
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap) {
|
|
1479
|
+
if (resolvedTool && resolvedTool !== "auto" && resolvedTool in toolMap && existsSync(outputPath)) {
|
|
1547
1480
|
const toolConfig = toolMap[resolvedTool];
|
|
1481
|
+
const hookId = createHash("sha256").update([configName, resolvedTool].filter(Boolean).join("-")).digest("hex");
|
|
1482
|
+
const successMessage = [
|
|
1483
|
+
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1484
|
+
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1485
|
+
"successfully"
|
|
1486
|
+
].filter(Boolean).join(" ");
|
|
1548
1487
|
try {
|
|
1549
|
-
const
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1552
|
-
if (ctx.id !== hookId) return;
|
|
1553
|
-
hooks.off("kubb:hook:end", handler);
|
|
1554
|
-
if (!ctx.success) {
|
|
1555
|
-
reject(ctx.error ?? /* @__PURE__ */ new Error(`${toolConfig.errorMessage}`));
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
hooks.emit("kubb:success", { message: [
|
|
1559
|
-
`${successPrefix} with ${styleText("dim", resolvedTool)}`,
|
|
1560
|
-
logLevel$1 >= logLevel.info ? `on ${styleText("dim", outputPath)}` : void 0,
|
|
1561
|
-
"successfully"
|
|
1562
|
-
].filter(Boolean).join(" ") }).then(resolve).catch(reject);
|
|
1563
|
-
};
|
|
1564
|
-
hooks.on("kubb:hook:end", handler);
|
|
1565
|
-
});
|
|
1488
|
+
const hookArgs = toolConfig.args(outputPath);
|
|
1489
|
+
const commandWithArgs = [toolConfig.command, ...hookArgs].join(" ");
|
|
1490
|
+
const hookEndPromise = waitForHookEnd(hooks, hookId, () => hooks.emit("kubb:success", { message: successMessage }), toolConfig.errorMessage);
|
|
1566
1491
|
await hooks.emit("kubb:hook:start", {
|
|
1567
1492
|
id: hookId,
|
|
1568
1493
|
command: toolConfig.command,
|
|
1569
|
-
args:
|
|
1494
|
+
args: hookArgs
|
|
1570
1495
|
});
|
|
1496
|
+
const { stream = false, onLine, onStdout, onStderr } = makeSink?.(commandWithArgs, hookId) ?? {};
|
|
1497
|
+
runHook({
|
|
1498
|
+
id: hookId,
|
|
1499
|
+
command: toolConfig.command,
|
|
1500
|
+
args: hookArgs,
|
|
1501
|
+
commandWithArgs,
|
|
1502
|
+
hooks,
|
|
1503
|
+
stream,
|
|
1504
|
+
sink: {
|
|
1505
|
+
onLine,
|
|
1506
|
+
onStdout,
|
|
1507
|
+
onStderr
|
|
1508
|
+
}
|
|
1509
|
+
}).catch(() => {});
|
|
1571
1510
|
await hookEndPromise;
|
|
1572
1511
|
} catch (caughtError) {
|
|
1573
|
-
|
|
1574
|
-
await hooks.emit("kubb:error", { error: err });
|
|
1575
|
-
toolError = err;
|
|
1512
|
+
toolError = toError(caughtError);
|
|
1576
1513
|
}
|
|
1577
1514
|
}
|
|
1578
1515
|
await onEnd();
|
|
1579
1516
|
if (toolError) throw toolError;
|
|
1580
1517
|
}
|
|
1581
1518
|
async function generate(options) {
|
|
1582
|
-
const { input, hooks, logLevel
|
|
1519
|
+
const { input, hooks, logLevel, makeSink } = options;
|
|
1583
1520
|
const hrStart = process$1.hrtime();
|
|
1584
1521
|
const inputPath = input ?? (options.config.input && "path" in options.config.input ? options.config.input.path : void 0);
|
|
1585
1522
|
const config = {
|
|
@@ -1591,163 +1528,230 @@ async function generate(options) {
|
|
|
1591
1528
|
...options.config.output
|
|
1592
1529
|
};
|
|
1593
1530
|
const kubb = createKubb(config, { hooks });
|
|
1594
|
-
await kubb.setup();
|
|
1595
1531
|
await hooks.emit("kubb:generation:start", { config });
|
|
1596
1532
|
await hooks.emit("kubb:info", {
|
|
1597
1533
|
message: config.name ? `Setup generation ${styleText("bold", config.name)}` : "Setup generation",
|
|
1598
1534
|
info: inputPath
|
|
1599
1535
|
});
|
|
1536
|
+
await kubb.setup();
|
|
1600
1537
|
await hooks.emit("kubb:info", {
|
|
1601
1538
|
message: config.name ? `Build generation ${styleText("bold", config.name)}` : "Build generation",
|
|
1602
1539
|
info: inputPath
|
|
1603
1540
|
});
|
|
1604
|
-
const { files,
|
|
1541
|
+
const { files, diagnostics, driver } = await kubb.safeBuild();
|
|
1605
1542
|
await hooks.emit("kubb:info", { message: "Load summary" });
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1543
|
+
const telemetryPlugins = Array.from(driver.plugins.values(), (p) => ({
|
|
1544
|
+
name: p.name,
|
|
1545
|
+
options: p.options
|
|
1546
|
+
}));
|
|
1547
|
+
const reportTelemetry = (status) => Telemetry.send(Telemetry.build({
|
|
1548
|
+
command: "generate",
|
|
1549
|
+
kubbVersion: version,
|
|
1550
|
+
plugins: telemetryPlugins,
|
|
1551
|
+
hrStart,
|
|
1552
|
+
filesCreated: files.length,
|
|
1553
|
+
status
|
|
1554
|
+
}));
|
|
1555
|
+
for (const diagnostic of diagnostics) {
|
|
1556
|
+
if (!Diagnostics.isProblem(diagnostic)) continue;
|
|
1557
|
+
const unknown = Diagnostics.narrow(diagnostic, Diagnostics.code.unknown);
|
|
1558
|
+
if (unknown) await hooks.emit("kubb:error", { error: unknown.cause ?? new Error(unknown.message) });
|
|
1559
|
+
else await Diagnostics.emit(hooks, diagnostic);
|
|
1560
|
+
}
|
|
1561
|
+
if (Diagnostics.hasError(diagnostics)) {
|
|
1609
1562
|
await hooks.emit("kubb:generation:end", {
|
|
1610
1563
|
config,
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
});
|
|
1614
|
-
await hooks.emit("kubb:generation:summary", {
|
|
1615
|
-
config,
|
|
1616
|
-
failedPlugins,
|
|
1564
|
+
storage: kubb.storage,
|
|
1565
|
+
diagnostics,
|
|
1617
1566
|
filesCreated: files.length,
|
|
1618
1567
|
status: "failed",
|
|
1619
|
-
hrStart
|
|
1620
|
-
pluginTimings: logLevel$2 >= logLevel.verbose ? pluginTimings : void 0
|
|
1568
|
+
hrStart
|
|
1621
1569
|
});
|
|
1622
|
-
await
|
|
1623
|
-
|
|
1624
|
-
kubbVersion: version,
|
|
1625
|
-
plugins: Array.from(driver.plugins.values(), (p) => ({
|
|
1626
|
-
name: p.name,
|
|
1627
|
-
options: p.options
|
|
1628
|
-
})),
|
|
1629
|
-
hrStart,
|
|
1630
|
-
filesCreated: files.length,
|
|
1631
|
-
status: "failed"
|
|
1632
|
-
}));
|
|
1633
|
-
process$1.exit(1);
|
|
1570
|
+
await reportTelemetry("failed");
|
|
1571
|
+
return false;
|
|
1634
1572
|
}
|
|
1635
|
-
await hooks.emit("kubb:success", {
|
|
1636
|
-
message: "Generation successfully",
|
|
1637
|
-
info: inputPath
|
|
1638
|
-
});
|
|
1639
|
-
await hooks.emit("kubb:generation:end", {
|
|
1640
|
-
config,
|
|
1641
|
-
files,
|
|
1642
|
-
sources: kubb.sources
|
|
1643
|
-
});
|
|
1644
1573
|
const outputPath = path.resolve(config.root, config.output.path);
|
|
1645
|
-
|
|
1574
|
+
const outputDiagnostics = [];
|
|
1575
|
+
const toolPasses = [config.output.format && {
|
|
1576
|
+
code: Diagnostics.code.formatFailed,
|
|
1646
1577
|
toolValue: config.output.format,
|
|
1647
1578
|
detect: detectFormatter,
|
|
1648
1579
|
toolMap: formatters,
|
|
1649
1580
|
toolLabel: "formatter",
|
|
1650
1581
|
successPrefix: "Formatting",
|
|
1651
1582
|
noToolMessage: "No formatter found (oxfmt, biome, or prettier). Skipping formatting.",
|
|
1652
|
-
configName: config.name,
|
|
1653
|
-
outputPath,
|
|
1654
|
-
logLevel: logLevel$2,
|
|
1655
|
-
hooks,
|
|
1656
1583
|
onStart: () => hooks.emit("kubb:format:start"),
|
|
1657
1584
|
onEnd: () => hooks.emit("kubb:format:end")
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1585
|
+
}, config.output.lint && {
|
|
1586
|
+
code: Diagnostics.code.lintFailed,
|
|
1660
1587
|
toolValue: config.output.lint,
|
|
1661
1588
|
detect: detectLinter,
|
|
1662
1589
|
toolMap: linters,
|
|
1663
1590
|
toolLabel: "linter",
|
|
1664
1591
|
successPrefix: "Linting",
|
|
1665
1592
|
noToolMessage: "No linter found (oxlint, biome, or eslint). Skipping linting.",
|
|
1666
|
-
configName: config.name,
|
|
1667
|
-
outputPath,
|
|
1668
|
-
logLevel: logLevel$2,
|
|
1669
|
-
hooks,
|
|
1670
1593
|
onStart: () => hooks.emit("kubb:lint:start"),
|
|
1671
1594
|
onEnd: () => hooks.emit("kubb:lint:end")
|
|
1672
|
-
});
|
|
1595
|
+
}].filter(Boolean);
|
|
1596
|
+
for (const { code, ...pass } of toolPasses) try {
|
|
1597
|
+
await runToolPass({
|
|
1598
|
+
...pass,
|
|
1599
|
+
configName: config.name,
|
|
1600
|
+
outputPath,
|
|
1601
|
+
logLevel,
|
|
1602
|
+
hooks,
|
|
1603
|
+
makeSink
|
|
1604
|
+
});
|
|
1605
|
+
} catch (caughtError) {
|
|
1606
|
+
const diagnostic = outputDiagnostic(code, pass.toolLabel, caughtError);
|
|
1607
|
+
outputDiagnostics.push(diagnostic);
|
|
1608
|
+
await Diagnostics.emit(hooks, diagnostic);
|
|
1609
|
+
}
|
|
1673
1610
|
if (config.hooks) {
|
|
1674
1611
|
await hooks.emit("kubb:hooks:start");
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1612
|
+
const hookFailures = [];
|
|
1613
|
+
const onHookEnd = (ctx) => {
|
|
1614
|
+
if (!ctx.success) hookFailures.push(ctx.error ?? /* @__PURE__ */ new Error("Post-generate hook failed"));
|
|
1615
|
+
};
|
|
1616
|
+
hooks.on("kubb:hook:end", onHookEnd);
|
|
1617
|
+
try {
|
|
1618
|
+
await executeHooks({
|
|
1619
|
+
configHooks: config.hooks,
|
|
1620
|
+
hooks,
|
|
1621
|
+
makeSink
|
|
1622
|
+
});
|
|
1623
|
+
} finally {
|
|
1624
|
+
hooks.off("kubb:hook:end", onHookEnd);
|
|
1625
|
+
}
|
|
1626
|
+
for (const error of hookFailures) {
|
|
1627
|
+
const diagnostic = outputDiagnostic(Diagnostics.code.hookFailed, "Post-generate hook", error);
|
|
1628
|
+
outputDiagnostics.push(diagnostic);
|
|
1629
|
+
await Diagnostics.emit(hooks, diagnostic);
|
|
1630
|
+
}
|
|
1679
1631
|
await hooks.emit("kubb:hooks:end");
|
|
1680
1632
|
}
|
|
1681
|
-
|
|
1633
|
+
const finalDiagnostics = [...diagnostics, ...outputDiagnostics];
|
|
1634
|
+
const failed = Diagnostics.hasError(outputDiagnostics);
|
|
1635
|
+
if (!failed) await hooks.emit("kubb:success", {
|
|
1636
|
+
message: "Generation succeeded",
|
|
1637
|
+
info: inputPath
|
|
1638
|
+
});
|
|
1639
|
+
await hooks.emit("kubb:generation:end", {
|
|
1682
1640
|
config,
|
|
1683
|
-
|
|
1641
|
+
storage: kubb.storage,
|
|
1642
|
+
diagnostics: finalDiagnostics,
|
|
1684
1643
|
filesCreated: files.length,
|
|
1685
|
-
status: "success",
|
|
1686
|
-
hrStart
|
|
1687
|
-
pluginTimings
|
|
1644
|
+
status: failed ? "failed" : "success",
|
|
1645
|
+
hrStart
|
|
1688
1646
|
});
|
|
1689
|
-
await
|
|
1690
|
-
|
|
1691
|
-
kubbVersion: version,
|
|
1692
|
-
plugins: Array.from(driver.plugins.values(), (p) => ({
|
|
1693
|
-
name: p.name,
|
|
1694
|
-
options: p.options
|
|
1695
|
-
})),
|
|
1696
|
-
hrStart,
|
|
1697
|
-
filesCreated: files.length,
|
|
1698
|
-
status: "success"
|
|
1699
|
-
}));
|
|
1647
|
+
await reportTelemetry(failed ? "failed" : "success");
|
|
1648
|
+
return !failed;
|
|
1700
1649
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1650
|
+
/**
|
|
1651
|
+
* Builds a coded diagnostic for an output-phase failure (formatter, linter, or `done` hook).
|
|
1652
|
+
*/
|
|
1653
|
+
function outputDiagnostic(code, label, caughtError) {
|
|
1654
|
+
const error = toError(caughtError);
|
|
1655
|
+
return {
|
|
1656
|
+
code,
|
|
1657
|
+
severity: "error",
|
|
1658
|
+
message: `${label} failed: ${error.message}`,
|
|
1659
|
+
help: "Check that the tool is installed and that the command and its config are correct.",
|
|
1660
|
+
location: { kind: "config" },
|
|
1661
|
+
cause: error
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
async function checkForUpdate(hooks) {
|
|
1705
1665
|
await executeIfOnline(async () => {
|
|
1706
1666
|
try {
|
|
1707
|
-
const
|
|
1708
|
-
if (
|
|
1667
|
+
const data = await (await fetch(KUBB_NPM_PACKAGE_URL)).json();
|
|
1668
|
+
if (data.version && version < data.version) await Diagnostics.emit(hooks, Diagnostics.update({
|
|
1709
1669
|
currentVersion: version,
|
|
1710
|
-
latestVersion
|
|
1711
|
-
});
|
|
1670
|
+
latestVersion: data.version
|
|
1671
|
+
}));
|
|
1712
1672
|
} catch {}
|
|
1713
1673
|
});
|
|
1674
|
+
}
|
|
1675
|
+
/**
|
|
1676
|
+
* Runs the full Kubb generation lifecycle for the given CLI options.
|
|
1677
|
+
* Loads configs, sets up the selected reporters (CLI `--reporter` overrides `config.reporters`),
|
|
1678
|
+
* checks for a newer version, and calls `generate` for each config entry.
|
|
1679
|
+
*/
|
|
1680
|
+
async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters }) {
|
|
1681
|
+
const logLevel$2 = logLevel[logLevelKey] ?? logLevel.info;
|
|
1682
|
+
const hooks = new AsyncEventEmitter();
|
|
1683
|
+
let configs;
|
|
1684
|
+
let resolvedConfigPath;
|
|
1685
|
+
try {
|
|
1686
|
+
const loaded = await getConfigs({
|
|
1687
|
+
configPath,
|
|
1688
|
+
input,
|
|
1689
|
+
watch,
|
|
1690
|
+
logLevel: logLevelKey
|
|
1691
|
+
});
|
|
1692
|
+
configs = loaded.configs;
|
|
1693
|
+
resolvedConfigPath = loaded.configPath;
|
|
1694
|
+
} catch (error) {
|
|
1695
|
+
await setupReporters(hooks, {
|
|
1696
|
+
logLevel: logLevel$2,
|
|
1697
|
+
reporters: [cliReporter]
|
|
1698
|
+
});
|
|
1699
|
+
await hooks.emit("kubb:error", { error: toError(error) });
|
|
1700
|
+
process$1.exit(1);
|
|
1701
|
+
}
|
|
1702
|
+
const requestedNames = cliReporters?.length ? cliReporters : ["cli"];
|
|
1703
|
+
const makeSink = await setupReporters(hooks, {
|
|
1704
|
+
logLevel: logLevel$2,
|
|
1705
|
+
reporters: selectReporters(configs[0]?.reporters ?? [], requestedNames)
|
|
1706
|
+
});
|
|
1707
|
+
await hooks.emit("kubb:lifecycle:start", { version });
|
|
1708
|
+
await checkForUpdate(hooks);
|
|
1714
1709
|
try {
|
|
1715
|
-
const
|
|
1716
|
-
const configs = await getConfigs(result.config, { input });
|
|
1710
|
+
const relativeConfigPath = path.relative(process$1.cwd(), resolvedConfigPath);
|
|
1717
1711
|
await hooks.emit("kubb:config:start");
|
|
1718
1712
|
await hooks.emit("kubb:info", {
|
|
1719
1713
|
message: "Config loaded",
|
|
1720
|
-
info:
|
|
1714
|
+
info: relativeConfigPath
|
|
1721
1715
|
});
|
|
1722
1716
|
await hooks.emit("kubb:success", {
|
|
1723
1717
|
message: "Config loaded successfully",
|
|
1724
|
-
info:
|
|
1718
|
+
info: relativeConfigPath
|
|
1725
1719
|
});
|
|
1726
1720
|
await hooks.emit("kubb:config:end", { configs });
|
|
1727
|
-
|
|
1728
|
-
for (const config of configs) if (
|
|
1729
|
-
hooks.removeAll();
|
|
1721
|
+
let anyFailed = false;
|
|
1722
|
+
for (const config of configs) if (config.input && "path" in config.input && watch) await startWatcher([input || config.input.path], async (paths) => {
|
|
1730
1723
|
await generate({
|
|
1731
1724
|
input,
|
|
1732
1725
|
config,
|
|
1733
|
-
logLevel: logLevel$
|
|
1734
|
-
hooks
|
|
1726
|
+
logLevel: logLevel$2,
|
|
1727
|
+
hooks,
|
|
1728
|
+
makeSink
|
|
1735
1729
|
});
|
|
1736
1730
|
clack.log.step(styleText("yellow", `Watching for changes in ${paths.join(" and ")}`));
|
|
1731
|
+
}, {
|
|
1732
|
+
info: (msg) => clack.log.info(msg),
|
|
1733
|
+
error: (msg) => clack.log.error(msg)
|
|
1737
1734
|
});
|
|
1738
|
-
else
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1735
|
+
else try {
|
|
1736
|
+
if (!await generate({
|
|
1737
|
+
input,
|
|
1738
|
+
config,
|
|
1739
|
+
logLevel: logLevel$2,
|
|
1740
|
+
hooks,
|
|
1741
|
+
makeSink
|
|
1742
|
+
})) anyFailed = true;
|
|
1743
|
+
} catch (configError) {
|
|
1744
|
+
await hooks.emit("kubb:error", { error: toError(configError) });
|
|
1745
|
+
anyFailed = true;
|
|
1746
|
+
}
|
|
1744
1747
|
await hooks.emit("kubb:lifecycle:end");
|
|
1748
|
+
if (anyFailed) process$1.exit(1);
|
|
1745
1749
|
} catch (error) {
|
|
1746
1750
|
await hooks.emit("kubb:error", { error: toError(error) });
|
|
1747
1751
|
process$1.exit(1);
|
|
1748
1752
|
}
|
|
1749
1753
|
}
|
|
1750
1754
|
//#endregion
|
|
1751
|
-
export {
|
|
1755
|
+
export { run };
|
|
1752
1756
|
|
|
1753
|
-
//# sourceMappingURL=
|
|
1757
|
+
//# sourceMappingURL=run-CHZKHTv0.js.map
|