@kubb/cli 5.10.1 → 5.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Telemetry-BfdvvZus.cjs → Telemetry-BV4GonCV.cjs} +2 -2
- package/dist/Telemetry-BV4GonCV.cjs.map +1 -0
- package/dist/Telemetry-CH2kkxWK.cjs +322 -0
- package/dist/Telemetry-CH2kkxWK.cjs.map +1 -0
- package/dist/{Telemetry-Bf6lUdai.js → Telemetry-Cz9QCzRo.js} +2 -2
- package/dist/Telemetry-Cz9QCzRo.js.map +1 -0
- package/dist/{background-D5K6ecEo.js → background-DFME5huR.js} +30 -7
- package/dist/background-DFME5huR.js.map +1 -0
- package/dist/{background-obsD4Gj2.cjs → background-DVZB1n4j.cjs} +25 -6
- package/dist/background-DVZB1n4j.cjs.map +1 -0
- package/dist/background-WaKtfQWr.cjs +192 -0
- package/dist/background-WaKtfQWr.cjs.map +1 -0
- package/dist/{background-C8doa9-4.js → background-_A5NwvYH.js} +1 -1
- package/dist/{config-CcqzzfB7.cjs → config-DKAqX5sW.cjs} +18 -4
- package/dist/config-DKAqX5sW.cjs.map +1 -0
- package/dist/{config-IMZ26zcb.js → config-DV_7s1m-.js} +19 -5
- package/dist/config-DV_7s1m-.js.map +1 -0
- package/dist/config-OL_izsmp.cjs +113 -0
- package/dist/config-OL_izsmp.cjs.map +1 -0
- package/dist/credentials-xOkTTDWj.cjs +113 -0
- package/dist/credentials-xOkTTDWj.cjs.map +1 -0
- package/dist/index.cjs +65 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +65 -24
- package/dist/index.js.map +1 -1
- package/dist/output-C5g7AtWH.cjs +1008 -0
- package/dist/output-C5g7AtWH.cjs.map +1 -0
- package/dist/{output-mwVt_Vj9.js → output-D_gc1nrM.js} +99 -44
- package/dist/output-D_gc1nrM.js.map +1 -0
- package/dist/{output-DLrxGtuN.cjs → output-nieBFDgM.cjs} +104 -43
- package/dist/output-nieBFDgM.cjs.map +1 -0
- package/dist/{registry-x-_nbYR6.cjs → registry-C8E_G7Xc.cjs} +49 -15
- package/dist/registry-C8E_G7Xc.cjs.map +1 -0
- package/dist/registry-CIpW2zQc.cjs +157 -0
- package/dist/registry-CIpW2zQc.cjs.map +1 -0
- package/dist/{registry-ChqX2AFQ.js → registry-De1vVn1d.js} +50 -16
- package/dist/registry-De1vVn1d.js.map +1 -0
- package/dist/rolldown-runtime-C0BPl7ul.cjs +43 -0
- package/dist/run-BbhrOuK6.cjs +40 -0
- package/dist/{run-1MJA0P5x.cjs.map → run-BbhrOuK6.cjs.map} +1 -1
- package/dist/{run-DHiVlG37.cjs → run-BnLba1gt.cjs} +27 -14
- package/dist/run-BnLba1gt.cjs.map +1 -0
- package/dist/{run-D4vOhfbJ.js → run-Bp47k1W1.js} +2 -2
- package/dist/{run-D4vOhfbJ.js.map → run-Bp47k1W1.js.map} +1 -1
- package/dist/run-BpdJ6X75.cjs +32 -0
- package/dist/{run-B13e9GQz.cjs.map → run-BpdJ6X75.cjs.map} +1 -1
- package/dist/{run-Cm0sJO0h.js → run-CCMlmk-z.js} +1 -1
- package/dist/{run-DTz7gAk1.js → run-CPYD1Lp0.js} +27 -14
- package/dist/run-CPYD1Lp0.js.map +1 -0
- package/dist/run-CSOEGpWZ.cjs +326 -0
- package/dist/run-CSOEGpWZ.cjs.map +1 -0
- package/dist/{run-B13e9GQz.cjs → run-CvE8ZdKG.cjs} +2 -2
- package/dist/run-CvE8ZdKG.cjs.map +1 -0
- package/dist/{run-Cu3pmezx.js → run-DaFK-Uy2.js} +2 -2
- package/dist/{run-Cu3pmezx.js.map → run-DaFK-Uy2.js.map} +1 -1
- package/dist/{run-BAlcXyYw.js → run-Ij84bqza.js} +22 -16
- package/dist/run-Ij84bqza.js.map +1 -0
- package/dist/{run-1MJA0P5x.cjs → run-MFjzBB_M.cjs} +2 -2
- package/dist/run-MFjzBB_M.cjs.map +1 -0
- package/dist/run-hgSZImuK.cjs +345 -0
- package/dist/run-hgSZImuK.cjs.map +1 -0
- package/dist/{run-CUyhuGlK.cjs → run-hyi91b22.cjs} +22 -16
- package/dist/run-hyi91b22.cjs.map +1 -0
- package/dist/{snapshot-DCG-Jf1A.js → snapshot-B6w3BLum.js} +22 -9
- package/dist/snapshot-B6w3BLum.js.map +1 -0
- package/dist/snapshot-DP9Pcnsg.cjs +264 -0
- package/dist/snapshot-DP9Pcnsg.cjs.map +1 -0
- package/dist/{snapshot-C5cthCuU.cjs → snapshot-D_F4XkYQ.cjs} +22 -9
- package/dist/snapshot-D_F4XkYQ.cjs.map +1 -0
- package/dist/studioWorker.js +2 -2
- package/package.json +15 -10
- package/dist/Telemetry-Bf6lUdai.js.map +0 -1
- package/dist/Telemetry-BfdvvZus.cjs.map +0 -1
- package/dist/background-D5K6ecEo.js.map +0 -1
- package/dist/background-obsD4Gj2.cjs.map +0 -1
- package/dist/config-CcqzzfB7.cjs.map +0 -1
- package/dist/config-IMZ26zcb.js.map +0 -1
- package/dist/output-DLrxGtuN.cjs.map +0 -1
- package/dist/output-mwVt_Vj9.js.map +0 -1
- package/dist/registry-ChqX2AFQ.js.map +0 -1
- package/dist/registry-x-_nbYR6.cjs.map +0 -1
- package/dist/run-BAlcXyYw.js.map +0 -1
- package/dist/run-CUyhuGlK.cjs.map +0 -1
- package/dist/run-DHiVlG37.cjs.map +0 -1
- package/dist/run-DTz7gAk1.js.map +0 -1
- package/dist/snapshot-C5cthCuU.cjs.map +0 -1
- package/dist/snapshot-DCG-Jf1A.js.map +0 -1
- package/dist/studioWorker.d.ts +0 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
|
-
const require_Telemetry = require("./Telemetry-
|
|
2
|
+
const require_Telemetry = require("./Telemetry-BV4GonCV.cjs");
|
|
3
3
|
let node_util = require("node:util");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
6
6
|
let node_fs_promises = require("node:fs/promises");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
let gunshi_agent = require("gunshi/agent");
|
|
9
|
+
let _kubb_core = require("@kubb/core");
|
|
9
10
|
let _clack_prompts = require("@clack/prompts");
|
|
10
11
|
_clack_prompts = require_rolldown_runtime.__toESM(_clack_prompts, 1);
|
|
11
12
|
let node_fs = require("node:fs");
|
|
12
13
|
let jiti = require("jiti");
|
|
13
|
-
let _kubb_core = require("@kubb/core");
|
|
14
14
|
//#region ../../internals/shared/src/constants.ts
|
|
15
15
|
const KUBB_CONFIG_FILENAME = "kubb.config.ts";
|
|
16
16
|
/** File extensions a Kubb config file may use. */
|
|
@@ -225,24 +225,6 @@ function formatVersions({ studio, kubb, agent }) {
|
|
|
225
225
|
`Studio v${studio}`
|
|
226
226
|
].filter(Boolean).join(", ");
|
|
227
227
|
}
|
|
228
|
-
/** The first three frames of a stack, without the message line. */
|
|
229
|
-
function topFrames(stack) {
|
|
230
|
-
return stack.split("\n").slice(1, 4).map((frame) => frame.trim());
|
|
231
|
-
}
|
|
232
|
-
/** First stack frames for verbose error output, including an optional `cause` chain. */
|
|
233
|
-
function formatErrorFrames(error) {
|
|
234
|
-
if (!error.stack) return null;
|
|
235
|
-
const frames = topFrames(error.stack);
|
|
236
|
-
const caused = error.cause instanceof Error ? error.cause : void 0;
|
|
237
|
-
if (!caused?.stack) return { frames };
|
|
238
|
-
return {
|
|
239
|
-
frames,
|
|
240
|
-
cause: {
|
|
241
|
-
header: `└─ caused by ${caused.message}`,
|
|
242
|
-
frames: topFrames(caused.stack)
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
228
|
/** The progress summary line the clack logger shows, `null` when there is nothing to display. */
|
|
247
229
|
function buildProgressLine(state) {
|
|
248
230
|
const parts = [];
|
|
@@ -304,12 +286,18 @@ function trimBlankEdges(lines) {
|
|
|
304
286
|
*
|
|
305
287
|
* @example
|
|
306
288
|
* ```ts
|
|
307
|
-
* export const plainLogger = createLogger(writer)
|
|
289
|
+
* export const plainLogger = createLogger(writer, { audience: 'agent' })
|
|
308
290
|
* ```
|
|
309
291
|
*/
|
|
310
|
-
function createLogger(writer) {
|
|
292
|
+
function createLogger(writer, { audience }) {
|
|
311
293
|
return function install(context, { logLevel }) {
|
|
312
294
|
const silent = logLevel <= _kubb_core.logLevel.silent;
|
|
295
|
+
const human = audience === "human";
|
|
296
|
+
const formatOptions = {
|
|
297
|
+
audience,
|
|
298
|
+
verbose: logLevel >= _kubb_core.logLevel.verbose,
|
|
299
|
+
width: Math.min(node_process.default.stdout.columns || 80, 100) - 2
|
|
300
|
+
};
|
|
313
301
|
const state = {
|
|
314
302
|
...createProgressCounters(),
|
|
315
303
|
spinner: null,
|
|
@@ -324,7 +312,15 @@ function createLogger(writer) {
|
|
|
324
312
|
/**
|
|
325
313
|
* Whether this run keeps its files in memory, as a `kubb studio` run without `--allow-write` does.
|
|
326
314
|
*/
|
|
327
|
-
inMemory: false
|
|
315
|
+
inMemory: false,
|
|
316
|
+
/**
|
|
317
|
+
* Problems held back so the human view can print them grouped by plugin once the build ends.
|
|
318
|
+
*/
|
|
319
|
+
problems: [],
|
|
320
|
+
/**
|
|
321
|
+
* The finished config's diagnostics and file count, for the closing summary.
|
|
322
|
+
*/
|
|
323
|
+
outcome: null
|
|
328
324
|
};
|
|
329
325
|
function text(message) {
|
|
330
326
|
return formatMessage(message, logLevel);
|
|
@@ -379,12 +375,20 @@ function createLogger(writer) {
|
|
|
379
375
|
const output = trimBlankEdges(lines);
|
|
380
376
|
if (output.length) writer.raw(output);
|
|
381
377
|
}
|
|
378
|
+
/** `✖ Failed 1 error · 1 warning in plugin-ts` once the build ended, or `✗ Generation failed` for a run that stopped early. */
|
|
379
|
+
function failedTitle() {
|
|
380
|
+
const diagnostics = state.outcome?.diagnostics ?? [];
|
|
381
|
+
const counts = formatCounts(diagnostics);
|
|
382
|
+
if (!human || !counts) return "✗ Generation failed";
|
|
383
|
+
const plugins = _kubb_core.Diagnostics.failedPlugins(diagnostics);
|
|
384
|
+
return `✖ Failed ${counts}${plugins.length ? ` in ${plugins.join(", ")}` : ""}`;
|
|
385
|
+
}
|
|
382
386
|
function closeGroup(status) {
|
|
383
387
|
if (!state.groupOpen) return;
|
|
384
388
|
state.groupOpen = false;
|
|
385
389
|
stopSpinner();
|
|
386
390
|
stopProgress();
|
|
387
|
-
writer.groupEnd(status === "failed" ? (0, node_util.styleText)("red",
|
|
391
|
+
writer.groupEnd(status === "failed" ? (0, node_util.styleText)("red", failedTitle()) : (0, node_util.styleText)("green", "✓ Generation succeeded"));
|
|
388
392
|
}
|
|
389
393
|
function reset() {
|
|
390
394
|
stopSpinner();
|
|
@@ -394,12 +398,25 @@ function createLogger(writer) {
|
|
|
394
398
|
state.pluginLines = [];
|
|
395
399
|
state.phase = null;
|
|
396
400
|
state.groupOpen = false;
|
|
401
|
+
state.problems = [];
|
|
402
|
+
state.outcome = null;
|
|
397
403
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if (
|
|
404
|
+
/**
|
|
405
|
+
* Prints problems grouped under their plugin's name, each with the code aligned at the right.
|
|
406
|
+
*/
|
|
407
|
+
function writeProblems(problems) {
|
|
408
|
+
if (!problems.length) return;
|
|
409
|
+
if (!human) {
|
|
410
|
+
for (const problem of problems) writer.diagnostic(_kubb_core.Diagnostics.format(problem, formatOptions));
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const lines = [...Map.groupBy(problems, (problem) => problem.plugin ?? "")].flatMap(([plugin, group]) => [...plugin ? [` ${(0, node_util.styleText)("bold", plugin)}`, ""] : [], ...group.flatMap((problem) => [..._kubb_core.Diagnostics.format(problem, formatOptions).map((line) => ` ${line}`), ""])]);
|
|
414
|
+
writer.diagnostic(lines.slice(0, -1));
|
|
415
|
+
}
|
|
416
|
+
/** The run's verdict: `1 error · 1 warning` for a human, `1 error, 1 warning` for an agent. */
|
|
417
|
+
function formatCounts(diagnostics) {
|
|
418
|
+
const { errors, warnings } = _kubb_core.Diagnostics.count(diagnostics);
|
|
419
|
+
return [errors && pluralize(errors, "error"), warnings && pluralize(warnings, "warning")].filter(Boolean).join(human ? " · " : ", ");
|
|
403
420
|
}
|
|
404
421
|
function formatLine(symbol, message, info) {
|
|
405
422
|
return text([
|
|
@@ -414,9 +431,24 @@ function createLogger(writer) {
|
|
|
414
431
|
});
|
|
415
432
|
context.hook("kubb:error", ({ error }) => {
|
|
416
433
|
if (state.phase) state.phase.failed = true;
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
434
|
+
const message = error.name === "Error" || _kubb_core.Diagnostics.isError(error) ? error.message : `${error.name}: ${error.message}`;
|
|
435
|
+
const help = _kubb_core.Diagnostics.isError(error) ? error.diagnostic.help : void 0;
|
|
436
|
+
const [headline = "", ...details] = _kubb_core.Diagnostics.format({
|
|
437
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
438
|
+
severity: "error",
|
|
439
|
+
message,
|
|
440
|
+
help,
|
|
441
|
+
cause: error
|
|
442
|
+
}, formatOptions);
|
|
443
|
+
if (!human) {
|
|
444
|
+
stopSpinner();
|
|
445
|
+
stopProgress();
|
|
446
|
+
writer.diagnostic([headline, ...details]);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (state.spinner) stopSpinner(message, "failed");
|
|
450
|
+
else writer.error(text(message));
|
|
451
|
+
if (details.length) writer.block(details.map(text));
|
|
420
452
|
});
|
|
421
453
|
context.hook("kubb:diagnostic", ({ diagnostic }) => {
|
|
422
454
|
if (silent && diagnostic.severity !== "error") return;
|
|
@@ -426,9 +458,11 @@ function createLogger(writer) {
|
|
|
426
458
|
writer.update([`\`v${diagnostic.currentVersion}\` → \`v${diagnostic.latestVersion}\``, "Run `npm install -g @kubb/cli` to update"], "Update available for `Kubb`");
|
|
427
459
|
return;
|
|
428
460
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
461
|
+
if (human && state.groupOpen) {
|
|
462
|
+
state.problems.push(diagnostic);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
writeProblems([diagnostic]);
|
|
432
466
|
});
|
|
433
467
|
context.hook("studio:disconnected", ({ code, reason }) => {
|
|
434
468
|
if (logLevel < _kubb_core.logLevel.warn) return;
|
|
@@ -498,11 +532,18 @@ function createLogger(writer) {
|
|
|
498
532
|
writer.step(text(result));
|
|
499
533
|
writeOutput(active.lines);
|
|
500
534
|
});
|
|
501
|
-
context.hook("kubb:generation:end", () => {
|
|
535
|
+
context.hook("kubb:generation:end", ({ diagnostics = [], filesCreated = 0, hrStart = node_process.default.hrtime() }) => {
|
|
502
536
|
stopSpinner();
|
|
503
537
|
stopProgress();
|
|
538
|
+
state.outcome = {
|
|
539
|
+
diagnostics,
|
|
540
|
+
filesCreated,
|
|
541
|
+
hrStart
|
|
542
|
+
};
|
|
543
|
+
writeProblems(state.problems.splice(0));
|
|
504
544
|
});
|
|
505
545
|
context.hook("kubb:lifecycle:end", () => {
|
|
546
|
+
writeProblems(state.problems.splice(0));
|
|
506
547
|
closeGroup("failed");
|
|
507
548
|
reset();
|
|
508
549
|
});
|
|
@@ -551,7 +592,7 @@ function createLogger(writer) {
|
|
|
551
592
|
});
|
|
552
593
|
context.hook("kubb:plugins:end", () => {
|
|
553
594
|
const failed = state.failedPlugins > 0;
|
|
554
|
-
stopSpinner(buildProgressLine(state) ??
|
|
595
|
+
stopSpinner(buildProgressLine(state) ?? void 0, failed ? "failed" : "success");
|
|
555
596
|
if (state.pluginLines.length) {
|
|
556
597
|
writer.block(state.pluginLines);
|
|
557
598
|
state.pluginLines = [];
|
|
@@ -592,8 +633,22 @@ function createLogger(writer) {
|
|
|
592
633
|
}
|
|
593
634
|
return { renderSummary(lines, { status }) {
|
|
594
635
|
if (silent || !state.groupOpen) return;
|
|
595
|
-
|
|
596
|
-
|
|
636
|
+
if (human) {
|
|
637
|
+
closeGroup(status);
|
|
638
|
+
writer.diagnostic([...lines]);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
stopSpinner();
|
|
642
|
+
stopProgress();
|
|
643
|
+
state.groupOpen = false;
|
|
644
|
+
const { diagnostics = [], filesCreated = 0, hrStart = node_process.default.hrtime() } = state.outcome ?? {};
|
|
645
|
+
if (status === "failed") {
|
|
646
|
+
const plugins = _kubb_core.Diagnostics.failedPlugins(diagnostics);
|
|
647
|
+
writer.diagnostic([`Kubb failed: ${formatCounts(diagnostics) || "an error"}${plugins.length ? ` (${plugins.join(", ")})` : ""}. Exit code 1.`, "Rerun with --reporter json for machine-readable diagnostics."]);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
const warnings = formatCounts(diagnostics);
|
|
651
|
+
writer.diagnostic([`Kubb succeeded: ${pluralize(filesCreated, "file")} generated in ${require_Telemetry.formatMs(require_Telemetry.getElapsedMs(hrStart))}${warnings ? `, ${warnings}` : ""}.`]);
|
|
597
652
|
} };
|
|
598
653
|
};
|
|
599
654
|
}
|
|
@@ -641,7 +696,7 @@ const clackWriter = {
|
|
|
641
696
|
/**
|
|
642
697
|
* TTY logger for local development, with animated steps and progress bars.
|
|
643
698
|
*/
|
|
644
|
-
const clackLogger = createLogger(clackWriter);
|
|
699
|
+
const clackLogger = createLogger(clackWriter, { audience: "human" });
|
|
645
700
|
//#endregion
|
|
646
701
|
//#region src/loggers/plainLogger.ts
|
|
647
702
|
/**
|
|
@@ -683,7 +738,7 @@ function createWriter(write) {
|
|
|
683
738
|
}
|
|
684
739
|
/** The plain logger writing through `write`, e.g. `console.error` so stdout carries only JSON. */
|
|
685
740
|
function createPlainLogger(write) {
|
|
686
|
-
return createLogger(createWriter(write));
|
|
741
|
+
return createLogger(createWriter(write), { audience: "agent" });
|
|
687
742
|
}
|
|
688
743
|
/** Draws on the console, for non-TTY environments and for an AI coding agent reading the output. */
|
|
689
744
|
const plainWriter = createWriter((line) => console.log(line));
|
|
@@ -691,7 +746,7 @@ const plainWriter = createWriter((line) => console.log(line));
|
|
|
691
746
|
* Console adapter for non-TTY environments, and for an AI coding agent reading the output. Reports
|
|
692
747
|
* the same run in the same order as `clackLogger`, without the animation.
|
|
693
748
|
*/
|
|
694
|
-
const plainLogger = createLogger(plainWriter);
|
|
749
|
+
const plainLogger = createLogger(plainWriter, { audience: "agent" });
|
|
695
750
|
//#endregion
|
|
696
751
|
//#region src/loggers/output.ts
|
|
697
752
|
const SPONSOR_TIPS = [
|
|
@@ -811,6 +866,12 @@ function createSpinner() {
|
|
|
811
866
|
return writer().spinner();
|
|
812
867
|
}
|
|
813
868
|
//#endregion
|
|
869
|
+
Object.defineProperty(exports, "CONFIG_EXTENSIONS", {
|
|
870
|
+
enumerable: true,
|
|
871
|
+
get: function() {
|
|
872
|
+
return CONFIG_EXTENSIONS;
|
|
873
|
+
}
|
|
874
|
+
});
|
|
814
875
|
Object.defineProperty(exports, "KUBB_CONFIG_FILENAME", {
|
|
815
876
|
enumerable: true,
|
|
816
877
|
get: function() {
|
|
@@ -944,4 +1005,4 @@ Object.defineProperty(exports, "pluralize", {
|
|
|
944
1005
|
}
|
|
945
1006
|
});
|
|
946
1007
|
|
|
947
|
-
//# sourceMappingURL=output-
|
|
1008
|
+
//# sourceMappingURL=output-nieBFDgM.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-nieBFDgM.cjs","names":["jiti","createJiti","readFile","process","resolve","dirname","join","existsSync","isCIEnvironment","getAgentProfile","styleText","formatMs","logLevelMap","styleText","formatMs","getElapsedMs","process","Diagnostics","relative","clack","styleText","styleText"],"sources":["../../../internals/shared/src/constants.ts","../../../internals/shared/src/loader.ts","../../../internals/shared/src/config.ts","../src/utils/env.ts","../src/loggers/banner.ts","../src/loggers/createLogger.ts","../src/loggers/clackLogger.ts","../src/loggers/plainLogger.ts","../src/loggers/output.ts"],"sourcesContent":["export const KUBB_CONFIG_FILENAME = 'kubb.config.ts' as const\n\n/** File extensions a Kubb config file may use. */\nexport const CONFIG_EXTENSIONS = ['.ts', '.mts', '.cts', '.js', '.mjs', '.cjs'] as const\n\nexport const KUBB_PACKAGE_NAME = 'kubb' as const\n\nexport const initDefaults = {\n inputPath: './openapi.yaml',\n outputPath: './src/gen',\n plugins: ['plugin-ts'],\n} as const\n","import { readFile } from 'node:fs/promises'\nimport { createJiti } from 'jiti'\n\n/**\n * jiti options for loading Kubb config modules: the automatic JSX runtime pointed at\n * `@kubb/renderer-jsx`, and `moduleCache` off so a re-load re-evaluates the file.\n */\nconst JITI_OPTIONS = {\n jsx: { runtime: 'automatic', importSource: '@kubb/renderer-jsx' },\n moduleCache: false,\n} satisfies Parameters<typeof createJiti>[1]\n\n/**\n * Plain JavaScript files. jiti hands these to Node's native `import()`, whose module cache never\n * lets go of a file, so `moduleCache: false` alone would keep returning the first version of it.\n */\nconst JAVASCRIPT_EXTENSION = /\\.[cm]?jsx?$/\n\n/**\n * Per-call options for {@link loadModule}.\n */\ntype LoadModuleOptions = {\n /**\n * Return the module's default export instead of the full namespace.\n */\n default?: boolean\n}\n\nconst jiti = createJiti(import.meta.url, JITI_OPTIONS)\n\n/**\n * Loads a Kubb TypeScript or JavaScript config module via jiti.\n *\n * jiti transpiles TypeScript and the `@kubb/renderer-jsx` JSX runtime on the fly. Every load\n * re-evaluates the file, so a config edited on disk is picked up by the next load.\n *\n * @example\n * ```ts\n * const config = await loadModule('/abs/kubb.config.ts', { default: true })\n * ```\n */\nexport async function loadModule<T = unknown>(filePath: string, options?: LoadModuleOptions): Promise<T> {\n if (!JAVASCRIPT_EXTENSION.test(filePath)) {\n return (options?.default ? jiti.import(filePath, { default: true }) : jiti.import(filePath)) as Promise<T>\n }\n\n // Transpiled through jiti instead, so every load re-evaluates the file as it is on disk now.\n // A TypeScript file it imports reloads too. A plain JavaScript file it imports still goes\n // through Node's `import()` and stays cached until the process restarts.\n const mod = (await jiti.evalModule(await readFile(filePath, 'utf8'), { filename: filePath, async: true, forceTranspile: true })) as\n | { default?: unknown }\n | undefined\n return (options?.default ? (mod?.default ?? mod) : mod) as T\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport process from 'node:process'\nimport { CONFIG_EXTENSIONS } from './constants.ts'\nimport { loadModule } from './loader.ts'\n\nconst SEARCH_FILES = ['', '.config/', 'configs/'].flatMap((prefix) => [`${prefix}.kubbrc`, `${prefix}kubb.config`])\n\n/**\n * The first Kubb config file in `cwd` or the nearest parent folder that has one: `.kubbrc` before\n * `kubb.config`, the folder itself before its `.config/` and `configs/`, and {@link CONFIG_EXTENSIONS} in order.\n */\nexport function findConfigFile(cwd: string = process.cwd()): string | undefined {\n for (let dir = resolve(cwd); ; dir = dirname(dir)) {\n const found = SEARCH_FILES.flatMap((file) => CONFIG_EXTENSIONS.map((extension) => join(dir, `${file}${extension}`))).find((file) => existsSync(file))\n if (found || dirname(dir) === dir) return found\n }\n}\n\n/**\n * Loads a Kubb config module, calls it with `cli` when it exports a function, and returns its\n * configs as a list, so a single config and a `defineConfig([...])` array read the same.\n */\nexport async function loadConfigFile<T>(file: string, cli: unknown): Promise<Array<T>> {\n const loaded = await loadModule<unknown>(file, { default: true })\n const resolved = (await (typeof loaded === 'function' ? loaded(cli) : loaded)) as T | Array<T>\n return Array.isArray(resolved) ? resolved : [resolved]\n}\n","import { isCIEnvironment } from '@internals/utils'\nimport { getAgentProfile } from 'gunshi/agent'\n\n/**\n * Returns `true` when the process has an interactive TTY with a valid terminal\n * width and is not running in CI.\n *\n * Some IDE-embedded terminals report `isTTY = true` but set `columns` to `0`,\n * which breaks clack's box-drawing helpers (they call `String.prototype.repeat`\n * with a negative count and throw a `RangeError`). A positive column count is\n * required before the TTY counts as usable.\n *\n * @example\n * ```ts\n * if (canUseTTY()) {\n * renderProgressBar()\n * }\n * ```\n */\nexport function canUseTTY(): boolean {\n return process.stdout.isTTY && (process.stdout.columns ?? 0) > 0 && !isCIEnvironment()\n}\n\n/**\n * Returns `true` when output can carry spinners and clack's gutter: an interactive TTY that no AI\n * coding agent is reading. Cursor-movement escapes are hard for an agent to parse even over a\n * pseudo-TTY, so it gets the plain writer.\n */\nexport function isRichOutput(): boolean {\n return canUseTTY() && !getAgentProfile().isAgent\n}\n","import { styleText } from 'node:util'\nimport { formatMs } from '@internals/utils'\n\n/**\n * Colors for each part of the Kubb mascot illustration.\n */\nconst palette = {\n /**\n * Top cap of the skittle.\n */\n lid: (text: string) => styleText('red', text),\n /**\n * Wood body.\n */\n wood: (text: string) => styleText('yellow', text),\n /**\n * Base wood body.\n */\n woodBase: (text: string) => styleText(['dim', 'yellow'], text),\n /**\n * Eye whites.\n */\n eye: (text: string) => styleText('white', text),\n /**\n * Highlight accent.\n */\n highlight: (text: string) => styleText('gray', text),\n /**\n * Cheek blush.\n */\n blush: (text: string) => styleText('magenta', text),\n}\n\n/**\n * Generates the Kubb mascot welcome banner as an ANSI-colored string.\n *\n * @example\n * ```ts\n * console.log(getIntro({ title: 'kubb.config.ts', description: 'generating…', version: '5.0.0', areEyesOpen: true }))\n * ```\n */\nexport function getIntro({\n title,\n description,\n version,\n areEyesOpen,\n}: {\n /**\n * Name of the active configuration or tool being started.\n */\n title: string\n /**\n * Short subtitle shown next to the arrow prompt.\n */\n description: string\n /**\n * Kubb version string rendered in the header.\n */\n version: string\n /**\n * When `false` the eyes are shown as closed dashes instead of open blocks.\n */\n areEyesOpen: boolean\n}): string {\n const kubbVersion = styleText(['bold', 'yellow'], `KUBB v${version}`)\n\n const eyeTop = areEyesOpen ? palette.eye('█▀█') : palette.eye('───')\n const eyeBottom = areEyesOpen ? palette.eye('▀▀▀') : palette.eye('───')\n\n return [\n ` ${palette.lid('▄▄▄▄▄▄▄▄▄▄▄▄▄')}`,\n ` ${palette.wood('█ ')}${palette.highlight('▄▄')}${palette.wood(' ')}${palette.highlight('▄▄')}${palette.wood(' █')} ${kubbVersion}`,\n ` ${palette.wood('█ ')}${eyeTop}${palette.wood(' ')}${eyeTop}${palette.wood(' █')} ${styleText('gray', title)}`,\n ` ${palette.wood('█ ')}${eyeBottom}${palette.wood(' ')}${palette.blush('◡')}${palette.wood(' ')}${eyeBottom}${palette.wood(' █')} ${styleText('yellow', '➜')} ${styleText('white', description)}`,\n ` ${palette.woodBase('▀▀▀▀▀▀▀▀▀▀▀▀▀')}`,\n ].join('\\n')\n}\n\n/**\n * Formats a millisecond duration with a threshold-based ANSI color.\n * `≤ 500 ms` → green · `≤ 1 000 ms` → yellow · `> 1 000 ms` → red.\n *\n * @example\n * ```ts\n * formatMsWithColor(200) // '\\x1b[32m200ms\\x1b[39m'\n * formatMsWithColor(800) // '\\x1b[33m800ms\\x1b[39m'\n * formatMsWithColor(1500) // '\\x1b[31m1.50s\\x1b[39m'\n * ```\n */\nexport function formatMsWithColor(ms: number): string {\n const formatted = formatMs(ms)\n if (ms <= 500) return styleText('green', formatted)\n if (ms <= 1000) return styleText('yellow', formatted)\n\n return styleText('red', formatted)\n}\n","import { relative } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, getElapsedMs } from '@internals/utils'\nimport type { Config } from '@kubb/core'\nimport { type Diagnostic, type DiagnosticFormatOptions, Diagnostics, logLevel as logLevelMap, type ProblemDiagnostic } from '@kubb/core'\nimport type { StudioConnectedContext } from '@kubb/studio'\nimport { formatMsWithColor } from './banner.ts'\nimport type { Logger, LoggerWriter, LogStatus, WriterProgress, WriterSpinner } from './defineLogger.ts'\n\n/** Display path for a config's input: the string form, or its `path` field when the input is an object. */\nfunction getInputPath(config: Config): string | undefined {\n const { input } = config\n if (typeof input === 'string') return input\n return typeof input?.path === 'string' ? input.path : undefined\n}\n\n/** Counts a noun, so a message never reads `1 files`. */\nexport function pluralize(count: number, noun: string): string {\n return `${count} ${count === 1 ? noun : `${noun}s`}`\n}\n\n/** Prefixes a `[HH:MM:SS]` timestamp at verbose and above. */\nfunction formatMessage(message: string, logLevel: number): string {\n if (logLevel >= logLevelMap.verbose) {\n const timestamp = new Date().toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n return `${styleText('dim', `[${timestamp}]`)} ${message}`\n }\n return message\n}\n\n/**\n * Renders a `studio:connected` event's versions: the runtime only when it differs from the host.\n */\nfunction formatVersions({ studio, kubb, agent }: StudioConnectedContext['versions']): string {\n return [`v${agent}`, kubb !== agent ? `runtime v${kubb}` : undefined, `Studio v${studio}`].filter(Boolean).join(', ')\n}\n\ntype ProgressState = {\n totalPlugins: number\n completedPlugins: number\n failedPlugins: number\n totalFiles: number\n processedFiles: number\n /** `process.hrtime()` snapshot taken at the start of generation, for the elapsed time. */\n hrStart: [number, number]\n}\n\n/** The progress summary line the clack logger shows, `null` when there is nothing to display. */\nfunction buildProgressLine(state: ProgressState): string | null {\n const parts: Array<string> = []\n const duration = formatMs(getElapsedMs(state.hrStart))\n\n if (state.totalPlugins > 0) {\n const pluginStr =\n state.failedPlugins > 0\n ? `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins} ${styleText('red', `(${state.failedPlugins} failed)`)}`\n : `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins}`\n parts.push(pluginStr)\n }\n\n if (state.totalFiles > 0) {\n parts.push(`Files ${styleText('green', state.processedFiles.toString())}/${state.totalFiles}`)\n }\n\n if (parts.length === 0) {\n return null\n }\n\n parts.push(`${styleText('green', duration)} elapsed`)\n return parts.join(styleText('dim', ' | '))\n}\n\nfunction createProgressCounters(): ProgressState {\n return {\n totalPlugins: 0,\n completedPlugins: 0,\n failedPlugins: 0,\n totalFiles: 0,\n processedFiles: 0,\n hrStart: process.hrtime(),\n }\n}\n\n/**\n * One output phase while its step owns the line. A phase buffers what it is told, because a spinner\n * redraws over anything written under it, and prints the lot once it knows its own result.\n */\ntype Phase = {\n successLabel: string\n failureLabel: string\n /**\n * Whether each hook's own result is worth a line. Format and lint run one command, so the phase\n * result already says everything; the post-generate phase runs several.\n */\n showHookResults: boolean\n failed: boolean\n hrStart: [number, number]\n lines: Array<string>\n /**\n * Raw lines a hook printed, drawn outside the group.\n */\n output: Array<string>\n}\n\ntype StartPhaseOptions = {\n /**\n * Shown while the phase runs.\n */\n running: string\n success: string\n failure: string\n showHookResults?: boolean\n}\n\n/**\n * The three output phases, in the order the generate runner runs them.\n */\nconst PHASES = {\n format: { running: 'Formatting', success: 'Formatted', failure: 'Formatting failed' },\n lint: { running: 'Linting', success: 'Linted', failure: 'Linting failed' },\n hooks: {\n running: 'Running post-generate hooks',\n success: 'Post-generate hooks completed',\n failure: 'Post-generate hooks failed',\n showHookResults: true,\n },\n} as const satisfies Record<string, StartPhaseOptions>\n\n/**\n * Drops the blank lines a subprocess leaves at either end of its output, so its block does not open\n * or close on an empty row.\n */\nfunction trimBlankEdges(lines: ReadonlyArray<string>): Array<string> {\n const start = lines.findIndex((line) => line.trim())\n if (start === -1) {\n return []\n }\n\n return lines.slice(start, lines.findLastIndex((line) => line.trim()) + 1)\n}\n\n/**\n * Wires a {@link LoggerWriter} onto the run's hooks. This owns what a run says and in what order:\n * one group per config, a step over the plugin work, a progress bar for the writes, one step per\n * output phase, then the summary and the group's closing result. The writer only decides how each\n * line looks, so every logger reports the same run the same way.\n *\n * @example\n * ```ts\n * export const plainLogger = createLogger(writer, { audience: 'agent' })\n * ```\n */\nexport function createLogger(writer: LoggerWriter, { audience }: { audience: DiagnosticFormatOptions['audience'] }): Logger {\n return function install(context, { logLevel }) {\n const silent = logLevel <= logLevelMap.silent\n const human = audience === 'human'\n const formatOptions: DiagnosticFormatOptions = {\n audience,\n verbose: logLevel >= logLevelMap.verbose,\n // The code lines up at the right edge, inside the two-column group indent.\n width: Math.min(process.stdout.columns || 80, 100) - 2,\n }\n const state = {\n ...createProgressCounters(),\n spinner: null as WriterSpinner | null,\n progress: null as WriterProgress | null,\n hooks: new Map<string, { hrStart: [number, number]; lines: Array<string> }>(),\n /**\n * Plugin results held back while the generation step owns the line.\n */\n pluginLines: [] as Array<string>,\n phase: null as Phase | null,\n groupOpen: false,\n /**\n * Whether this run keeps its files in memory, as a `kubb studio` run without `--allow-write` does.\n */\n inMemory: false,\n /**\n * Problems held back so the human view can print them grouped by plugin once the build ends.\n */\n problems: [] as Array<ProblemDiagnostic>,\n /**\n * The finished config's diagnostics and file count, for the closing summary.\n */\n outcome: null as { diagnostics: Array<Diagnostic>; filesCreated: number; hrStart: [number, number] } | null,\n }\n\n function text(message: string): string {\n return formatMessage(message, logLevel)\n }\n\n function startSpinner(message: string) {\n if (silent) {\n return\n }\n\n state.spinner = writer.spinner()\n state.spinner.start(text(message))\n }\n\n function stopSpinner(message?: string, status: LogStatus = 'success') {\n const spinner = state.spinner\n if (!spinner) {\n return\n }\n state.spinner = null\n\n if (message === undefined) {\n spinner.clear()\n return\n }\n if (status === 'failed') {\n spinner.error(text(message))\n return\n }\n spinner.stop(text(message))\n }\n\n function stopProgress(message?: string) {\n const progress = state.progress\n if (!progress) {\n return\n }\n state.progress = null\n progress.stop(message === undefined ? '' : text(message))\n }\n\n function startPhase({ running, success, failure, showHookResults = false }: StartPhaseOptions) {\n state.phase = { successLabel: success, failureLabel: failure, showHookResults, failed: false, hrStart: process.hrtime(), lines: [], output: [] }\n startSpinner(running)\n }\n\n function endPhase() {\n const phase = state.phase\n state.phase = null\n\n if (!phase || silent) {\n return\n }\n\n const duration = formatMsWithColor(getElapsedMs(phase.hrStart))\n\n stopSpinner(phase.failed ? `${phase.failureLabel} after ${duration}` : `${phase.successLabel} in ${duration}`, phase.failed ? 'failed' : 'success')\n\n if (phase.lines.length) {\n writer.block(phase.lines)\n }\n writeOutput(phase.output)\n }\n\n function writeOutput(lines: ReadonlyArray<string>) {\n const output = trimBlankEdges(lines)\n if (output.length) {\n writer.raw(output)\n }\n }\n\n /** `✖ Failed 1 error · 1 warning in plugin-ts` once the build ended, or `✗ Generation failed` for a run that stopped early. */\n function failedTitle(): string {\n const diagnostics = state.outcome?.diagnostics ?? []\n const counts = formatCounts(diagnostics)\n if (!human || !counts) {\n return '✗ Generation failed'\n }\n const plugins = Diagnostics.failedPlugins(diagnostics)\n return `✖ Failed ${counts}${plugins.length ? ` in ${plugins.join(', ')}` : ''}`\n }\n\n // A run that throws before `kubb:generation:end` never reaches the summary, so the lifecycle\n // end calls this too rather than leave a group without its closing line.\n function closeGroup(status: LogStatus) {\n if (!state.groupOpen) {\n return\n }\n state.groupOpen = false\n\n stopSpinner()\n stopProgress()\n writer.groupEnd(status === 'failed' ? styleText('red', failedTitle()) : styleText('green', '✓ Generation succeeded'))\n }\n\n function reset() {\n stopSpinner()\n stopProgress()\n Object.assign(state, createProgressCounters())\n state.hooks.clear()\n state.pluginLines = []\n state.phase = null\n state.groupOpen = false\n state.problems = []\n state.outcome = null\n }\n\n /**\n * Prints problems grouped under their plugin's name, each with the code aligned at the right.\n */\n function writeProblems(problems: ReadonlyArray<ProblemDiagnostic>) {\n if (!problems.length) {\n return\n }\n if (!human) {\n for (const problem of problems) writer.diagnostic(Diagnostics.format(problem, formatOptions))\n return\n }\n\n const byPlugin = Map.groupBy(problems, (problem) => problem.plugin ?? '')\n const lines = [...byPlugin].flatMap(([plugin, group]) => [\n ...(plugin ? [` ${styleText('bold', plugin)}`, ''] : []),\n ...group.flatMap((problem) => [...Diagnostics.format(problem, formatOptions).map((line) => ` ${line}`), '']),\n ])\n writer.diagnostic(lines.slice(0, -1))\n }\n\n /** The run's verdict: `1 error · 1 warning` for a human, `1 error, 1 warning` for an agent. */\n function formatCounts(diagnostics: ReadonlyArray<Diagnostic>): string {\n const { errors, warnings } = Diagnostics.count(diagnostics)\n const parts = [errors && pluralize(errors, 'error'), warnings && pluralize(warnings, 'warning')].filter(Boolean)\n return parts.join(human ? ' · ' : ', ')\n }\n\n function formatLine(symbol: string, message: string, info?: string): string {\n return text([symbol, message, info && styleText('dim', info)].filter(Boolean).join(' '))\n }\n\n context.hook('kubb:warn', ({ message, info }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n writer.warn(formatLine(styleText('yellow', '⚠'), message, logLevel >= logLevelMap.info ? info : undefined))\n })\n\n // Unguarded: a failure stays visible even at silent.\n context.hook('kubb:error', ({ error }) => {\n if (state.phase) {\n state.phase.failed = true\n }\n\n // Rendered as a `KUBB_UNKNOWN` diagnostic, so the output alone says what broke and where. The\n // name tells a `TypeError` from a plain `Error`.\n const message = error.name === 'Error' || Diagnostics.isError(error) ? error.message : `${error.name}: ${error.message}`\n const help = Diagnostics.isError(error) ? error.diagnostic.help : undefined\n const [headline = '', ...details] = Diagnostics.format({ code: Diagnostics.code.unknown, severity: 'error', message, help, cause: error }, formatOptions)\n\n if (!human) {\n stopSpinner()\n stopProgress()\n writer.diagnostic([headline, ...details])\n return\n }\n\n // The writer draws the error symbol, so the message goes in bare.\n if (state.spinner) {\n stopSpinner(message, 'failed')\n } else {\n writer.error(text(message))\n }\n if (details.length) {\n writer.block(details.map(text))\n }\n })\n\n context.hook('kubb:diagnostic', ({ diagnostic }) => {\n // Silent still surfaces errors so failures stay visible. It drops warnings and info.\n if (silent && diagnostic.severity !== 'error') {\n return\n }\n\n stopSpinner()\n stopProgress()\n\n if (Diagnostics.isUpdate(diagnostic)) {\n writer.update(\n [`\\`v${diagnostic.currentVersion}\\` → \\`v${diagnostic.latestVersion}\\``, 'Run `npm install -g @kubb/cli` to update'],\n 'Update available for `Kubb`',\n )\n return\n }\n\n // Inside a build, the human view waits for the end to group by plugin.\n if (human && state.groupOpen) {\n state.problems.push(diagnostic)\n return\n }\n writeProblems([diagnostic])\n })\n\n // A `kubb studio` session emits these on the same emitter as its generations, so one logger\n // renders the whole command.\n context.hook('studio:disconnected', ({ code, reason }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n\n stopSpinner()\n // 4002 is `AgentCloseCode.SUPERSEDED`, spelled out because `@kubb/studio` is an optional peer.\n if (code === 4002) {\n writer.warn(text('⚠ Another process connected to Kubb Studio as this agent, so this one stopped'))\n return\n }\n writer.warn(text(`⚠ Kubb Studio ended the session (${reason || `code ${code}`})`))\n })\n\n context.hook('studio:warn', ({ message, permission }) => {\n if (logLevel < logLevelMap.warn) {\n return\n }\n const remedy = permission ? `; pass --${permission.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`)} to allow it` : ''\n writer.warn(text(`⚠ ${message}${remedy}`))\n })\n\n // Unguarded, like `kubb:error`: a failure stays visible even at silent.\n context.hook('studio:error', ({ error }) => {\n if (state.spinner) {\n stopSpinner(error.message, 'failed')\n return\n }\n writer.error(text(error.message))\n })\n\n context.hook('kubb:lifecycle:start', () => {\n reset()\n })\n\n context.hook('kubb:generation:start', ({ config }) => {\n closeGroup('failed')\n reset()\n\n state.totalPlugins = config.plugins?.length ?? 0\n state.inMemory = config.storage?.name === 'memory'\n\n if (silent) {\n return\n }\n\n const inputPath = getInputPath(config)\n\n writer.group(text([styleText('bold', config.name ?? 'kubb'), inputPath ? styleText('dim', inputPath) : undefined].filter(Boolean).join(' ')))\n state.groupOpen = true\n\n startSpinner('Generating')\n })\n\n context.hook('kubb:format:start', () => startPhase(PHASES.format))\n context.hook('kubb:format:end', endPhase)\n context.hook('kubb:lint:start', () => startPhase(PHASES.lint))\n context.hook('kubb:lint:end', endPhase)\n context.hook('kubb:hooks:start', () => startPhase(PHASES.hooks))\n context.hook('kubb:hooks:end', endPhase)\n\n context.hook('kubb:hook:end', (ctx) => {\n const { id, command, name, args, success, error } = ctx\n if (!id) {\n return\n }\n\n if (!success && state.phase) {\n state.phase.failed = true\n }\n\n if (silent) {\n // Even when silent, surface a failed hook's captured output.\n if (!ctx.success) {\n if (ctx.stdout) console.log(ctx.stdout)\n if (ctx.stderr) console.error(ctx.stderr)\n }\n return\n }\n\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n state.hooks.delete(id)\n\n const label = styleText('dim', name ?? (args?.length ? `${command} ${args.join(' ')}` : command))\n const reason = error?.message ? ` (${error.message})` : ''\n const result = success\n ? `${styleText('green', '✓')} ${label} in ${formatMsWithColor(getElapsedMs(active.hrStart))}`\n : `${styleText('red', '✗')} ${label} failed${reason}`\n\n const phase = state.phase\n if (phase) {\n if (phase.showHookResults || !success) {\n phase.lines.push(result)\n }\n phase.output.push(...active.lines)\n return\n }\n\n stopSpinner()\n writer.step(text(result))\n writeOutput(active.lines)\n })\n\n context.hook('kubb:generation:end', ({ diagnostics = [], filesCreated = 0, hrStart = process.hrtime() }) => {\n stopSpinner()\n stopProgress()\n state.outcome = { diagnostics, filesCreated, hrStart }\n writeProblems(state.problems.splice(0))\n })\n\n context.hook('kubb:lifecycle:end', () => {\n writeProblems(state.problems.splice(0))\n closeGroup('failed')\n reset()\n })\n\n // Not registered at silent: the missing `kubb:hook:line` listener is also what tells the runner not to stream.\n if (!silent) {\n context.hook('kubb:info', ({ message, info }) => {\n const line = formatLine(styleText('blue', 'ℹ'), message, info)\n\n // Info carries something new (the auto-detected tool), so inside a phase it waits for the phase to print.\n if (state.phase) {\n state.phase.lines.push(line)\n return\n }\n if (state.spinner) {\n state.spinner.message(line)\n return\n }\n writer.info(line)\n })\n\n context.hook('kubb:success', ({ message, info }) => {\n const line = formatLine(styleText('green', '✓'), message, logLevel >= logLevelMap.info ? info : undefined)\n\n // The phase step's own result already reports these successes, so let the step carry them.\n if (state.spinner) {\n state.spinner.message(line)\n return\n }\n writer.success(line)\n })\n\n context.hook('studio:connected', ({ url, versions }) => {\n stopSpinner()\n writer.success(text(`✓ Connected to ${styleText('cyan', url)} ${styleText('dim', `(${formatVersions(versions)})`)}`))\n startSpinner('✓ Ready to receive jobs')\n })\n\n context.hook('studio:command', ({ command, info }) => {\n stopSpinner()\n writer.success(text(`✓ Finished ${command} ${styleText('dim', `(${info})`)}`))\n startSpinner('✓ Ready to receive jobs')\n })\n\n context.hook('studio:reconnecting', ({ delayMs }) => {\n stopSpinner()\n writer.info(text(styleText('dim', `Retrying connection to Kubb Studio in ${formatMs(delayMs)}`)))\n })\n\n context.hook('kubb:plugin:start', ({ plugin }) => {\n state.spinner?.message(text(`Generating ${styleText('dim', plugin.name)}`))\n })\n\n // Buffered, not printed: a step redraws over anything written while it runs.\n context.hook('kubb:plugin:end', ({ plugin, duration, success }) => {\n if (success) {\n state.completedPlugins++\n }\n if (!success) {\n state.failedPlugins++\n }\n state.pluginLines.push(text(`${plugin.name} ${success ? 'completed' : 'failed'} in ${formatMsWithColor(duration)}`))\n })\n\n context.hook('kubb:plugins:end', () => {\n const failed = state.failedPlugins > 0\n stopSpinner(buildProgressLine(state) ?? undefined, failed ? 'failed' : 'success')\n\n if (state.pluginLines.length) {\n writer.block(state.pluginLines)\n state.pluginLines = []\n }\n })\n\n context.hook('kubb:files:processing:start', ({ files }) => {\n stopSpinner()\n state.totalFiles = files.length\n state.processedFiles = 0\n\n state.progress = writer.progress(files.length)\n state.progress.start(text(`${state.inMemory ? 'Generating' : 'Writing'} ${pluralize(files.length, 'file')}`))\n })\n\n context.hook('kubb:files:processing:update', ({ files }) => {\n for (const { file, config } of files) {\n state.processedFiles++\n state.progress?.advance(`${state.inMemory ? 'Generating' : 'Writing'} ${relative(config.root, file.path)}`)\n }\n })\n\n context.hook('kubb:files:processing:end', () => {\n stopProgress(state.inMemory ? `Generated ${pluralize(state.processedFiles, 'file')} in memory` : `Wrote ${pluralize(state.processedFiles, 'file')}`)\n })\n\n context.hook('kubb:hook:start', ({ id }) => {\n if (!id) {\n return\n }\n state.hooks.set(id, { hrStart: process.hrtime(), lines: [] })\n })\n\n context.hook('kubb:hook:line', ({ id, line }) => {\n const active = state.hooks.get(id)\n if (!active) {\n return\n }\n\n // A phase step redraws its own line, so its output waits until the phase ends.\n if (state.phase) {\n active.lines.push(line)\n return\n }\n writer.raw([line])\n })\n }\n\n return {\n renderSummary(lines, { status }) {\n if (silent || !state.groupOpen) {\n return\n }\n\n if (human) {\n closeGroup(status)\n writer.diagnostic([...lines])\n return\n }\n\n // The verdict below replaces the group's closing line.\n stopSpinner()\n stopProgress()\n state.groupOpen = false\n\n // An agent gets one verdict line instead of the aligned table, and on failure where to get more.\n const { diagnostics = [], filesCreated = 0, hrStart = process.hrtime() } = state.outcome ?? {}\n if (status === 'failed') {\n const plugins = Diagnostics.failedPlugins(diagnostics)\n writer.diagnostic([\n `Kubb failed: ${formatCounts(diagnostics) || 'an error'}${plugins.length ? ` (${plugins.join(', ')})` : ''}. Exit code 1.`,\n 'Rerun with --reporter json for machine-readable diagnostics.',\n ])\n return\n }\n const warnings = formatCounts(diagnostics)\n writer.diagnostic([\n `Kubb succeeded: ${pluralize(filesCreated, 'file')} generated in ${formatMs(getElapsedMs(hrStart))}${warnings ? `, ${warnings}` : ''}.`,\n ])\n },\n }\n }\n}\n","import { styleText } from 'node:util'\nimport * as clack from '@clack/prompts'\nimport { createLogger } from './createLogger.ts'\nimport type { Logger, LoggerWriter } from './defineLogger.ts'\n\n/**\n * Draws with clack: a gutter bar per group, animated steps, and a progress bar for the writes.\n */\nexport const clackWriter: LoggerWriter = {\n group: (title) => clack.intro(title),\n groupEnd: (text) => clack.outro(text),\n step: (text) => clack.log.step(text, { spacing: 0 }),\n info: (text) => clack.log.info(text),\n success: (text) => clack.log.success(text),\n warn: (text) => clack.log.warn(text),\n error: (text) => clack.log.error(text),\n block: (lines) => clack.log.message(lines, { spacing: 0 }),\n // A subprocess's output is not Kubb's tree, so it goes out past clack and its gutter bar. The\n // step above it is already stopped by the time this runs.\n raw: (lines) => console.log(styleText('dim', lines.join('\\n'))),\n // The diagnostic carries its own code and indented rows, so clear clack's gutter and bar and let\n // the block stand on its own.\n diagnostic: (lines) => clack.log.message(lines, { symbol: '', secondarySymbol: '' }),\n update: (lines, title) =>\n clack.box(lines.join('\\n'), title, {\n width: 'auto',\n formatBorder: (border: string) => styleText('yellow', border),\n rounded: true,\n withGuide: false,\n contentAlign: 'center',\n titleAlign: 'center',\n }),\n spinner: () => clack.spinner(),\n progress(max) {\n const bar = clack.progress({ style: 'block', max, size: 30 })\n\n return {\n start: (text) => bar.start(text),\n advance: (text) => bar.advance(1, text),\n stop: (text) => bar.stop(text),\n }\n },\n}\n\n/**\n * TTY logger for local development, with animated steps and progress bars.\n */\nexport const clackLogger: Logger = createLogger(clackWriter, { audience: 'human' })\n","import { createLogger } from './createLogger.ts'\nimport type { Logger, LoggerWriter } from './defineLogger.ts'\n\n/**\n * Prefixes that stand in for the symbols clack draws, so plain output reads the same way.\n */\nexport const SYMBOLS = { info: 'ℹ', warn: '⚠', error: '✗', step: '◇' } as const\n\n/** Draws with one `write` call per line. Nothing animates, so a step prints at start and end. */\nfunction createWriter(write: (line: string) => void): LoggerWriter {\n return {\n group: write,\n groupEnd: write,\n step: (text) => write(`${SYMBOLS.step} ${text}`),\n info: write,\n success: write,\n warn: write,\n error: (text) => write(`${SYMBOLS.error} ${text}`),\n block: (lines) => write(lines.join('\\n')),\n raw: (lines) => write(lines.join('\\n')),\n diagnostic: (lines) => write(lines.join('\\n')),\n update: (lines, title) => write([title, ...lines].join('\\n')),\n spinner: () => ({\n start: write,\n message: write,\n clear: () => {},\n stop: (text) => text && write(text),\n error: (text) => write(`${SYMBOLS.error} ${text}`),\n }),\n progress: () => ({\n start: write,\n advance: write,\n stop: (text) => text && write(text),\n }),\n }\n}\n\n/** The plain logger writing through `write`, e.g. `console.error` so stdout carries only JSON. */\nexport function createPlainLogger(write: (line: string) => void): Logger {\n return createLogger(createWriter(write), { audience: 'agent' })\n}\n\n/** Draws on the console, for non-TTY environments and for an AI coding agent reading the output. */\nexport const plainWriter = createWriter((line) => console.log(line))\n\n/**\n * Console adapter for non-TTY environments, and for an AI coding agent reading the output. Reports\n * the same run in the same order as `clackLogger`, without the animation.\n */\nexport const plainLogger = createLogger(plainWriter, { audience: 'agent' })\n","import { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { isRichOutput } from '../utils/env.ts'\nimport { getIntro } from './banner.ts'\nimport { clackWriter } from './clackLogger.ts'\nimport type { LoggerWriter, WriterSpinner } from './defineLogger.ts'\nimport { plainWriter, SYMBOLS } from './plainLogger.ts'\n\nconst SPONSOR_TIPS = [\n 'Your sponsorship keeps Kubb codegen, plugins, and docs maintained',\n 'Sponsor faster generators and better Kubb Studio workflows',\n 'Help keep Kubb free for TypeScript teams building APIs',\n 'Support React Query, Zod, Faker, and MSW integrations',\n 'Back open-source tools that turn OpenAPI into TypeScript',\n 'Sponsor fixes, releases, and new plugins for your API workflow',\n 'Help Kubb stay independent and focused on developer tools',\n] as const\n\nconst SPONSOR_LINKS = ['https://github.com/sponsors/stijnvanhulle', 'https://opencollective.com/kubb', 'https://kubb.dev/sponsors'] as const\n\n/** The writer the loggers draw with on this terminal, so a command's own lines look like its run. */\nfunction writer(): LoggerWriter {\n return isRichOutput() ? clackWriter : plainWriter\n}\n\nfunction nextTip(): string {\n const tip = SPONSOR_TIPS[Math.floor(Math.random() * SPONSOR_TIPS.length)]!\n const link = SPONSOR_LINKS[Math.floor(Math.random() * SPONSOR_LINKS.length)]!\n return `${tip}: ${link}`\n}\n\nfunction formatTip(tip: string): string {\n return styleText('magenta', ' Tip ') + styleText('yellow', tip)\n}\n\n/**\n * Prints one random tip outside every group. Rich terminals get the styled variant;\n * plain/CI output gets a stable text-only line so the tip is still visible as final output.\n */\nexport function logTip(): void {\n const tip = nextTip()\n if (!isRichOutput()) {\n console.log(`Tip: ${tip}`)\n return\n }\n\n console.log(`${styleText('magenta', '✦')}${formatTip(tip)}`)\n}\n\ntype Level = keyof typeof SYMBOLS\n\n// Not through the writers: in plain output a command's own info and warning carry their symbol, and clack's step keeps its spacing.\nfunction write(level: Level, message: string): void {\n if (isRichOutput()) {\n prompts.log[level](message)\n\n return\n }\n\n console.log(`${SYMBOLS[level]} ${message}`)\n}\n\ntype IntroOptions = {\n title?: string\n /**\n * Printed under the title, for a command that has a caveat to lead with.\n */\n warning?: string\n /**\n * Whether to open a block a later {@link logOutro} closes. Pass `false` for a command that\n * prints and exits, since nothing would ever close the block.\n *\n * @default true\n */\n block?: boolean\n}\n\n/**\n * Opens a command's output with its title.\n */\nexport function logIntro({ title, warning, block = true }: IntroOptions): void {\n if (block && isRichOutput()) {\n if (title) {\n prompts.intro(title)\n }\n\n if (warning) {\n prompts.log.warn(warning)\n }\n\n return\n }\n\n if (title) {\n console.log(title)\n }\n\n if (warning) {\n console.warn(warning)\n }\n\n if (title || warning) {\n console.log()\n }\n}\n\n/**\n * Closes the block {@link logIntro} opened. The closing gutter is not a written line, so plain\n * output prints the text on its own.\n */\nexport function logOutro(text: string): void {\n writer().groupEnd(text)\n}\n\n/**\n * Prints one empty line between two groups, without clack's gutter bar, since the bar belongs to a\n * group and a spacer sits outside every one.\n */\nexport function logSpacer(): void {\n console.log('')\n}\n\n/**\n * Opens the command with the Kubb mascot and version, or a single version line where the terminal\n * cannot draw it.\n */\nexport function logBanner(version: string): void {\n if (isRichOutput()) {\n console.log(`\\n${getIntro({ title: 'Turn your API spec into type-safe code', description: 'Ready to start', version, areEyesOpen: true })}\\n`)\n\n return\n }\n\n console.log(`Kubb CLI v${version}`)\n}\n\n/** Prints lines as one block, without a symbol in front of them. Not the writer's block, which drops clack's spacing around it. */\nexport function logBlock(lines: string | Array<string>): void {\n if (isRichOutput()) {\n prompts.log.message(lines)\n\n return\n }\n\n console.log([lines].flat().join('\\n'))\n}\n\nexport function logInfo(message: string): void {\n write('info', message)\n}\n\nexport function logWarn(message: string): void {\n write('warn', message)\n}\n\nexport function logError(message: string): void {\n write('error', message)\n}\n\n/**\n * Reports a step the command is taking, rather than something it found.\n */\nexport function logStep(message: string): void {\n write('step', message)\n}\n\n/**\n * A progress spinner, or a writer that prints each message it is given when the terminal cannot\n * animate one. Callers drive both the same way, including the failure state.\n */\nexport function createSpinner(): WriterSpinner {\n return writer().spinner()\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
|
-
const require_Telemetry = require("./Telemetry-
|
|
2
|
+
const require_Telemetry = require("./Telemetry-BV4GonCV.cjs");
|
|
3
3
|
let node_process = require("node:process");
|
|
4
4
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
5
5
|
let _kubb_core = require("@kubb/core");
|
|
@@ -9,7 +9,12 @@ const ID = new RegExp(`^${SLUG}(\\/${SLUG})?$`);
|
|
|
9
9
|
/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */
|
|
10
10
|
function registryUrl() {
|
|
11
11
|
const url = node_process.default.env.KUBB_REGISTRY || "https://kubb.dev/registry";
|
|
12
|
-
if (!/^https?:\/\//.test(url)) throw new Error(
|
|
12
|
+
if (!/^https?:\/\//.test(url)) throw new _kubb_core.Diagnostics.Error({
|
|
13
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
14
|
+
severity: "error",
|
|
15
|
+
message: `KUBB_REGISTRY must be an http(s) URL, got "${url}".`,
|
|
16
|
+
help: "Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry."
|
|
17
|
+
});
|
|
13
18
|
return url.replace(/\/+$/, "");
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
@@ -18,27 +23,51 @@ function registryUrl() {
|
|
|
18
23
|
* @throws when the id has another shape, so it never reaches a URL unchecked.
|
|
19
24
|
*/
|
|
20
25
|
function toRegistryId(input) {
|
|
21
|
-
if (!ID.test(input)) throw new Error(
|
|
26
|
+
if (!ID.test(input)) throw new _kubb_core.Diagnostics.Error({
|
|
27
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
28
|
+
severity: "error",
|
|
29
|
+
message: `"${input}" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`
|
|
30
|
+
});
|
|
22
31
|
return input.includes("/") ? input : `kubb-labs/${input}`;
|
|
23
32
|
}
|
|
24
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.
|
|
35
|
+
* A network error throws with the URL.
|
|
36
|
+
*/
|
|
25
37
|
async function fetchJSON(url) {
|
|
38
|
+
let response;
|
|
26
39
|
try {
|
|
27
|
-
|
|
28
|
-
if (!response.ok) return { status: response.status };
|
|
29
|
-
return {
|
|
30
|
-
status: response.status,
|
|
31
|
-
body: await response.json()
|
|
32
|
-
};
|
|
40
|
+
response = await globalThis.fetch(url, { headers: { accept: "application/json" } });
|
|
33
41
|
} catch (cause) {
|
|
34
|
-
throw new Error(
|
|
42
|
+
throw new _kubb_core.Diagnostics.Error({
|
|
43
|
+
code: _kubb_core.Diagnostics.code.inputUnreachable,
|
|
44
|
+
severity: "error",
|
|
45
|
+
message: `Could not read ${url}: ${require_Telemetry.getErrorMessage(cause)}`,
|
|
46
|
+
help: "Check your network connection and that the registry is reachable.",
|
|
47
|
+
cause: require_Telemetry.toError(cause)
|
|
48
|
+
});
|
|
35
49
|
}
|
|
50
|
+
if (!response.ok) return { status: response.status };
|
|
51
|
+
return {
|
|
52
|
+
status: response.status,
|
|
53
|
+
body: await response.json().catch(() => void 0)
|
|
54
|
+
};
|
|
36
55
|
}
|
|
37
56
|
/** Fetches one extension's detail document. */
|
|
38
57
|
async function fetchRegistryDetail({ id, registry }) {
|
|
39
58
|
const { status, body } = await fetchJSON(`${registry}/${id}.json`);
|
|
40
|
-
if (status === 404) throw new Error(
|
|
41
|
-
|
|
59
|
+
if (status === 404) throw new _kubb_core.Diagnostics.Error({
|
|
60
|
+
code: _kubb_core.Diagnostics.code.pluginNotFound,
|
|
61
|
+
severity: "error",
|
|
62
|
+
message: `"${id}" is not in the registry at ${registry}.`,
|
|
63
|
+
help: "Check the id at https://kubb.dev/extensions."
|
|
64
|
+
});
|
|
65
|
+
if (status !== 200 || !(0, _kubb_core.isRegistryEntry)(body) || body.id !== id) throw new _kubb_core.Diagnostics.Error({
|
|
66
|
+
code: _kubb_core.Diagnostics.code.inputRequestFailed,
|
|
67
|
+
severity: "error",
|
|
68
|
+
message: `The registry at ${registry} sent an invalid entry for "${id}" (HTTP ${status}).`,
|
|
69
|
+
help: "Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry."
|
|
70
|
+
});
|
|
42
71
|
const { overview } = body;
|
|
43
72
|
return {
|
|
44
73
|
...body,
|
|
@@ -49,7 +78,12 @@ async function fetchRegistryDetail({ id, registry }) {
|
|
|
49
78
|
async function fetchRegistryIndex({ registry }) {
|
|
50
79
|
const { status, body } = await fetchJSON(`${registry}/index.json`);
|
|
51
80
|
const index = body;
|
|
52
|
-
if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) throw new Error(
|
|
81
|
+
if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) throw new _kubb_core.Diagnostics.Error({
|
|
82
|
+
code: _kubb_core.Diagnostics.code.inputRequestFailed,
|
|
83
|
+
severity: "error",
|
|
84
|
+
message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,
|
|
85
|
+
help: "Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry."
|
|
86
|
+
});
|
|
53
87
|
return index.extensions.filter(_kubb_core.isRegistryEntry);
|
|
54
88
|
}
|
|
55
89
|
/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */
|
|
@@ -120,4 +154,4 @@ Object.defineProperty(exports, "toRegistryId", {
|
|
|
120
154
|
}
|
|
121
155
|
});
|
|
122
156
|
|
|
123
|
-
//# sourceMappingURL=registry-
|
|
157
|
+
//# sourceMappingURL=registry-C8E_G7Xc.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-C8E_G7Xc.cjs","names":["process","Diagnostics","getErrorMessage","toError","isRegistryEntry","isValid","isLessThan"],"sources":["../src/utils/registry.ts"],"sourcesContent":["import process from 'node:process'\nimport { getErrorMessage, toError } from '@internals/utils'\nimport {\n checkCompatibility,\n Diagnostics,\n type ExtensionManifest,\n isRegistryEntry,\n type RegistryArtifact,\n type RegistryDetail,\n type RegistryEntry,\n} from '@kubb/core'\nimport { isLessThan, isValid } from 'verkit'\n\nexport const DEFAULT_REGISTRY = 'https://kubb.dev/registry'\n\nconst SLUG = '[a-z0-9]+(?:-[a-z0-9]+)*'\nconst ID = new RegExp(`^${SLUG}(\\\\/${SLUG})?$`)\n\n/** The registry base URL: `KUBB_REGISTRY`, or kubb.dev. */\nexport function registryUrl(): string {\n const url = process.env.KUBB_REGISTRY || DEFAULT_REGISTRY\n if (!/^https?:\\/\\//.test(url))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `KUBB_REGISTRY must be an http(s) URL, got \"${url}\".`,\n help: 'Set `KUBB_REGISTRY` to an http(s) URL, or unset it to use https://kubb.dev/registry.',\n })\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Turns `owner/slug`, or a bare `slug` meaning `kubb-labs/<slug>`, into a registry id.\n *\n * @throws when the id has another shape, so it never reaches a URL unchecked.\n */\nexport function toRegistryId(input: string): string {\n if (!ID.test(input))\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `\"${input}\" is not a registry id. Use owner/slug, such as kubb-labs/plugin-zod, or a slug, such as plugin-zod.`,\n })\n return input.includes('/') ? input : `kubb-labs/${input}`\n}\n\n/**\n * GETs `url` as JSON. A non-2xx answer or a body that is not JSON returns no `body`.\n * A network error throws with the URL.\n */\nasync function fetchJSON(url: string): Promise<{ status: number; body?: unknown }> {\n let response: Response\n try {\n response = await globalThis.fetch(url, { headers: { accept: 'application/json' } })\n } catch (cause) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputUnreachable,\n severity: 'error',\n message: `Could not read ${url}: ${getErrorMessage(cause)}`,\n help: 'Check your network connection and that the registry is reachable.',\n cause: toError(cause),\n })\n }\n if (!response.ok) return { status: response.status }\n return { status: response.status, body: await response.json().catch(() => undefined) }\n}\n\n/** Fetches one extension's detail document. */\nexport async function fetchRegistryDetail({ id, registry }: { id: string; registry: string }): Promise<RegistryDetail> {\n const { status, body } = await fetchJSON(`${registry}/${id}.json`)\n if (status === 404)\n throw new Diagnostics.Error({\n code: Diagnostics.code.pluginNotFound,\n severity: 'error',\n message: `\"${id}\" is not in the registry at ${registry}.`,\n help: 'Check the id at https://kubb.dev/extensions.',\n })\n if (status !== 200 || !isRegistryEntry(body) || body.id !== id)\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid entry for \"${id}\" (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n\n const { overview } = body as { overview?: unknown }\n return { ...body, overview: typeof overview === 'string' ? overview : null }\n}\n\n/** Fetches the registry index, leaving out entries that fail validation. */\nexport async function fetchRegistryIndex({ registry }: { registry: string }): Promise<Array<RegistryEntry>> {\n const { status, body } = await fetchJSON(`${registry}/index.json`)\n const index = body as { version?: unknown; extensions?: unknown } | null | undefined\n if (status !== 200 || index?.version !== 1 || !Array.isArray(index.extensions)) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.inputRequestFailed,\n severity: 'error',\n message: `The registry at ${registry} sent an invalid index (HTTP ${status}).`,\n help: 'Try again later, or check that `KUBB_REGISTRY` points at a Kubb registry.',\n })\n }\n return index.extensions.filter(isRegistryEntry)\n}\n\n/** What the package manager installs: `<package>@<version>`, or a GitHub release's commit, so the install cannot move with the tag. */\nexport function installSpec(artifact: RegistryArtifact): string {\n return artifact.kind === 'github' ? `github:${artifact.owner}/${artifact.repo}#${artifact.commit}` : `${artifact.package}@${artifact.version}`\n}\n\n/** Why the running Kubb or Node.js version cannot use this extension, or `undefined` when it can. */\nexport function incompatibility(manifest: ExtensionManifest): string | undefined {\n try {\n checkCompatibility({ name: manifest.name, compatibility: manifest.compatibility })\n return undefined\n } catch (error) {\n return getErrorMessage(error)\n }\n}\n\n/**\n * Whether `latest` is newer than `installed`. An unknown installed version counts as outdated, and an\n * invalid `latest` never does.\n */\nexport function isOutdated({ installed, latest }: { installed: string | undefined; latest: string }): boolean {\n if (!isValid(latest)) return false\n return !installed || !isValid(installed) || isLessThan(installed, latest)\n}\n"],"mappings":"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"}
|