@kubb/cli 5.11.6 → 5.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Telemetry-Be3hIy6_.cjs → Telemetry-D-IDgRfq.cjs} +2 -2
- package/dist/{Telemetry-Be3hIy6_.cjs.map → Telemetry-D-IDgRfq.cjs.map} +1 -1
- package/dist/{Telemetry-CfJAUDnh.js → Telemetry-wyeU72_v.js} +2 -2
- package/dist/{Telemetry-CfJAUDnh.js.map → Telemetry-wyeU72_v.js.map} +1 -1
- package/dist/{background-BBpH2jmk.js → background-B49o0iOw.js} +2 -2
- package/dist/{background-BBpH2jmk.js.map → background-B49o0iOw.js.map} +1 -1
- package/dist/{background-DS2zOde-.js → background-D0g61wus.js} +1 -1
- package/dist/{background-BW-e9FCX.cjs → background-DY-7vFSm.cjs} +2 -2
- package/dist/{background-BW-e9FCX.cjs.map → background-DY-7vFSm.cjs.map} +1 -1
- package/dist/index.cjs +19 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/dist/{registry-CgQYxUju.js → registry-BS1M25zz.js} +3 -3
- package/dist/{registry-CgQYxUju.js.map → registry-BS1M25zz.js.map} +1 -1
- package/dist/{registry-BlKLO4ft.cjs → registry-DSDoBaVk.cjs} +3 -3
- package/dist/{registry-BlKLO4ft.cjs.map → registry-DSDoBaVk.cjs.map} +1 -1
- package/dist/{reporters-Dl8lrJZG.js → reporters-BXNKLBLf.js} +4 -4
- package/dist/{reporters-Dl8lrJZG.js.map → reporters-BXNKLBLf.js.map} +1 -1
- package/dist/{reporters-TkCgd4dS.cjs → reporters-C4xq0GFT.cjs} +4 -4
- package/dist/{reporters-TkCgd4dS.cjs.map → reporters-C4xq0GFT.cjs.map} +1 -1
- package/dist/{run-CFf0yxyY.cjs → run-4DWl8vSu.cjs} +12 -6
- package/dist/run-4DWl8vSu.cjs.map +1 -0
- package/dist/{run-BJn0RSW2.js → run-Bd_ZfPG1.js} +7 -7
- package/dist/{run-BJn0RSW2.js.map → run-Bd_ZfPG1.js.map} +1 -1
- package/dist/{run-D_dD7xHp.js → run-Byr2y0hI.js} +12 -6
- package/dist/run-Byr2y0hI.js.map +1 -0
- package/dist/{run-BszyZwY3.cjs → run-C9EYgEqG.cjs} +7 -7
- package/dist/{run-BszyZwY3.cjs.map → run-C9EYgEqG.cjs.map} +1 -1
- package/dist/{run-wkN1irUo.js → run-CuRCXhQb.js} +22 -28
- package/dist/run-CuRCXhQb.js.map +1 -0
- package/dist/{run-TrjCNL8e.cjs → run-DNzoHmRZ.cjs} +22 -28
- package/dist/run-DNzoHmRZ.cjs.map +1 -0
- package/dist/{run-DsJJCzQD.js → run-DcX-F_wC.js} +1 -1
- package/dist/{run-BtVKUjdK.cjs → run-bSFXs9i3.cjs} +2 -2
- package/dist/{run-BtVKUjdK.cjs.map → run-bSFXs9i3.cjs.map} +1 -1
- package/dist/{run-KuzAqsjg.js → run-z960932J.js} +2 -2
- package/dist/{run-KuzAqsjg.js.map → run-z960932J.js.map} +1 -1
- package/dist/{snapshot-CdGwHH15.js → snapshot-CLgI_qzL.js} +6 -6
- package/dist/{snapshot-CdGwHH15.js.map → snapshot-CLgI_qzL.js.map} +1 -1
- package/dist/{snapshot-u4L8mh4Y.cjs → snapshot-DzzsJSWr.cjs} +6 -6
- package/dist/{snapshot-u4L8mh4Y.cjs.map → snapshot-DzzsJSWr.cjs.map} +1 -1
- package/dist/{status-dpSvxxtN.cjs → status-B50z7yha.cjs} +3 -3
- package/dist/{status-dpSvxxtN.cjs.map → status-B50z7yha.cjs.map} +1 -1
- package/dist/{status-DHPeR3bq.js → status-DrKO_t5S.js} +3 -3
- package/dist/{status-DHPeR3bq.js.map → status-DrKO_t5S.js.map} +1 -1
- package/dist/studioWorker.js +2 -2
- package/dist/{summary-DkSLti6f.js → summary-Bi_pAA9i.js} +3 -3
- package/dist/{summary-DkSLti6f.js.map → summary-Bi_pAA9i.js.map} +1 -1
- package/dist/{summary-6-rotl2L.cjs → summary-C8QI_30-.cjs} +3 -3
- package/dist/{summary-6-rotl2L.cjs.map → summary-C8QI_30-.cjs.map} +1 -1
- package/dist/{text-CMP4M19Z.js → text-DgzXienb.js} +2 -2
- package/dist/{text-CMP4M19Z.js.map → text-DgzXienb.js.map} +1 -1
- package/dist/{text-CknhKMvM.cjs → text-Sp4fptq1.cjs} +2 -2
- package/dist/{text-CknhKMvM.cjs.map → text-Sp4fptq1.cjs.map} +1 -1
- package/dist/{utils-CnjEJIdZ.js → utils-BDDF8GOv.js} +4 -80
- package/dist/utils-BDDF8GOv.js.map +1 -0
- package/dist/{utils-DpKrXR2t.cjs → utils-Dju97QYB.cjs} +3 -91
- package/dist/utils-Dju97QYB.cjs.map +1 -0
- package/package.json +7 -7
- package/dist/run-CFf0yxyY.cjs.map +0 -1
- package/dist/run-D_dD7xHp.js.map +0 -1
- package/dist/run-TrjCNL8e.cjs.map +0 -1
- package/dist/run-wkN1irUo.js.map +0 -1
- package/dist/utils-CnjEJIdZ.js.map +0 -1
- package/dist/utils-DpKrXR2t.cjs.map +0 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
2
|
import { n as toError } from "./errors-DmC83ALX.js";
|
|
3
|
-
import { n as trackRun } from "./Telemetry-
|
|
4
|
-
import { t as pluralize } from "./text-
|
|
3
|
+
import { n as trackRun } from "./Telemetry-wyeU72_v.js";
|
|
4
|
+
import { t as pluralize } from "./text-DgzXienb.js";
|
|
5
5
|
import { n as findConfigFile, t as getConfigs } from "./config-Bh00Hwpw.js";
|
|
6
|
-
import { t as logCommandSummary } from "./summary-
|
|
6
|
+
import { t as logCommandSummary } from "./summary-Bi_pAA9i.js";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import { resolve } from "node:path";
|
|
10
|
+
import { checkoutGitInput, getInputKind } from "@kubb/core";
|
|
10
11
|
//#region src/runners/validate/run.ts
|
|
11
12
|
/**
|
|
12
13
|
* Validates `input` with the configured adapters, falling back to OpenAPI when no config exists.
|
|
@@ -36,7 +37,7 @@ async function run({ input, configPath }) {
|
|
|
36
37
|
}];
|
|
37
38
|
};
|
|
38
39
|
const unique = new Map((loaded?.configs ?? []).map((config) => {
|
|
39
|
-
const resolved =
|
|
40
|
+
const resolved = getInputKind(input) === "file" ? resolve(config.root || process.cwd(), input) : input;
|
|
40
41
|
return [`${config.adapter?.name}\0${resolved}`, {
|
|
41
42
|
adapter: config.adapter,
|
|
42
43
|
input: resolved
|
|
@@ -47,7 +48,12 @@ async function run({ input, configPath }) {
|
|
|
47
48
|
for (const target of targets) {
|
|
48
49
|
adapterName = target.adapter?.name;
|
|
49
50
|
if (!target.adapter) throw new Error("No adapter is configured. Set adapter in your Kubb config to validate this specification.");
|
|
50
|
-
|
|
51
|
+
const checkout = getInputKind(target.input) === "git" ? await checkoutGitInput(target.input) : void 0;
|
|
52
|
+
try {
|
|
53
|
+
await target.adapter.validate(checkout?.path ?? target.input, { throwOnError: true });
|
|
54
|
+
} finally {
|
|
55
|
+
await checkout?.dispose();
|
|
56
|
+
}
|
|
51
57
|
}
|
|
52
58
|
const specifications = new Set(targets.map((target) => target.input)).size;
|
|
53
59
|
const adapterNames = [...new Set(targets.flatMap((target) => target.adapter?.name ?? []))];
|
|
@@ -90,4 +96,4 @@ async function run({ input, configPath }) {
|
|
|
90
96
|
//#endregion
|
|
91
97
|
export { run };
|
|
92
98
|
|
|
93
|
-
//# sourceMappingURL=run-
|
|
99
|
+
//# sourceMappingURL=run-Byr2y0hI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-Byr2y0hI.js","names":[],"sources":["../src/runners/validate/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { resolve } from 'node:path'\nimport { styleText } from 'node:util'\nimport { findConfigFile } from '@internals/shared'\nimport { toError } from '@internals/utils'\nimport { type Config, checkoutGitInput, getInputKind } from '@kubb/core'\nimport { trackRun } from '../../Telemetry.ts'\nimport { getConfigs } from '../../config.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport { logCommandSummary } from '../../ui/summary.ts'\n\ntype ValidateOptions = {\n /**\n * Path, URL, or git input (`git+<repo>#<ref>:<path>`) of the specification to validate.\n */\n input: string\n configPath?: string\n}\n\n/**\n * Validates `input` with the configured adapters, falling back to OpenAPI when no config exists.\n * Exits the process with code 1 on validation failure or missing dependency.\n */\nexport async function run({ input, configPath }: ValidateOptions): Promise<void> {\n const hrStart = process.hrtime()\n const report = trackRun({ command: 'validate', hrStart })\n let adapterName: string | undefined\n\n try {\n const configFile = configPath ?? findConfigFile()\n // A config found by search that does not load must not block validating a file; an explicit `--config` still fails.\n const loaded = configFile\n ? await getConfigs({ configPath: configFile, input }).catch((error) => {\n if (configPath) throw error\n })\n : undefined\n const fallback = async () => {\n adapterName = '@kubb/adapter-oas'\n const { adapterOas } = await import('@kubb/adapter-oas')\n return [{ adapter: adapterOas(), input }]\n }\n // An array config often repeats one adapter, so each adapter and input pair is validated once.\n const unique = new Map(\n (loaded?.configs ?? []).map((config) => {\n const resolved = getInputKind(input) === 'file' ? resolve(config.root || process.cwd(), input) : input\n return [`${config.adapter?.name}\\0${resolved}`, { adapter: config.adapter, input: resolved }] as const\n }),\n )\n const targets: Array<{ adapter: Config['adapter']; input: string }> = loaded ? [...unique.values()] : await fallback()\n if (!targets.length) throw new Error('The Kubb config contains no configurations to validate.')\n for (const target of targets) {\n adapterName = target.adapter?.name\n if (!target.adapter) throw new Error('No adapter is configured. Set adapter in your Kubb config to validate this specification.')\n const checkout = getInputKind(target.input) === 'git' ? await checkoutGitInput(target.input) : undefined\n try {\n await target.adapter.validate(checkout?.path ?? target.input, { throwOnError: true })\n } finally {\n await checkout?.dispose()\n }\n }\n const specifications = new Set(targets.map((target) => target.input)).size\n const adapterNames = [...new Set(targets.flatMap((target) => target.adapter?.name ?? []))]\n await report({ status: 'success' })\n\n logCommandSummary({\n title: 'Validation passed',\n status: 'success',\n hrStart,\n lines: [\n ` ${styleText('bold', `${pluralize(specifications, 'specification')} validated`)}`,\n ` ${styleText('dim', 'Input')} ${styleText('cyan', input)}`,\n ` ${styleText('dim', adapterNames.length === 1 ? 'Adapter' : 'Adapters')} ${adapterNames.join(', ')}`,\n ],\n })\n } catch (error) {\n await report({ status: 'failed' })\n const message = toError(error).message\n const missingAdapter = adapterName === '@kubb/adapter-oas' && /(?:Cannot find|Cannot resolve|not found)[\\s\\S]*@kubb\\/adapter-oas/.test(message)\n logCommandSummary({\n title: missingAdapter ? 'Could not validate' : 'Validation failed',\n status: 'failed',\n hrStart,\n lines: [\n ` ${styleText('dim', 'Input')} ${styleText('cyan', input)}`,\n ` ${styleText('dim', 'Adapter')} ${adapterName ?? 'not configured'}${missingAdapter ? ' · not installed' : ''}`,\n '',\n styleText('bold', missingAdapter ? 'Required package' : 'Validation error'),\n ` ${styleText('red', message)}`,\n ...(missingAdapter\n ? ['', 'Install it with:', styleText('cyan', ' npm install @kubb/adapter-oas'), styleText('cyan', ' pnpm add @kubb/adapter-oas')]\n : []),\n ],\n })\n\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,eAAsB,IAAI,EAAE,OAAO,cAA8C;CAC/E,MAAM,UAAU,QAAQ,OAAO;CAC/B,MAAM,SAAS,SAAS;EAAE,SAAS;EAAY;CAAQ,CAAC;CACxD,IAAI;CAEJ,IAAI;EACF,MAAM,aAAa,cAAc,eAAe;EAEhD,MAAM,SAAS,aACX,MAAM,WAAW;GAAE,YAAY;GAAY;EAAM,CAAC,CAAC,CAAC,OAAO,UAAU;GACnE,IAAI,YAAY,MAAM;EACxB,CAAC,IACD,KAAA;EACJ,MAAM,WAAW,YAAY;GAC3B,cAAc;GACd,MAAM,EAAE,eAAe,MAAM,OAAO;GACpC,OAAO,CAAC;IAAE,SAAS,WAAW;IAAG;GAAM,CAAC;EAC1C;EAEA,MAAM,SAAS,IAAI,KAChB,QAAQ,WAAW,CAAC,EAAA,CAAG,KAAK,WAAW;GACtC,MAAM,WAAW,aAAa,KAAK,MAAM,SAAS,QAAQ,OAAO,QAAQ,QAAQ,IAAI,GAAG,KAAK,IAAI;GACjG,OAAO,CAAC,GAAG,OAAO,SAAS,KAAK,IAAI,YAAY;IAAE,SAAS,OAAO;IAAS,OAAO;GAAS,CAAC;EAC9F,CAAC,CACH;EACA,MAAM,UAAgE,SAAS,CAAC,GAAG,OAAO,OAAO,CAAC,IAAI,MAAM,SAAS;EACrH,IAAI,CAAC,QAAQ,QAAQ,MAAM,IAAI,MAAM,yDAAyD;EAC9F,KAAK,MAAM,UAAU,SAAS;GAC5B,cAAc,OAAO,SAAS;GAC9B,IAAI,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,2FAA2F;GAChI,MAAM,WAAW,aAAa,OAAO,KAAK,MAAM,QAAQ,MAAM,iBAAiB,OAAO,KAAK,IAAI,KAAA;GAC/F,IAAI;IACF,MAAM,OAAO,QAAQ,SAAS,UAAU,QAAQ,OAAO,OAAO,EAAE,cAAc,KAAK,CAAC;GACtF,UAAU;IACR,MAAM,UAAU,QAAQ;GAC1B;EACF;EACA,MAAM,iBAAiB,IAAI,IAAI,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC;EACtE,MAAM,eAAe,CAAC,GAAG,IAAI,IAAI,QAAQ,SAAS,WAAW,OAAO,SAAS,QAAQ,CAAC,CAAC,CAAC,CAAC;EACzF,MAAM,OAAO,EAAE,QAAQ,UAAU,CAAC;EAElC,kBAAkB;GAChB,OAAO;GACP,QAAQ;GACR;GACA,OAAO;IACL,KAAK,UAAU,QAAQ,GAAG,UAAU,gBAAgB,eAAe,EAAE,WAAW;IAChF,KAAK,UAAU,OAAO,OAAO,EAAE,MAAM,UAAU,QAAQ,KAAK;IAC5D,KAAK,UAAU,OAAO,aAAa,WAAW,IAAI,YAAY,UAAU,EAAE,IAAI,aAAa,KAAK,IAAI;GACtG;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,MAAM,UAAU,QAAQ,KAAK,CAAC,CAAC;EAC/B,MAAM,iBAAiB,gBAAgB,uBAAuB,oEAAoE,KAAK,OAAO;EAC9I,kBAAkB;GAChB,OAAO,iBAAiB,uBAAuB;GAC/C,QAAQ;GACR;GACA,OAAO;IACL,KAAK,UAAU,OAAO,OAAO,EAAE,MAAM,UAAU,QAAQ,KAAK;IAC5D,KAAK,UAAU,OAAO,SAAS,EAAE,IAAI,eAAe,mBAAmB,iBAAiB,qBAAqB;IAC7G;IACA,UAAU,QAAQ,iBAAiB,qBAAqB,kBAAkB;IAC1E,KAAK,UAAU,OAAO,OAAO;IAC7B,GAAI,iBACA;KAAC;KAAI;KAAoB,UAAU,QAAQ,iCAAiC;KAAG,UAAU,QAAQ,8BAA8B;IAAC,IAChI,CAAC;GACP;EACF,CAAC;EAED,QAAQ,KAAK,CAAC;CAChB;AACF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
2
|
const require_errors = require("./errors-Cl69p_vI.cjs");
|
|
3
|
-
const require_Telemetry = require("./Telemetry-
|
|
4
|
-
const require_utils = require("./utils-
|
|
5
|
-
const require_text = require("./text-
|
|
3
|
+
const require_Telemetry = require("./Telemetry-D-IDgRfq.cjs");
|
|
4
|
+
const require_utils = require("./utils-Dju97QYB.cjs");
|
|
5
|
+
const require_text = require("./text-Sp4fptq1.cjs");
|
|
6
6
|
const require_config = require("./config-D63Gum4F.cjs");
|
|
7
|
-
const require_reporters = require("./reporters-
|
|
7
|
+
const require_reporters = require("./reporters-C4xq0GFT.cjs");
|
|
8
8
|
const require_credentials = require("./credentials-DDaKqtJn.cjs");
|
|
9
9
|
let node_util = require("node:util");
|
|
10
10
|
let node_os = require("node:os");
|
|
@@ -271,7 +271,7 @@ async function connect(options, context = {}) {
|
|
|
271
271
|
let unwatch;
|
|
272
272
|
try {
|
|
273
273
|
if (!context.prepared) {
|
|
274
|
-
const { getWorkerStatus } = await Promise.resolve().then(() => require("./background-
|
|
274
|
+
const { getWorkerStatus } = await Promise.resolve().then(() => require("./background-DY-7vFSm.cjs"));
|
|
275
275
|
if ((await getWorkerStatus()).running) throw new _kubb_core.Diagnostics.Error({
|
|
276
276
|
code: _kubb_core.Diagnostics.code.unknown,
|
|
277
277
|
severity: "error",
|
|
@@ -339,7 +339,7 @@ async function connect(options, context = {}) {
|
|
|
339
339
|
await hooks.callHook("kubb:lifecycle:end");
|
|
340
340
|
unwatch?.();
|
|
341
341
|
if (background) {
|
|
342
|
-
const { startWorker } = await Promise.resolve().then(() => require("./background-
|
|
342
|
+
const { startWorker } = await Promise.resolve().then(() => require("./background-DY-7vFSm.cjs"));
|
|
343
343
|
await startWorker(options);
|
|
344
344
|
if (options.logLevel !== "silent") require_text.logOutro("Running in the background · kubb studio stop");
|
|
345
345
|
return;
|
|
@@ -417,4 +417,4 @@ exports.login = login;
|
|
|
417
417
|
exports.prepareConnection = prepareConnection;
|
|
418
418
|
exports.runStudio = runStudio;
|
|
419
419
|
|
|
420
|
-
//# sourceMappingURL=run-
|
|
420
|
+
//# sourceMappingURL=run-C9EYgEqG.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-BszyZwY3.cjs","names":["process","isCIEnvironment","x","isCIEnvironment","process","createSpinner","pairAgent","path","process","hostname","getMachineId","styleText","isRichOutput","writeCredentials","getCredentialsPath","PairingCanceledError","AgentPermission","toPermissionFlag","KUBB_CONFIG_FILENAME","isCIEnvironment","canUseTTY","prompts","getConfigs","Diagnostics","readCredentials","Hookable","logLevelMap","cliReporter","plainWriter","connectAgent","InvalidAgentTokenError","clearCredentials","defaultStudioUrl","trackRun","toError"],"sources":["../../../internals/utils/src/copyToClipboard.ts","../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst COMMANDS: Partial<Record<NodeJS.Platform, [string, ...Array<string>]>> = {\n darwin: ['pbcopy'],\n win32: ['clip.exe'],\n linux: ['xclip', '-selection', 'clipboard'],\n}\n\n/**\n * Copies text to the system clipboard with the platform's own tool. Resolves `false` in CI, on a\n * platform without a known tool, or when the tool is missing or fails.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n // Wayland sessions have no X selection for xclip to serve, so they use `wl-copy`.\n const command = process.platform === 'linux' && process.env.WAYLAND_DISPLAY ? (['wl-copy'] as const) : COMMANDS[process.platform]\n if (!command || isCIEnvironment()) return false\n\n const [name, ...args] = command\n // stdout and stderr are ignored: xclip and wl-copy stay alive to serve the selection and would hold open pipes until the timeout.\n const run = x(name, args, { timeout: 2_000, nodeOptions: { stdio: ['pipe', 'ignore', 'ignore'] } })\n // A missing tool closes stdin before the write lands; the rejection below reports it.\n run.process?.stdin?.once('error', () => {})\n run.process?.stdin?.end(text)\n\n return run.then(\n ({ exitCode }) => exitCode === 0,\n () => false,\n )\n}\n","import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport { toPermissionFlag } from '../../ui/text.ts'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { copyToClipboard, isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Diagnostics, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { AgentPermission } from '@kubb/studio/protocol'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainWriter } from '../../loggers/plainWriter.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { logIntro, logOutro, logTip } from '../../ui/intro.ts'\nimport { logBlock, logStep } from '../../ui/log.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { canUseTTY, isRichOutput } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<AgentPermission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowReadAst?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // A retry notice stays on screen a while before the countdown takes the line back.\n let retryUntil = 0\n // The spinner only starts once a code is shown.\n let waiting = false\n let countdown: NodeJS.Timeout | undefined\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n logStep(\n [\n 'Pair this machine',\n `${styleText('dim', 'Open')} ${styleText('cyan', session.verification_uri)}`,\n `${styleText('dim', 'Code')} ${styleText('bold', session.user_code)}`,\n ].join('\\n'),\n )\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n // Same fallback as the poll in `@kubb/studio`, so the countdown ends when polling does.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let copied = false\n const waitingText = () =>\n `Waiting for approval ${styleText('dim', `expires in ${formatCountdown(deadline - Date.now())}${copied ? ' · code copied' : ''} · ctrl+c to cancel`)}`\n clearInterval(countdown)\n spinner.start(waitingText())\n waiting = true\n // Plain output prints every message, so only an animated spinner ticks.\n if (isRichOutput()) countdown = setInterval(() => Date.now() > retryUntil && spinner.message(waitingText()), 1000)\n // Not awaited: the code shows at once, and the spinner picks up the copy when it lands.\n void copyToClipboard(session.user_code).then((done) => {\n copied = done\n })\n },\n onRetry: (error) => {\n retryUntil = Date.now() + 5000\n spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`)\n },\n })\n clearInterval(countdown)\n spinner.stop(`Paired as ${agent.name}${agent.organizationSlug ? ` · org ${agent.organizationSlug}` : ''}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(agent.organizationSlug ? { organizationSlug: agent.organizationSlug } : {}),\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n clearInterval(countdown)\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/** Time left on a pairing code as `m:ss`, never below `0:00`. */\nexport function formatCountdown(ms: number): string {\n const seconds = Math.max(0, Math.ceil(ms / 1000))\n\n return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`\n}\n\n/**\n * What each permission is asked as, in the order the list shows them.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: AgentPermission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n title: (configPath: string) => string\n hint: string\n}> = [\n { key: AgentPermission.READ, label: 'read source', title: () => 'Read generated files', hint: 'show code in the browser' },\n { key: AgentPermission.READ_AST, label: 'read spec', title: () => 'Read the parsed spec', hint: 'browse schemas and operations' },\n { key: AgentPermission.WRITE, label: 'write files', title: () => 'Write files to disk', hint: 'generate from the browser' },\n { key: AgentPermission.CONFIG_EDIT, label: 'edit config', title: (configPath) => `Change ${configPath}`, hint: 'edit plugin options' },\n { key: AgentPermission.EXEC, label: 'run tools', title: () => 'Run the formatter, linter, and postGenerate', hint: 'after each generation' },\n]\n\n/**\n * Two permissions per row, each marked granted or not, with the flags that grant the missing ones\n * after the last row. For `kubb studio status`.\n */\nexport function formatPermissionRows(granted: Partial<Record<AgentPermission, boolean>>): Array<string> {\n const width = Math.max(...PERMISSIONS.map(({ label }) => label.length))\n const cells = PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✓') : styleText('red', '✖')} ${label.padEnd(width)}`)\n const rows = Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join(' '))\n const flags = PERMISSIONS.filter(({ key }) => !granted[key])\n .map(({ key }) => toPermissionFlag(key))\n .join(' ')\n\n return flags ? [...rows.slice(0, -1), `${rows.at(-1)} ${styleText('dim', flags)}`] : rows\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and the rest are asked in one list whose answers are stored\n * in `~/.kubb/credentials.json`.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n): Promise<Record<AgentPermission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted = Object.fromEntries(PERMISSIONS.map(({ key }) => [key, options.permission[key] || remembered?.[key] === true])) as Record<\n AgentPermission,\n boolean\n >\n const pending = PERMISSIONS.filter(({ key }) => !options.permission[key] && typeof remembered?.[key] !== 'boolean')\n\n if (!pending.length || isCIEnvironment() || !canUseTTY()) return granted\n\n prompts.updateSettings({ withGuide: true })\n const selected = await prompts.multiselect({\n message: 'What may Kubb Studio do in this project?',\n options: pending.map(({ key, title, hint }) => ({ value: key, label: title(configPath), hint })),\n required: false,\n })\n // A canceled list grants nothing and saves nothing, so the next run asks again.\n if (prompts.isCancel(selected)) return granted\n\n const answers = Object.fromEntries(pending.map(({ key }) => [key, selected.includes(key)]))\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n\n return { ...granted, ...answers }\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does, one entry per `defineConfig(...)` entry.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; configs: Array<Config> }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n\n if (!configs.length) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Config not defined, create a kubb.config.ts or pass it with --config',\n })\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, configs }\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const stored = await readCredentials()\n const credentials = await (async () => {\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Not paired with ${options.studioUrl}. In CI, run \\`kubb studio snapshot\\` instead, or run \\`kubb studio login\\` on a machine with a browser.`,\n })\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n let unwatch: (() => void) | undefined\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'This project is running in the background. Run `kubb studio stop` first.',\n })\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { writer: plainWriter } : {}),\n })\n // `b` hands the session to the background worker; only a foreground run in a terminal listens.\n const listens = !context.onState && process.stdin.isTTY === true && canUseTTY()\n let background = false\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (listens && !unwatch) {\n unwatch = watchKeys({\n onBackground: () => {\n background = true\n stop()\n },\n onStop: stop,\n })\n }\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock([\n `${styleText('dim', 'Project')} ${path.basename(process.cwd())} ${styleText(\n 'dim',\n PERMISSIONS.filter(({ key }) => permissions[key])\n .map(({ label }) => label)\n .join(' · ') || 'no permissions',\n )}`,\n styleText('dim', listens ? 'Press b to keep running in the background, Ctrl+C to disconnect' : 'Press Ctrl+C to disconnect'),\n ])\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfigs: async () => (await loadConfigs(options)).configs,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n await clearCredentials()\n if (pairedAgain) throw new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n\n // The pairing prompts need stdin back.\n unwatch?.()\n unwatch = undefined\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n // Stops the \"Ready for jobs\" spinner, which would otherwise keep drawing under the closing line.\n await hooks.callHook('kubb:lifecycle:end')\n unwatch?.()\n if (background) {\n const { startWorker } = await import('./background.ts')\n await startWorker(options)\n if (options.logLevel !== 'silent') logOutro('Running in the background · kubb studio stop')\n return\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n unwatch?.()\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Listens for single keys on a TTY stdin. Raw mode turns Ctrl+C into a key instead of SIGINT, so it\n * is handled here too. Returns the function that restores the terminal, safe to call twice.\n */\nexport function watchKeys({ onBackground, onStop }: { onBackground: () => void; onStop: () => void }): () => void {\n const stdin = process.stdin\n const onData = (data: Buffer) => {\n const key = data.toString()\n if (key === 'b' || key === 'B') onBackground()\n if (key === '\\u0003') onStop()\n }\n // A clack spinner reads stdin too and exits the process on Ctrl+C, before the session can close\n // its socket, so its Ctrl+C alias is lifted while these keys are read.\n const cancelAlias = prompts.settings.aliases.get('\\u0003')\n prompts.settings.aliases.delete('\\u0003')\n stdin.setRawMode(true)\n stdin.on('data', onData)\n stdin.resume()\n let restored = false\n\n return () => {\n if (restored) return\n restored = true\n if (cancelAlias) prompts.settings.aliases.set('\\u0003', cancelAlias)\n stdin.off('data', onData)\n stdin.setRawMode(false)\n stdin.pause()\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: Object.fromEntries(Object.values(AgentPermission).map((key) => [key, values[key] ?? false])) as Record<AgentPermission, boolean>,\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-C9EYgEqG.cjs","names":["process","isCIEnvironment","x","isCIEnvironment","process","createSpinner","pairAgent","path","process","hostname","getMachineId","styleText","isRichOutput","writeCredentials","getCredentialsPath","PairingCanceledError","AgentPermission","toPermissionFlag","KUBB_CONFIG_FILENAME","isCIEnvironment","canUseTTY","prompts","getConfigs","Diagnostics","readCredentials","Hookable","logLevelMap","cliReporter","plainWriter","connectAgent","InvalidAgentTokenError","clearCredentials","defaultStudioUrl","trackRun","toError"],"sources":["../../../internals/utils/src/copyToClipboard.ts","../../../internals/utils/src/openInBrowser.ts","../src/runners/studio/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst COMMANDS: Partial<Record<NodeJS.Platform, [string, ...Array<string>]>> = {\n darwin: ['pbcopy'],\n win32: ['clip.exe'],\n linux: ['xclip', '-selection', 'clipboard'],\n}\n\n/**\n * Copies text to the system clipboard with the platform's own tool. Resolves `false` in CI, on a\n * platform without a known tool, or when the tool is missing or fails.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n // Wayland sessions have no X selection for xclip to serve, so they use `wl-copy`.\n const command = process.platform === 'linux' && process.env.WAYLAND_DISPLAY ? (['wl-copy'] as const) : COMMANDS[process.platform]\n if (!command || isCIEnvironment()) return false\n\n const [name, ...args] = command\n // stdout and stderr are ignored: xclip and wl-copy stay alive to serve the selection and would hold open pipes until the timeout.\n const run = x(name, args, { timeout: 2_000, nodeOptions: { stdio: ['pipe', 'ignore', 'ignore'] } })\n // A missing tool closes stdin before the write lands; the rejection below reports it.\n run.process?.stdin?.once('error', () => {})\n run.process?.stdin?.end(text)\n\n return run.then(\n ({ exitCode }) => exitCode === 0,\n () => false,\n )\n}\n","import process from 'node:process'\nimport { x } from 'tinyexec'\nimport { isCIEnvironment } from './isCIEnvironment.ts'\n\nconst ignore = () => {}\n\n/**\n * Opens a URL or local file in the default browser, unless running in CI.\n */\nexport function openInBrowser(target: string): void {\n if (isCIEnvironment()) return\n\n if (process.platform === 'win32') {\n x('cmd', ['/c', 'start', '', target]).then(ignore, ignore)\n return\n }\n x(process.platform === 'darwin' ? 'open' : 'xdg-open', [target]).then(ignore, ignore)\n}\n","import { hostname } from 'node:os'\nimport { toPermissionFlag } from '../../ui/text.ts'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport * as prompts from '@clack/prompts'\nimport { KUBB_CONFIG_FILENAME } from '@internals/shared'\nimport { copyToClipboard, isCIEnvironment, openInBrowser, toError } from '@internals/utils'\nimport type { CLIOptions, Config } from '@kubb/core'\nimport { cliReporter, Diagnostics, Hookable, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'\nimport { connectAgent, defaultStudioUrl, InvalidAgentTokenError, pairAgent, PairingCanceledError } from '@kubb/studio'\nimport { AgentPermission } from '@kubb/studio/protocol'\nimport { trackRun } from '../../Telemetry.ts'\nimport { plainWriter } from '../../loggers/plainWriter.ts'\nimport setupReporters from '../../loggers/reporters.ts'\nimport { logIntro, logOutro, logTip } from '../../ui/intro.ts'\nimport { logBlock, logStep } from '../../ui/log.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { canUseTTY, isRichOutput } from '../../utils/env.ts'\nimport { getConfigs } from '../../config.ts'\nimport { clearCredentials, type Credentials, getCredentialsPath, getMachineId, readCredentials, writeCredentials } from './credentials.ts'\nimport { version } from '../../../package.json'\n\nexport type StudioOptions = {\n /**\n * Current `@kubb/cli` version, reported to Studio and used for the telemetry payload.\n */\n version: string\n configPath?: string\n /**\n * Base URL of the Studio instance, for a self-hosted deployment. Resolved before it reaches here,\n * since stored credentials are bound to it.\n */\n studioUrl: string\n /**\n * What Studio may do in this project. Each flag grants outright; the rest are asked once per\n * project through {@link resolvePermissions}.\n */\n permission: Record<AgentPermission, boolean>\n /**\n * Whether to open the approval page in a browser during pairing.\n */\n autoOpen: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\nexport type SnapshotOptions = Pick<StudioOptions, 'configPath' | 'studioUrl' | 'logLevel'> & {\n /**\n * Organization CI API key. Falls back to `KUBB_TOKEN`.\n */\n token?: string\n /**\n * Stable identity for the CI agent. Falls back to CI auto-detection.\n */\n id?: string\n /** Identity of another CI agent to also compare with. Falls back to CI auto-detection. */\n baseId?: string\n /**\n * Package name for the generated tarball. Falls back to the nearest package.json.\n */\n name?: string\n /**\n * Package version for the generated tarball. Falls back to the nearest package.json.\n */\n packageVersion?: string\n /**\n * Print the result as one JSON object instead of a summary.\n */\n json?: boolean\n}\n\n/** The flags a `kubb studio` subcommand parsed; each one is optional since a subcommand declares only the flags it uses. */\nexport type StudioValues = {\n config?: string\n url?: string\n allowRead?: boolean\n allowReadAst?: boolean\n allowWrite?: boolean\n allowConfigEdit?: boolean\n allowExec?: boolean\n open?: boolean\n logLevel?: CLIOptions['logLevel']\n}\n\ntype LoginOptions = {\n /**\n * Aborting this cancels an in-flight pairing request or poll and rejects with\n * {@link PairingCanceledError}. Wired to `kubb studio`'s shutdown signal, so Ctrl+C during\n * pairing cancels it instead of leaving the poll running.\n */\n signal?: AbortSignal\n /**\n * Credentials from before this login. When the fresh pairing resolves to the same agent on the\n * same Studio, its saved project permissions carry forward instead of being asked again.\n * Left out for an explicitly requested `kubb studio login`, which always starts clean.\n */\n previousCredentials?: Credentials | null\n}\n\n/**\n * Pairs this machine with Studio and stores the resulting token.\n *\n * The CLI holds a code and the browser approves it, rather than the user copying a token out of\n * the UI. The token comes back over the CLI's own HTTPS POST, so it never lands in a URL, a\n * server log, or a `Referer` header.\n */\nexport async function login({ studioUrl, autoOpen }: StudioOptions, { signal, previousCredentials }: LoginOptions = {}): Promise<Credentials> {\n const spinner = createSpinner()\n // A retry notice stays on screen a while before the countdown takes the line back.\n let retryUntil = 0\n // The spinner only starts once a code is shown.\n let waiting = false\n let countdown: NodeJS.Timeout | undefined\n\n try {\n const { token, agent } = await pairAgent({\n studioUrl,\n type: 'cli',\n name: path.basename(process.cwd()),\n hostname: hostname(),\n machineId: await getMachineId(),\n signal,\n onCode: (session) => {\n logStep(\n [\n 'Pair this machine',\n `${styleText('dim', 'Open')} ${styleText('cyan', session.verification_uri)}`,\n `${styleText('dim', 'Code')} ${styleText('bold', session.user_code)}`,\n ].join('\\n'),\n )\n\n if (autoOpen) {\n openInBrowser(session.verification_uri_complete)\n }\n\n // Same fallback as the poll in `@kubb/studio`, so the countdown ends when polling does.\n const deadline = Date.now() + (session.expires_in > 0 ? session.expires_in : 600) * 1000\n let copied = false\n const waitingText = () =>\n `Waiting for approval ${styleText('dim', `expires in ${formatCountdown(deadline - Date.now())}${copied ? ' · code copied' : ''} · ctrl+c to cancel`)}`\n clearInterval(countdown)\n spinner.start(waitingText())\n waiting = true\n // Plain output prints every message, so only an animated spinner ticks.\n if (isRichOutput()) countdown = setInterval(() => Date.now() > retryUntil && spinner.message(waitingText()), 1000)\n // Not awaited: the code shows at once, and the spinner picks up the copy when it lands.\n void copyToClipboard(session.user_code).then((done) => {\n copied = done\n })\n },\n onRetry: (error) => {\n retryUntil = Date.now() + 5000\n spinner.message(`Could not reach Kubb Studio, retrying: ${error.message}`)\n },\n })\n clearInterval(countdown)\n spinner.stop(`Paired as ${agent.name}${agent.organizationSlug ? ` · org ${agent.organizationSlug}` : ''}`)\n\n const keepsIdentity = previousCredentials?.studioUrl === studioUrl && previousCredentials.agentId === agent.id\n const credentials: Credentials = {\n studioUrl,\n token,\n agentId: agent.id,\n agentSlug: agent.slug,\n ...(agent.organizationSlug ? { organizationSlug: agent.organizationSlug } : {}),\n ...(keepsIdentity && previousCredentials?.projects ? { projects: previousCredentials.projects } : {}),\n }\n await writeCredentials(credentials)\n\n console.log(`Credentials stored in ${getCredentialsPath()}`)\n\n return credentials\n } catch (error) {\n clearInterval(countdown)\n if (waiting) {\n spinner.stop(error instanceof PairingCanceledError ? 'Pairing canceled' : 'Pairing failed')\n }\n throw error\n }\n}\n\n/** Time left on a pairing code as `m:ss`, never below `0:00`. */\nexport function formatCountdown(ms: number): string {\n const seconds = Math.max(0, Math.ceil(ms / 1000))\n\n return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`\n}\n\n/**\n * What each permission is asked as, in the order the list shows them.\n */\nconst PERMISSIONS: ReadonlyArray<{\n key: AgentPermission\n /**\n * Short label for status output and the connect summary.\n */\n label: string\n title: (configPath: string) => string\n hint: string\n}> = [\n { key: AgentPermission.READ, label: 'read source', title: () => 'Read generated files', hint: 'show code in the browser' },\n { key: AgentPermission.READ_AST, label: 'read spec', title: () => 'Read the parsed spec', hint: 'browse schemas and operations' },\n { key: AgentPermission.WRITE, label: 'write files', title: () => 'Write files to disk', hint: 'generate from the browser' },\n { key: AgentPermission.CONFIG_EDIT, label: 'edit config', title: (configPath) => `Change ${configPath}`, hint: 'edit plugin options' },\n { key: AgentPermission.EXEC, label: 'run tools', title: () => 'Run the formatter, linter, and postGenerate', hint: 'after each generation' },\n]\n\n/**\n * Two permissions per row, each marked granted or not, with the flags that grant the missing ones\n * after the last row. For `kubb studio status`.\n */\nexport function formatPermissionRows(granted: Partial<Record<AgentPermission, boolean>>): Array<string> {\n const width = Math.max(...PERMISSIONS.map(({ label }) => label.length))\n const cells = PERMISSIONS.map(({ key, label }) => `${granted[key] ? styleText('green', '✓') : styleText('red', '✖')} ${label.padEnd(width)}`)\n const rows = Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join(' '))\n const flags = PERMISSIONS.filter(({ key }) => !granted[key])\n .map(({ key }) => toPermissionFlag(key))\n .join(' ')\n\n return flags ? [...rows.slice(0, -1), `${rows.at(-1)} ${styleText('dim', flags)}`] : rows\n}\n\n/**\n * Resolves Studio permissions for the current project.\n * Flags win, saved answers are reused, and the rest are asked in one list whose answers are stored\n * in `~/.kubb/credentials.json`.\n */\nexport async function resolvePermissions(\n options: StudioOptions,\n credentials: Credentials,\n configPath: string = KUBB_CONFIG_FILENAME,\n): Promise<Record<AgentPermission, boolean>> {\n const project = process.cwd()\n const remembered = credentials.projects?.[project]\n const granted = Object.fromEntries(PERMISSIONS.map(({ key }) => [key, options.permission[key] || remembered?.[key] === true])) as Record<\n AgentPermission,\n boolean\n >\n const pending = PERMISSIONS.filter(({ key }) => !options.permission[key] && typeof remembered?.[key] !== 'boolean')\n\n if (!pending.length || isCIEnvironment() || !canUseTTY()) return granted\n\n prompts.updateSettings({ withGuide: true })\n const selected = await prompts.multiselect({\n message: 'What may Kubb Studio do in this project?',\n options: pending.map(({ key, title, hint }) => ({ value: key, label: title(configPath), hint })),\n required: false,\n })\n // A canceled list grants nothing and saves nothing, so the next run asks again.\n if (prompts.isCancel(selected)) return granted\n\n const answers = Object.fromEntries(pending.map(({ key }) => [key, selected.includes(key)]))\n await writeCredentials({\n ...credentials,\n projects: { ...credentials.projects, [project]: { ...remembered, ...answers } },\n })\n\n return { ...granted, ...answers }\n}\n\n/**\n * Loads the project's Kubb config the same way `kubb generate` does, one entry per `defineConfig(...)` entry.\n */\nexport async function loadConfigs(options: Pick<StudioOptions, 'configPath' | 'logLevel'>): Promise<{ configPath: string; configs: Array<Config> }> {\n const { configPath, configs } = await getConfigs({ configPath: options.configPath, logLevel: options.logLevel })\n\n if (!configs.length) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Config not defined, create a kubb.config.ts or pass it with --config',\n })\n }\n\n // `getConfigs` resolves this to an absolute path. Relativized here, once, so the permission\n // prompt and the path Studio receives over the wire both show the project-relative form instead\n // of leaking the local filesystem layout.\n return { configPath: path.relative(process.cwd(), configPath) || configPath, configs }\n}\n\nexport type PreparedConnection = {\n configPath: string\n credentials: Credentials\n permissions: StudioOptions['permission']\n}\n\n/** Validates the project and resolves pairing and permissions before starting its worker. */\nexport async function prepareConnection(options: StudioOptions, signal?: AbortSignal): Promise<PreparedConnection> {\n const { configPath } = await loadConfigs(options)\n const stored = await readCredentials()\n const credentials = await (async () => {\n if (stored?.studioUrl === options.studioUrl) return stored\n if (isCIEnvironment()) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Not paired with ${options.studioUrl}. In CI, run \\`kubb studio snapshot\\` instead, or run \\`kubb studio login\\` on a machine with a browser.`,\n })\n }\n return login(options, { signal })\n })()\n const permissions = await resolvePermissions(options, credentials, configPath)\n return { configPath, credentials, permissions }\n}\n\nexport type WorkerState = 'starting' | 'connected' | 'reconnecting' | 'authentication required' | 'stopped'\n\n/** Runs the same project connection in the foreground or in a background worker. */\nexport async function connect(\n options: StudioOptions,\n context: {\n prepared?: PreparedConnection\n signal?: AbortSignal\n onState?: (state: WorkerState) => void | Promise<void>\n } = {},\n): Promise<void> {\n const shutdown = new AbortController()\n const signal = context.signal ?? shutdown.signal\n const stop = () => shutdown.abort()\n const events = process as unknown as NodeJS.EventEmitter\n if (!context.signal) {\n events.once('SIGINT', stop)\n events.once('SIGTERM', stop)\n }\n let unwatch: (() => void) | undefined\n try {\n if (!context.prepared) {\n const { getWorkerStatus } = await import('./background.ts')\n const worker = await getWorkerStatus()\n if (worker.running)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'This project is running in the background. Run `kubb studio stop` first.',\n })\n }\n const prepared = context.prepared ?? (await prepareConnection(options, signal))\n let { credentials, permissions } = prepared\n const { configPath } = prepared\n let hinted = false\n // Set by a fresh pairing until it connects, so a token rejected right after approval fails the run instead of looping.\n let pairedAgain = false\n\n // The background worker writes to a log file, so it gets the plain logger rather than the\n // animated one. The logger also covers the `studio:*` events and each generation run.\n const hooks = new Hookable<KubbHooks>()\n setupReporters(hooks, {\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n reporters: [cliReporter],\n ...(context.onState ? { writer: plainWriter } : {}),\n })\n // `b` hands the session to the background worker; only a foreground run in a terminal listens.\n const listens = !context.onState && process.stdin.isTTY === true && canUseTTY()\n let background = false\n hooks.hook('studio:connected', async () => {\n pairedAgain = false\n await context.onState?.('connected')\n if (listens && !unwatch) {\n unwatch = watchKeys({\n onBackground: () => {\n background = true\n stop()\n },\n onStop: stop,\n })\n }\n if (hinted || context.onState || options.logLevel === 'silent') return\n hinted = true\n logBlock([\n `${styleText('dim', 'Project')} ${path.basename(process.cwd())} ${styleText(\n 'dim',\n PERMISSIONS.filter(({ key }) => permissions[key])\n .map(({ label }) => label)\n .join(' · ') || 'no permissions',\n )}`,\n styleText('dim', listens ? 'Press b to keep running in the background, Ctrl+C to disconnect' : 'Press Ctrl+C to disconnect'),\n ])\n logTip()\n })\n hooks.hook('studio:reconnecting', () => context.onState?.('reconnecting'))\n\n for (;;) {\n try {\n await connectAgent({\n token: credentials.token,\n studioUrl: options.studioUrl,\n configPath,\n version: options.version,\n root: process.cwd(),\n permissions,\n loadConfigs: async () => (await loadConfigs(options)).configs,\n hooks,\n signal,\n })\n break\n } catch (error) {\n if (!(error instanceof InvalidAgentTokenError)) throw error\n await context.onState?.('authentication required')\n await clearCredentials()\n if (pairedAgain) throw new Error(`${error.message} Studio rejected the newly approved token too. Run \\`kubb studio login\\` and try again.`)\n if (context.onState || isCIEnvironment() || !canUseTTY()) throw new Error(`${error.message} Run \\`kubb studio login\\` to pair again.`)\n\n // The pairing prompts need stdin back.\n unwatch?.()\n unwatch = undefined\n console.log(styleText('yellow', `${error.message} Pairing again...`))\n credentials = await login(options, { signal, previousCredentials: credentials })\n pairedAgain = true\n permissions = await resolvePermissions(options, credentials, configPath)\n }\n }\n // Stops the \"Ready for jobs\" spinner, which would otherwise keep drawing under the closing line.\n await hooks.callHook('kubb:lifecycle:end')\n unwatch?.()\n if (background) {\n const { startWorker } = await import('./background.ts')\n await startWorker(options)\n if (options.logLevel !== 'silent') logOutro('Running in the background · kubb studio stop')\n return\n }\n if (!context.onState && signal.aborted && options.logLevel !== 'silent') logOutro('Disconnected')\n } catch (error) {\n if (!(error instanceof PairingCanceledError)) throw error\n } finally {\n unwatch?.()\n events.off('SIGINT', stop)\n events.off('SIGTERM', stop)\n }\n}\n\n/**\n * Listens for single keys on a TTY stdin. Raw mode turns Ctrl+C into a key instead of SIGINT, so it\n * is handled here too. Returns the function that restores the terminal, safe to call twice.\n */\nexport function watchKeys({ onBackground, onStop }: { onBackground: () => void; onStop: () => void }): () => void {\n const stdin = process.stdin\n const onData = (data: Buffer) => {\n const key = data.toString()\n if (key === 'b' || key === 'B') onBackground()\n if (key === '\\u0003') onStop()\n }\n // A clack spinner reads stdin too and exits the process on Ctrl+C, before the session can close\n // its socket, so its Ctrl+C alias is lifted while these keys are read.\n const cancelAlias = prompts.settings.aliases.get('\\u0003')\n prompts.settings.aliases.delete('\\u0003')\n stdin.setRawMode(true)\n stdin.on('data', onData)\n stdin.resume()\n let restored = false\n\n return () => {\n if (restored) return\n restored = true\n if (cancelAlias) prompts.settings.aliases.set('\\u0003', cancelAlias)\n stdin.off('data', onData)\n stdin.setRawMode(false)\n stdin.pause()\n }\n}\n\n/**\n * Runs a Studio command from its parsed flags: builds the {@link StudioOptions}, prints the intro,\n * and reports the run to telemetry. A failure is printed and sets the exit code instead of throwing.\n */\nexport async function runStudio(\n values: StudioValues,\n action: (options: StudioOptions) => Promise<unknown>,\n { block = false, json = false }: { block?: boolean; json?: boolean } = {},\n): Promise<void> {\n const options: StudioOptions = {\n version,\n configPath: values.config,\n studioUrl: values.url ?? defaultStudioUrl,\n permission: Object.fromEntries(Object.values(AgentPermission).map((key) => [key, values[key] ?? false])) as Record<AgentPermission, boolean>,\n autoOpen: values.open ?? true,\n logLevel: values.logLevel,\n }\n const report = trackRun({ command: 'studio', hrStart: process.hrtime() })\n\n try {\n if (options.logLevel !== 'silent' && !json) {\n logIntro({\n warning: styleText('yellow', 'This feature is still under development, use with caution'),\n block,\n })\n }\n\n await action(options)\n\n await report({ status: 'success' })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
|
-
import { a as getElapsedMs, i as formatMs, n as trackRun, r as version } from "./Telemetry-
|
|
3
|
-
import {
|
|
4
|
-
import { a as logOutro, d as logStep, i as logIntro, l as logError, m as createPlainWriter, o as logSpacer, s as logTip, t as pluralize, u as logInfo } from "./text-
|
|
5
|
-
import { d as logBanner, o as isOutdated } from "./registry-
|
|
2
|
+
import { a as getElapsedMs, i as formatMs, n as trackRun, r as version } from "./Telemetry-wyeU72_v.js";
|
|
3
|
+
import { c as createSpinner, i as listenForKeys, o as startWatcher, s as trackBuild, t as diffBuilds } from "./utils-BDDF8GOv.js";
|
|
4
|
+
import { a as logOutro, d as logStep, f as logWarn, i as logIntro, l as logError, m as createPlainWriter, o as logSpacer, s as logTip, t as pluralize, u as logInfo } from "./text-DgzXienb.js";
|
|
5
|
+
import { d as logBanner, o as isOutdated } from "./registry-BS1M25zz.js";
|
|
6
6
|
import { t as getConfigs } from "./config-Bh00Hwpw.js";
|
|
7
|
-
import { n as setupReporters, t as selectReporters } from "./reporters-
|
|
7
|
+
import { n as setupReporters, t as selectReporters } from "./reporters-BXNKLBLf.js";
|
|
8
8
|
import { styleText } from "node:util";
|
|
9
9
|
import process from "node:process";
|
|
10
10
|
import path from "node:path";
|
|
@@ -144,10 +144,9 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
144
144
|
let queue = Promise.resolve();
|
|
145
145
|
for (const config of configs) {
|
|
146
146
|
const effectiveInput = input ?? config.input;
|
|
147
|
-
const
|
|
148
|
-
const watchPath = inputKind === "file" || inputKind === "url" ? effectiveInput : void 0;
|
|
147
|
+
const watchPath = (typeof effectiveInput === "string" ? getInputKind(effectiveInput) : void 0) === "file" ? effectiveInput : void 0;
|
|
149
148
|
if (watchPath && tracker) {
|
|
150
|
-
const label = styleText("yellow", `Watching ${
|
|
149
|
+
const label = styleText("yellow", `Watching ${path.relative(process.cwd(), watchPath)}`);
|
|
151
150
|
let previous;
|
|
152
151
|
const build = async () => {
|
|
153
152
|
const hrStart = process.hrtime();
|
|
@@ -185,29 +184,24 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
185
184
|
rebuild: () => rebuilds.forEach((trigger) => void trigger()),
|
|
186
185
|
quit: (code) => void Promise.resolve(hooks.callHook("kubb:lifecycle:end")).finally(() => process.exit(code))
|
|
187
186
|
});
|
|
188
|
-
const initialBody = inputKind === "url" ? await fetchUrlBody(watchPath) : void 0;
|
|
189
187
|
await rebuild();
|
|
190
|
-
|
|
191
|
-
log: {
|
|
192
|
-
info: logInfo,
|
|
193
|
-
error: logError
|
|
194
|
-
},
|
|
195
|
-
initialBody
|
|
196
|
-
});
|
|
197
|
-
else await startWatcher([watchPath], rebuild, {
|
|
188
|
+
await startWatcher([watchPath], rebuild, {
|
|
198
189
|
info: logInfo,
|
|
199
190
|
error: logError
|
|
200
191
|
});
|
|
201
|
-
} else
|
|
202
|
-
if (!
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
192
|
+
} else {
|
|
193
|
+
if (tracker && !quiet) logWarn("Watch mode only follows a local `input` file, so this config is generated once.");
|
|
194
|
+
try {
|
|
195
|
+
if (!await generate({
|
|
196
|
+
input,
|
|
197
|
+
config,
|
|
198
|
+
hooks,
|
|
199
|
+
dryRun
|
|
200
|
+
})) anyFailed = true;
|
|
201
|
+
} catch (configError) {
|
|
202
|
+
await Diagnostics.emit(errorHooks, configError);
|
|
203
|
+
anyFailed = true;
|
|
204
|
+
}
|
|
211
205
|
}
|
|
212
206
|
}
|
|
213
207
|
await hooks.callHook("kubb:lifecycle:end");
|
|
@@ -221,4 +215,4 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
221
215
|
//#endregion
|
|
222
216
|
export { generate, run };
|
|
223
217
|
|
|
224
|
-
//# sourceMappingURL=run-
|
|
218
|
+
//# sourceMappingURL=run-CuRCXhQb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-CuRCXhQb.js","names":["logLevel","logLevelMap"],"sources":["../src/runners/generate/run.ts"],"sourcesContent":["import path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, formatters, getElapsedMs, linters } from '@internals/utils'\nimport {\n Hookable,\n type CLIOptions,\n cliReporter,\n type Config,\n createKubb,\n Diagnostics,\n fileReporter,\n getInputKind,\n htmlReporter,\n jsonReporter,\n type KubbHooks,\n logLevel as logLevelMap,\n memoryStorage,\n type ReporterName,\n} from '@kubb/core'\nimport { version } from '../../../package.json'\nimport { trackRun } from '../../Telemetry.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport setupReporters, { selectReporters } from '../../loggers/reporters.ts'\nimport { createPlainWriter } from '../../loggers/plainWriter.ts'\nimport { logIntro, logOutro, logSpacer, logTip } from '../../ui/intro.ts'\nimport { logError, logInfo, logStep, logWarn } from '../../ui/log.ts'\nimport { logBanner } from '../../ui/mascot.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { getConfigs } from '../../config.ts'\nimport { isOutdated } from '../../utils/registry.ts'\nimport { type BuildDiff, type BuildSnapshot, diffBuilds, listenForKeys, startWatcher, trackBuild } from './utils.ts'\n\n/** NPM registry endpoint used to check for @kubb/cli updates. */\nconst KUBB_NPM_PACKAGE_URL = 'https://registry.npmjs.org/@kubb/cli/latest' as const\n\n/** Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run. */\nconst UPDATE_CHECK_TIMEOUT_MS = 3_000\n\n/** The formatter names from `Config['output'].format`, without `'auto'` (detection, not a tool) and `false` (skip). */\ntype FormatterName = Exclude<NonNullable<Config['output']['format']>, 'auto' | false>\ntype LinterName = Exclude<NonNullable<Config['output']['lint']>, 'auto' | false>\n\n// Pinned here, not in `@internals/utils` (which must not import `@kubb/core`): a tool added to the union without a descriptor fails to compile.\nformatters satisfies Record<FormatterName, unknown>\nlinters satisfies Record<LinterName, unknown>\n\ntype GenerateProps = {\n input?: string\n config: Config\n hooks: Hookable<KubbHooks>\n /**\n * When `true`, generates in memory instead of writing to disk, skips formatting, linting, and\n * post-generate commands, and prints what would change on disk.\n */\n dryRun?: boolean\n}\n\nexport async function generate(options: GenerateProps): Promise<boolean> {\n const { input, hooks, dryRun = false } = options\n\n const report = trackRun({ command: 'generate', hrStart: process.hrtime() })\n\n const config: Config = {\n ...options.config,\n input: input ?? options.config.input,\n // Dry-run never touches disk, regardless of the config's own storage driver.\n storage: dryRun ? memoryStorage() : options.config.storage,\n // Also keeps core's `hasOutputPasses` false, so dry-run skips the output manifest write too.\n output: dryRun ? { ...options.config.output, format: false, lint: false, postGenerate: [] } : options.config.output,\n }\n\n // Core formats, lints and runs `output.postGenerate` after an error-free build, and reports\n // their failures as coded diagnostics that reach the summary, the json report and the exit code.\n const kubb = createKubb(config, { hooks })\n const result = await kubb.generate()\n\n await report({\n // A setup that threw leaves no driver, so read the configured plugins instead.\n plugins: kubb.config.plugins.flatMap((p) =>\n p && typeof p === 'object' ? [{ name: p.meta?.name ?? p.name ?? '', options: (p.options ?? {}) as Record<string, unknown> }] : [],\n ),\n filesCreated: result.files.length,\n status: result.success ? 'success' : 'failed',\n })\n\n return result.success\n}\n\ntype GenerateCommandOptions = {\n input?: string\n configPath?: string\n logLevel: string\n watch: boolean\n reporters?: Array<ReporterName>\n dryRun?: boolean\n}\n\n/** The latest published version, `undefined` when the registry does not answer in time. Never rejects. */\nasync function fetchLatestVersion(): Promise<string | undefined> {\n try {\n const res = await fetch(KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(UPDATE_CHECK_TIMEOUT_MS) })\n const data = (await res.json()) as { version: string }\n return data.version\n } catch {\n // Ignore network errors\n return undefined\n }\n}\n\nasync function checkForUpdate({ hooks, latest }: { hooks: Hookable<KubbHooks>; latest: Promise<string | undefined> }): Promise<void> {\n const latestVersion = await latest\n if (latestVersion && isOutdated({ installed: version, latest: latestVersion })) {\n await Diagnostics.emit(hooks, Diagnostics.update({ currentVersion: version, latestVersion }))\n }\n}\n\n/** Prints `Rebuilt in 1.2s · +1 schema -2 operations`, without the names part when the spec kept the same names. */\nfunction logRebuild({ diff: { schemas, operations }, durationMs }: { diff: BuildDiff; durationMs: number }): void {\n const specChange = [\n schemas.added && styleText('green', `+${pluralize(schemas.added, 'schema')}`),\n schemas.removed && styleText('red', `-${pluralize(schemas.removed, 'schema')}`),\n operations.added && styleText('green', `+${pluralize(operations.added, 'operation')}`),\n operations.removed && styleText('red', `-${pluralize(operations.removed, 'operation')}`),\n ]\n .filter(Boolean)\n .join(' ')\n logStep([`Rebuilt in ${formatMs(durationMs)}`, specChange].filter(Boolean).join(styleText('dim', ' · ')))\n}\n\n/**\n * Runs the full Kubb generation lifecycle for the given CLI options.\n * Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),\n * checks for a newer version, and calls `generate` for each config entry.\n */\nexport async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }: GenerateCommandOptions): Promise<void> {\n // Started first so the registry request overlaps the banner and the config load.\n const latest = fetchLatestVersion()\n const logLevel = logLevelMap[logLevelKey as keyof typeof logLevelMap] ?? logLevelMap.info\n const hooks = new Hookable<KubbHooks>()\n\n // CLI `--reporter` selects which reporters to trigger by name, defaulting to `cli`. `defineConfig`\n // registers the built-in reporters on the config; a config exported without it falls back to them below.\n const requestedNames: Array<ReporterName> = cliReporters?.length ? cliReporters : ['cli']\n\n // The `json` reporter owns stdout, so the command writes nothing of its own around it.\n const json = requestedNames.includes('json')\n const quiet = logLevel <= logLevelMap.silent || json\n\n // Errors raised outside a build have no report entry. In `json` mode they go to a stderr logger,\n // so they are never silent and stdout stays one JSON document.\n const errorHooks = json ? new Hookable<KubbHooks>() : hooks\n if (json) setupReporters(errorHooks, { logLevel, reporters: [cliReporter], writer: createPlainWriter(console.error) })\n\n // The config loads while the banner plays; the output still prints in order once the banner is done.\n const banner = quiet ? undefined : logBanner(version)\n const loading = getConfigs({\n configPath,\n input,\n watch,\n logLevel: logLevelKey as CLIOptions['logLevel'],\n })\n // Handled below; this keeps a rejection during the banner from counting as unhandled.\n loading.catch(() => undefined)\n await banner\n\n if (!quiet) {\n logIntro({ title: 'Configuration' })\n }\n\n // Load the config first so `config.reporters` can pick the reporters. A failure here has no\n // reporter installed yet, so fall back to the default `cli` reporter to surface it.\n const configSpinner = createSpinner()\n let configs: Array<Config>\n let resolvedConfigPath: string\n try {\n if (!quiet) configSpinner.start('Loading config')\n\n const loaded = await loading\n configs = loaded.configs\n resolvedConfigPath = loaded.configPath\n\n if (!quiet) configSpinner.stop(`Loaded ${styleText('dim', path.relative(process.cwd(), resolvedConfigPath))}`)\n } catch (error) {\n if (!quiet) configSpinner.error('Config failed loading')\n\n if (!json) setupReporters(hooks, { logLevel, reporters: [cliReporter] })\n // A diagnostic thrown while the config file runs, such as invalid extension options, sits in the cause chain.\n await Diagnostics.emit(errorHooks, error)\n\n if (!quiet) logOutro(styleText('red', '✗ Configuration failed'))\n process.exit(1)\n }\n\n // Without a reporter nothing is printed, not even an error, so a config written without\n // `defineConfig` gets the same built-ins it would have registered.\n const available = configs[0]?.reporters?.length ? configs[0].reporters : [cliReporter, jsonReporter, fileReporter, htmlReporter]\n const reporters = selectReporters(available, requestedNames)\n setupReporters(hooks, { logLevel, reporters, dryRun })\n\n await hooks.callHook('kubb:lifecycle:start', { version })\n\n // Inside the bootstrap group, so an update notice reads as part of the setup rather than as part\n // of the first config's generation.\n await checkForUpdate({ hooks, latest })\n\n if (!quiet) logOutro(`${pluralize(configs.length, 'config')} ready`)\n\n try {\n let anyFailed = false\n // One tracker, one key listener and one build queue serve every watched config, so several configs never mix diffs or answer `r` twice.\n const tracker = watch ? trackBuild(hooks) : undefined\n const rebuilds: Array<() => Promise<void>> = []\n let armKeys: (() => void) | undefined\n // Configs share the hooks emitter, so every build, from any watcher or the `r` key, waits for the one before it.\n let queue = Promise.resolve()\n for (const config of configs) {\n const effectiveInput = input ?? config.input\n const inputKind = typeof effectiveInput === 'string' ? getInputKind(effectiveInput) : undefined\n const watchPath = inputKind === 'file' ? (effectiveInput as string) : undefined\n if (watchPath && tracker) {\n const label = styleText('yellow', `Watching ${path.relative(process.cwd(), watchPath)}`)\n let previous: BuildSnapshot | undefined\n // Don't removeAll() between builds, that would also drop logger and lifecycle\n // listeners. Plugin listeners are already disposed by safeBuild's dispose()\n // in its finally block, so re-running generate() on the same hooks emitter is safe.\n const build = async () => {\n const hrStart = process.hrtime()\n const succeeded = await generate({ input, config, hooks, dryRun })\n const snapshot = tracker.take()\n if (previous) logRebuild({ diff: diffBuilds(previous, snapshot), durationMs: getElapsedMs(hrStart) })\n previous = snapshot\n\n logStep(armKeys ? `${label} ${styleText('dim', 'r rebuild · q quit')}` : label)\n armKeys?.()\n if (succeeded) {\n logSpacer()\n logTip()\n }\n }\n // A trigger that lands while this config's build is queued joins it; one that lands during the build queues one more. Never rejects.\n let pending = false\n const rebuild = (): Promise<void> => {\n if (pending) return queue\n pending = true\n queue = queue\n .then(() => {\n pending = false\n return build()\n })\n .catch((error) => void Diagnostics.emit(errorHooks, error))\n return queue\n }\n rebuilds.push(rebuild)\n if (!quiet) {\n armKeys ??= listenForKeys({\n rebuild: () => rebuilds.forEach((trigger) => void trigger()),\n quit: (code) => void Promise.resolve(hooks.callHook('kubb:lifecycle:end')).finally(() => process.exit(code)),\n })\n }\n\n // The watcher ignores its startup state, so run the first build here; a failing one keeps watching so the user can fix the input.\n await rebuild()\n\n await startWatcher([watchPath], rebuild, { info: logInfo, error: logError })\n } else {\n if (tracker && !quiet) logWarn('Watch mode only follows a local `input` file, so this config is generated once.')\n try {\n const succeeded = await generate({ input, config, hooks, dryRun })\n if (!succeeded) anyFailed = true\n } catch (configError) {\n await Diagnostics.emit(errorHooks, configError)\n anyFailed = true\n }\n }\n }\n\n await hooks.callHook('kubb:lifecycle:end')\n\n // Watch mode prints a tip after each successful build. Regular generate commands need to\n // print one explicitly after the lifecycle group has closed so it stays outside the group.\n if (!quiet && !watch && !anyFailed) {\n logTip()\n }\n\n if (anyFailed) {\n process.exit(1)\n }\n } catch (error) {\n await Diagnostics.emit(errorHooks, error)\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAkCA,MAAM,uBAAuB;;AAG7B,MAAM,0BAA0B;AAqBhC,eAAsB,SAAS,SAA0C;CACvE,MAAM,EAAE,OAAO,OAAO,SAAS,UAAU;CAEzC,MAAM,SAAS,SAAS;EAAE,SAAS;EAAY,SAAS,QAAQ,OAAO;CAAE,CAAC;CAE1E,MAAM,SAAiB;EACrB,GAAG,QAAQ;EACX,OAAO,SAAS,QAAQ,OAAO;EAE/B,SAAS,SAAS,cAAc,IAAI,QAAQ,OAAO;EAEnD,QAAQ,SAAS;GAAE,GAAG,QAAQ,OAAO;GAAQ,QAAQ;GAAO,MAAM;GAAO,cAAc,CAAC;EAAE,IAAI,QAAQ,OAAO;CAC/G;CAIA,MAAM,OAAO,WAAW,QAAQ,EAAE,MAAM,CAAC;CACzC,MAAM,SAAS,MAAM,KAAK,SAAS;CAEnC,MAAM,OAAO;EAEX,SAAS,KAAK,OAAO,QAAQ,SAAS,MACpC,KAAK,OAAO,MAAM,WAAW,CAAC;GAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ;GAAI,SAAU,EAAE,WAAW,CAAC;EAA8B,CAAC,IAAI,CAAC,CAClI;EACA,cAAc,OAAO,MAAM;EAC3B,QAAQ,OAAO,UAAU,YAAY;CACvC,CAAC;CAED,OAAO,OAAO;AAChB;;AAYA,eAAe,qBAAkD;CAC/D,IAAI;EAGF,QAAO,OADa,MADF,MAAM,sBAAsB,EAAE,QAAQ,YAAY,QAAQ,uBAAuB,EAAE,CAAC,EAAA,CAC9E,KAAK,EAAA,CACjB;CACd,QAAQ;EAEN;CACF;AACF;AAEA,eAAe,eAAe,EAAE,OAAO,UAA8F;CACnI,MAAM,gBAAgB,MAAM;CAC5B,IAAI,iBAAiB,WAAW;EAAE,WAAW;EAAS,QAAQ;CAAc,CAAC,GAC3E,MAAM,YAAY,KAAK,OAAO,YAAY,OAAO;EAAE,gBAAgB;EAAS;CAAc,CAAC,CAAC;AAEhG;;AAGA,SAAS,WAAW,EAAE,MAAM,EAAE,SAAS,cAAc,cAA6D;CAChH,MAAM,aAAa;EACjB,QAAQ,SAAS,UAAU,SAAS,IAAI,UAAU,QAAQ,OAAO,QAAQ,GAAG;EAC5E,QAAQ,WAAW,UAAU,OAAO,IAAI,UAAU,QAAQ,SAAS,QAAQ,GAAG;EAC9E,WAAW,SAAS,UAAU,SAAS,IAAI,UAAU,WAAW,OAAO,WAAW,GAAG;EACrF,WAAW,WAAW,UAAU,OAAO,IAAI,UAAU,WAAW,SAAS,WAAW,GAAG;CACzF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CACX,QAAQ,CAAC,cAAc,SAAS,UAAU,KAAK,UAAU,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,UAAU,OAAO,KAAK,CAAC,CAAC;AAC1G;;;;;;AAOA,eAAsB,IAAI,EAAE,OAAO,YAAY,UAAU,aAAa,OAAO,WAAW,cAAc,UAAiD;CAErJ,MAAM,SAAS,mBAAmB;CAClC,MAAMA,aAAWC,SAAY,gBAA4CA,SAAY;CACrF,MAAM,QAAQ,IAAI,SAAoB;CAItC,MAAM,iBAAsC,cAAc,SAAS,eAAe,CAAC,KAAK;CAGxF,MAAM,OAAO,eAAe,SAAS,MAAM;CAC3C,MAAM,QAAQD,cAAYC,SAAY,UAAU;CAIhD,MAAM,aAAa,OAAO,IAAI,SAAoB,IAAI;CACtD,IAAI,MAAM,eAAe,YAAY;EAAE,UAAA;EAAU,WAAW,CAAC,WAAW;EAAG,QAAQ,kBAAkB,QAAQ,KAAK;CAAE,CAAC;CAGrH,MAAM,SAAS,QAAQ,KAAA,IAAY,UAAU,OAAO;CACpD,MAAM,UAAU,WAAW;EACzB;EACA;EACA;EACA,UAAU;CACZ,CAAC;CAED,QAAQ,YAAY,KAAA,CAAS;CAC7B,MAAM;CAEN,IAAI,CAAC,OACH,SAAS,EAAE,OAAO,gBAAgB,CAAC;CAKrC,MAAM,gBAAgB,cAAc;CACpC,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,IAAI,CAAC,OAAO,cAAc,MAAM,gBAAgB;EAEhD,MAAM,SAAS,MAAM;EACrB,UAAU,OAAO;EACjB,qBAAqB,OAAO;EAE5B,IAAI,CAAC,OAAO,cAAc,KAAK,UAAU,UAAU,OAAO,KAAK,SAAS,QAAQ,IAAI,GAAG,kBAAkB,CAAC,GAAG;CAC/G,SAAS,OAAO;EACd,IAAI,CAAC,OAAO,cAAc,MAAM,uBAAuB;EAEvD,IAAI,CAAC,MAAM,eAAe,OAAO;GAAE,UAAA;GAAU,WAAW,CAAC,WAAW;EAAE,CAAC;EAEvE,MAAM,YAAY,KAAK,YAAY,KAAK;EAExC,IAAI,CAAC,OAAO,SAAS,UAAU,OAAO,wBAAwB,CAAC;EAC/D,QAAQ,KAAK,CAAC;CAChB;CAIA,MAAM,YAAY,QAAQ,EAAE,EAAE,WAAW,SAAS,QAAQ,EAAE,CAAC,YAAY;EAAC;EAAa;EAAc;EAAc;CAAY;CAC/H,MAAM,YAAY,gBAAgB,WAAW,cAAc;CAC3D,eAAe,OAAO;EAAE,UAAA;EAAU;EAAW;CAAO,CAAC;CAErD,MAAM,MAAM,SAAS,wBAAwB,EAAE,QAAQ,CAAC;CAIxD,MAAM,eAAe;EAAE;EAAO;CAAO,CAAC;CAEtC,IAAI,CAAC,OAAO,SAAS,GAAG,UAAU,QAAQ,QAAQ,QAAQ,EAAE,OAAO;CAEnE,IAAI;EACF,IAAI,YAAY;EAEhB,MAAM,UAAU,QAAQ,WAAW,KAAK,IAAI,KAAA;EAC5C,MAAM,WAAuC,CAAC;EAC9C,IAAI;EAEJ,IAAI,QAAQ,QAAQ,QAAQ;EAC5B,KAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,iBAAiB,SAAS,OAAO;GAEvC,MAAM,aADY,OAAO,mBAAmB,WAAW,aAAa,cAAc,IAAI,KAAA,OACtD,SAAU,iBAA4B,KAAA;GACtE,IAAI,aAAa,SAAS;IACxB,MAAM,QAAQ,UAAU,UAAU,YAAY,KAAK,SAAS,QAAQ,IAAI,GAAG,SAAS,GAAG;IACvF,IAAI;IAIJ,MAAM,QAAQ,YAAY;KACxB,MAAM,UAAU,QAAQ,OAAO;KAC/B,MAAM,YAAY,MAAM,SAAS;MAAE;MAAO;MAAQ;MAAO;KAAO,CAAC;KACjE,MAAM,WAAW,QAAQ,KAAK;KAC9B,IAAI,UAAU,WAAW;MAAE,MAAM,WAAW,UAAU,QAAQ;MAAG,YAAY,aAAa,OAAO;KAAE,CAAC;KACpG,WAAW;KAEX,QAAQ,UAAU,GAAG,MAAM,IAAI,UAAU,OAAO,oBAAoB,MAAM,KAAK;KAC/E,UAAU;KACV,IAAI,WAAW;MACb,UAAU;MACV,OAAO;KACT;IACF;IAEA,IAAI,UAAU;IACd,MAAM,gBAA+B;KACnC,IAAI,SAAS,OAAO;KACpB,UAAU;KACV,QAAQ,MACL,WAAW;MACV,UAAU;MACV,OAAO,MAAM;KACf,CAAC,CAAC,CACD,OAAO,UAAU,KAAK,YAAY,KAAK,YAAY,KAAK,CAAC;KAC5D,OAAO;IACT;IACA,SAAS,KAAK,OAAO;IACrB,IAAI,CAAC,OACH,YAAY,cAAc;KACxB,eAAe,SAAS,SAAS,YAAY,KAAK,QAAQ,CAAC;KAC3D,OAAO,SAAS,KAAK,QAAQ,QAAQ,MAAM,SAAS,oBAAoB,CAAC,CAAC,CAAC,cAAc,QAAQ,KAAK,IAAI,CAAC;IAC7G,CAAC;IAIH,MAAM,QAAQ;IAEd,MAAM,aAAa,CAAC,SAAS,GAAG,SAAS;KAAE,MAAM;KAAS,OAAO;IAAS,CAAC;GAC7E,OAAO;IACL,IAAI,WAAW,CAAC,OAAO,QAAQ,iFAAiF;IAChH,IAAI;KAEF,IAAI,CAAC,MADmB,SAAS;MAAE;MAAO;MAAQ;MAAO;KAAO,CAAC,GACjD,YAAY;IAC9B,SAAS,aAAa;KACpB,MAAM,YAAY,KAAK,YAAY,WAAW;KAC9C,YAAY;IACd;GACF;EACF;EAEA,MAAM,MAAM,SAAS,oBAAoB;EAIzC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WACvB,OAAO;EAGT,IAAI,WACF,QAAQ,KAAK,CAAC;CAElB,SAAS,OAAO;EACd,MAAM,YAAY,KAAK,YAAY,KAAK;EACxC,QAAQ,KAAK,CAAC;CAChB;AACF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
|
-
const require_Telemetry = require("./Telemetry-
|
|
3
|
-
const require_utils = require("./utils-
|
|
4
|
-
const require_text = require("./text-
|
|
5
|
-
const require_registry = require("./registry-
|
|
2
|
+
const require_Telemetry = require("./Telemetry-D-IDgRfq.cjs");
|
|
3
|
+
const require_utils = require("./utils-Dju97QYB.cjs");
|
|
4
|
+
const require_text = require("./text-Sp4fptq1.cjs");
|
|
5
|
+
const require_registry = require("./registry-DSDoBaVk.cjs");
|
|
6
6
|
const require_config = require("./config-D63Gum4F.cjs");
|
|
7
|
-
const require_reporters = require("./reporters-
|
|
7
|
+
const require_reporters = require("./reporters-C4xq0GFT.cjs");
|
|
8
8
|
let node_util = require("node:util");
|
|
9
9
|
let node_process = require("node:process");
|
|
10
10
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
@@ -146,10 +146,9 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
146
146
|
let queue = Promise.resolve();
|
|
147
147
|
for (const config of configs) {
|
|
148
148
|
const effectiveInput = input ?? config.input;
|
|
149
|
-
const
|
|
150
|
-
const watchPath = inputKind === "file" || inputKind === "url" ? effectiveInput : void 0;
|
|
149
|
+
const watchPath = (typeof effectiveInput === "string" ? (0, _kubb_core.getInputKind)(effectiveInput) : void 0) === "file" ? effectiveInput : void 0;
|
|
151
150
|
if (watchPath && tracker) {
|
|
152
|
-
const label = (0, node_util.styleText)("yellow", `Watching ${
|
|
151
|
+
const label = (0, node_util.styleText)("yellow", `Watching ${node_path.default.relative(node_process.default.cwd(), watchPath)}`);
|
|
153
152
|
let previous;
|
|
154
153
|
const build = async () => {
|
|
155
154
|
const hrStart = node_process.default.hrtime();
|
|
@@ -187,29 +186,24 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
187
186
|
rebuild: () => rebuilds.forEach((trigger) => void trigger()),
|
|
188
187
|
quit: (code) => void Promise.resolve(hooks.callHook("kubb:lifecycle:end")).finally(() => node_process.default.exit(code))
|
|
189
188
|
});
|
|
190
|
-
const initialBody = inputKind === "url" ? await require_utils.fetchUrlBody(watchPath) : void 0;
|
|
191
189
|
await rebuild();
|
|
192
|
-
|
|
193
|
-
log: {
|
|
194
|
-
info: require_text.logInfo,
|
|
195
|
-
error: require_text.logError
|
|
196
|
-
},
|
|
197
|
-
initialBody
|
|
198
|
-
});
|
|
199
|
-
else await require_utils.startWatcher([watchPath], rebuild, {
|
|
190
|
+
await require_utils.startWatcher([watchPath], rebuild, {
|
|
200
191
|
info: require_text.logInfo,
|
|
201
192
|
error: require_text.logError
|
|
202
193
|
});
|
|
203
|
-
} else
|
|
204
|
-
if (!
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
194
|
+
} else {
|
|
195
|
+
if (tracker && !quiet) require_text.logWarn("Watch mode only follows a local `input` file, so this config is generated once.");
|
|
196
|
+
try {
|
|
197
|
+
if (!await generate({
|
|
198
|
+
input,
|
|
199
|
+
config,
|
|
200
|
+
hooks,
|
|
201
|
+
dryRun
|
|
202
|
+
})) anyFailed = true;
|
|
203
|
+
} catch (configError) {
|
|
204
|
+
await _kubb_core.Diagnostics.emit(errorHooks, configError);
|
|
205
|
+
anyFailed = true;
|
|
206
|
+
}
|
|
213
207
|
}
|
|
214
208
|
}
|
|
215
209
|
await hooks.callHook("kubb:lifecycle:end");
|
|
@@ -224,4 +218,4 @@ async function run({ input, configPath, logLevel: logLevelKey, watch, reporters:
|
|
|
224
218
|
exports.generate = generate;
|
|
225
219
|
exports.run = run;
|
|
226
220
|
|
|
227
|
-
//# sourceMappingURL=run-
|
|
221
|
+
//# sourceMappingURL=run-DNzoHmRZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-DNzoHmRZ.cjs","names":["trackRun","process","memoryStorage","createKubb","isOutdated","version","Diagnostics","styleText","pluralize","formatMs","logLevelMap","Hookable","cliReporter","createPlainWriter","logBanner","getConfigs","createSpinner","path","jsonReporter","fileReporter","htmlReporter","selectReporters","trackBuild","getInputKind","diffBuilds","getElapsedMs","listenForKeys","startWatcher","logInfo","logError"],"sources":["../src/runners/generate/run.ts"],"sourcesContent":["import path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatMs, formatters, getElapsedMs, linters } from '@internals/utils'\nimport {\n Hookable,\n type CLIOptions,\n cliReporter,\n type Config,\n createKubb,\n Diagnostics,\n fileReporter,\n getInputKind,\n htmlReporter,\n jsonReporter,\n type KubbHooks,\n logLevel as logLevelMap,\n memoryStorage,\n type ReporterName,\n} from '@kubb/core'\nimport { version } from '../../../package.json'\nimport { trackRun } from '../../Telemetry.ts'\nimport { pluralize } from '../../ui/text.ts'\nimport setupReporters, { selectReporters } from '../../loggers/reporters.ts'\nimport { createPlainWriter } from '../../loggers/plainWriter.ts'\nimport { logIntro, logOutro, logSpacer, logTip } from '../../ui/intro.ts'\nimport { logError, logInfo, logStep, logWarn } from '../../ui/log.ts'\nimport { logBanner } from '../../ui/mascot.ts'\nimport { createSpinner } from '../../ui/spinner.ts'\nimport { getConfigs } from '../../config.ts'\nimport { isOutdated } from '../../utils/registry.ts'\nimport { type BuildDiff, type BuildSnapshot, diffBuilds, listenForKeys, startWatcher, trackBuild } from './utils.ts'\n\n/** NPM registry endpoint used to check for @kubb/cli updates. */\nconst KUBB_NPM_PACKAGE_URL = 'https://registry.npmjs.org/@kubb/cli/latest' as const\n\n/** Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run. */\nconst UPDATE_CHECK_TIMEOUT_MS = 3_000\n\n/** The formatter names from `Config['output'].format`, without `'auto'` (detection, not a tool) and `false` (skip). */\ntype FormatterName = Exclude<NonNullable<Config['output']['format']>, 'auto' | false>\ntype LinterName = Exclude<NonNullable<Config['output']['lint']>, 'auto' | false>\n\n// Pinned here, not in `@internals/utils` (which must not import `@kubb/core`): a tool added to the union without a descriptor fails to compile.\nformatters satisfies Record<FormatterName, unknown>\nlinters satisfies Record<LinterName, unknown>\n\ntype GenerateProps = {\n input?: string\n config: Config\n hooks: Hookable<KubbHooks>\n /**\n * When `true`, generates in memory instead of writing to disk, skips formatting, linting, and\n * post-generate commands, and prints what would change on disk.\n */\n dryRun?: boolean\n}\n\nexport async function generate(options: GenerateProps): Promise<boolean> {\n const { input, hooks, dryRun = false } = options\n\n const report = trackRun({ command: 'generate', hrStart: process.hrtime() })\n\n const config: Config = {\n ...options.config,\n input: input ?? options.config.input,\n // Dry-run never touches disk, regardless of the config's own storage driver.\n storage: dryRun ? memoryStorage() : options.config.storage,\n // Also keeps core's `hasOutputPasses` false, so dry-run skips the output manifest write too.\n output: dryRun ? { ...options.config.output, format: false, lint: false, postGenerate: [] } : options.config.output,\n }\n\n // Core formats, lints and runs `output.postGenerate` after an error-free build, and reports\n // their failures as coded diagnostics that reach the summary, the json report and the exit code.\n const kubb = createKubb(config, { hooks })\n const result = await kubb.generate()\n\n await report({\n // A setup that threw leaves no driver, so read the configured plugins instead.\n plugins: kubb.config.plugins.flatMap((p) =>\n p && typeof p === 'object' ? [{ name: p.meta?.name ?? p.name ?? '', options: (p.options ?? {}) as Record<string, unknown> }] : [],\n ),\n filesCreated: result.files.length,\n status: result.success ? 'success' : 'failed',\n })\n\n return result.success\n}\n\ntype GenerateCommandOptions = {\n input?: string\n configPath?: string\n logLevel: string\n watch: boolean\n reporters?: Array<ReporterName>\n dryRun?: boolean\n}\n\n/** The latest published version, `undefined` when the registry does not answer in time. Never rejects. */\nasync function fetchLatestVersion(): Promise<string | undefined> {\n try {\n const res = await fetch(KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(UPDATE_CHECK_TIMEOUT_MS) })\n const data = (await res.json()) as { version: string }\n return data.version\n } catch {\n // Ignore network errors\n return undefined\n }\n}\n\nasync function checkForUpdate({ hooks, latest }: { hooks: Hookable<KubbHooks>; latest: Promise<string | undefined> }): Promise<void> {\n const latestVersion = await latest\n if (latestVersion && isOutdated({ installed: version, latest: latestVersion })) {\n await Diagnostics.emit(hooks, Diagnostics.update({ currentVersion: version, latestVersion }))\n }\n}\n\n/** Prints `Rebuilt in 1.2s · +1 schema -2 operations`, without the names part when the spec kept the same names. */\nfunction logRebuild({ diff: { schemas, operations }, durationMs }: { diff: BuildDiff; durationMs: number }): void {\n const specChange = [\n schemas.added && styleText('green', `+${pluralize(schemas.added, 'schema')}`),\n schemas.removed && styleText('red', `-${pluralize(schemas.removed, 'schema')}`),\n operations.added && styleText('green', `+${pluralize(operations.added, 'operation')}`),\n operations.removed && styleText('red', `-${pluralize(operations.removed, 'operation')}`),\n ]\n .filter(Boolean)\n .join(' ')\n logStep([`Rebuilt in ${formatMs(durationMs)}`, specChange].filter(Boolean).join(styleText('dim', ' · ')))\n}\n\n/**\n * Runs the full Kubb generation lifecycle for the given CLI options.\n * Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),\n * checks for a newer version, and calls `generate` for each config entry.\n */\nexport async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }: GenerateCommandOptions): Promise<void> {\n // Started first so the registry request overlaps the banner and the config load.\n const latest = fetchLatestVersion()\n const logLevel = logLevelMap[logLevelKey as keyof typeof logLevelMap] ?? logLevelMap.info\n const hooks = new Hookable<KubbHooks>()\n\n // CLI `--reporter` selects which reporters to trigger by name, defaulting to `cli`. `defineConfig`\n // registers the built-in reporters on the config; a config exported without it falls back to them below.\n const requestedNames: Array<ReporterName> = cliReporters?.length ? cliReporters : ['cli']\n\n // The `json` reporter owns stdout, so the command writes nothing of its own around it.\n const json = requestedNames.includes('json')\n const quiet = logLevel <= logLevelMap.silent || json\n\n // Errors raised outside a build have no report entry. In `json` mode they go to a stderr logger,\n // so they are never silent and stdout stays one JSON document.\n const errorHooks = json ? new Hookable<KubbHooks>() : hooks\n if (json) setupReporters(errorHooks, { logLevel, reporters: [cliReporter], writer: createPlainWriter(console.error) })\n\n // The config loads while the banner plays; the output still prints in order once the banner is done.\n const banner = quiet ? undefined : logBanner(version)\n const loading = getConfigs({\n configPath,\n input,\n watch,\n logLevel: logLevelKey as CLIOptions['logLevel'],\n })\n // Handled below; this keeps a rejection during the banner from counting as unhandled.\n loading.catch(() => undefined)\n await banner\n\n if (!quiet) {\n logIntro({ title: 'Configuration' })\n }\n\n // Load the config first so `config.reporters` can pick the reporters. A failure here has no\n // reporter installed yet, so fall back to the default `cli` reporter to surface it.\n const configSpinner = createSpinner()\n let configs: Array<Config>\n let resolvedConfigPath: string\n try {\n if (!quiet) configSpinner.start('Loading config')\n\n const loaded = await loading\n configs = loaded.configs\n resolvedConfigPath = loaded.configPath\n\n if (!quiet) configSpinner.stop(`Loaded ${styleText('dim', path.relative(process.cwd(), resolvedConfigPath))}`)\n } catch (error) {\n if (!quiet) configSpinner.error('Config failed loading')\n\n if (!json) setupReporters(hooks, { logLevel, reporters: [cliReporter] })\n // A diagnostic thrown while the config file runs, such as invalid extension options, sits in the cause chain.\n await Diagnostics.emit(errorHooks, error)\n\n if (!quiet) logOutro(styleText('red', '✗ Configuration failed'))\n process.exit(1)\n }\n\n // Without a reporter nothing is printed, not even an error, so a config written without\n // `defineConfig` gets the same built-ins it would have registered.\n const available = configs[0]?.reporters?.length ? configs[0].reporters : [cliReporter, jsonReporter, fileReporter, htmlReporter]\n const reporters = selectReporters(available, requestedNames)\n setupReporters(hooks, { logLevel, reporters, dryRun })\n\n await hooks.callHook('kubb:lifecycle:start', { version })\n\n // Inside the bootstrap group, so an update notice reads as part of the setup rather than as part\n // of the first config's generation.\n await checkForUpdate({ hooks, latest })\n\n if (!quiet) logOutro(`${pluralize(configs.length, 'config')} ready`)\n\n try {\n let anyFailed = false\n // One tracker, one key listener and one build queue serve every watched config, so several configs never mix diffs or answer `r` twice.\n const tracker = watch ? trackBuild(hooks) : undefined\n const rebuilds: Array<() => Promise<void>> = []\n let armKeys: (() => void) | undefined\n // Configs share the hooks emitter, so every build, from any watcher or the `r` key, waits for the one before it.\n let queue = Promise.resolve()\n for (const config of configs) {\n const effectiveInput = input ?? config.input\n const inputKind = typeof effectiveInput === 'string' ? getInputKind(effectiveInput) : undefined\n const watchPath = inputKind === 'file' ? (effectiveInput as string) : undefined\n if (watchPath && tracker) {\n const label = styleText('yellow', `Watching ${path.relative(process.cwd(), watchPath)}`)\n let previous: BuildSnapshot | undefined\n // Don't removeAll() between builds, that would also drop logger and lifecycle\n // listeners. Plugin listeners are already disposed by safeBuild's dispose()\n // in its finally block, so re-running generate() on the same hooks emitter is safe.\n const build = async () => {\n const hrStart = process.hrtime()\n const succeeded = await generate({ input, config, hooks, dryRun })\n const snapshot = tracker.take()\n if (previous) logRebuild({ diff: diffBuilds(previous, snapshot), durationMs: getElapsedMs(hrStart) })\n previous = snapshot\n\n logStep(armKeys ? `${label} ${styleText('dim', 'r rebuild · q quit')}` : label)\n armKeys?.()\n if (succeeded) {\n logSpacer()\n logTip()\n }\n }\n // A trigger that lands while this config's build is queued joins it; one that lands during the build queues one more. Never rejects.\n let pending = false\n const rebuild = (): Promise<void> => {\n if (pending) return queue\n pending = true\n queue = queue\n .then(() => {\n pending = false\n return build()\n })\n .catch((error) => void Diagnostics.emit(errorHooks, error))\n return queue\n }\n rebuilds.push(rebuild)\n if (!quiet) {\n armKeys ??= listenForKeys({\n rebuild: () => rebuilds.forEach((trigger) => void trigger()),\n quit: (code) => void Promise.resolve(hooks.callHook('kubb:lifecycle:end')).finally(() => process.exit(code)),\n })\n }\n\n // The watcher ignores its startup state, so run the first build here; a failing one keeps watching so the user can fix the input.\n await rebuild()\n\n await startWatcher([watchPath], rebuild, { info: logInfo, error: logError })\n } else {\n if (tracker && !quiet) logWarn('Watch mode only follows a local `input` file, so this config is generated once.')\n try {\n const succeeded = await generate({ input, config, hooks, dryRun })\n if (!succeeded) anyFailed = true\n } catch (configError) {\n await Diagnostics.emit(errorHooks, configError)\n anyFailed = true\n }\n }\n }\n\n await hooks.callHook('kubb:lifecycle:end')\n\n // Watch mode prints a tip after each successful build. Regular generate commands need to\n // print one explicitly after the lifecycle group has closed so it stays outside the group.\n if (!quiet && !watch && !anyFailed) {\n logTip()\n }\n\n if (anyFailed) {\n process.exit(1)\n }\n } catch (error) {\n await Diagnostics.emit(errorHooks, error)\n process.exit(1)\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as connect, a as login, c as runStudio } from "./run-
|
|
1
|
+
export { t as connect, a as login, c as runStudio } from "./run-Bd_ZfPG1.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
2
|
const require_errors = require("./errors-Cl69p_vI.cjs");
|
|
3
|
-
const require_Telemetry = require("./Telemetry-
|
|
3
|
+
const require_Telemetry = require("./Telemetry-D-IDgRfq.cjs");
|
|
4
4
|
let node_util = require("node:util");
|
|
5
5
|
let node_process = require("node:process");
|
|
6
6
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
@@ -30,4 +30,4 @@ async function run() {
|
|
|
30
30
|
//#endregion
|
|
31
31
|
exports.run = run;
|
|
32
32
|
|
|
33
|
-
//# sourceMappingURL=run-
|
|
33
|
+
//# sourceMappingURL=run-bSFXs9i3.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-
|
|
1
|
+
{"version":3,"file":"run-bSFXs9i3.cjs","names":["trackRun","process","styleText","toError"],"sources":["../src/runners/mcp/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport type * as McpModule from '@kubb/mcp'\nimport { trackRun } from '../../Telemetry.ts'\n\n/**\n * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.\n */\nexport async function run(): Promise<void> {\n const { run: startMcpServer } = (await import('@kubb/mcp')) as typeof McpModule\n\n const report = trackRun({ command: 'mcp', hrStart: process.hrtime() })\n\n try {\n // The MCP stdio transport owns stdout: anything else written there corrupts the JSON-RPC stream.\n console.error(styleText('cyan', '⏳ Starting MCP server...'))\n console.warn(styleText('yellow', 'This feature is still under development, use with caution'))\n const server = startMcpServer()\n // Report once the client introduces itself, so the event names the client (e.g. `claude-code`, `cursor-vscode`).\n server.on('initialize', ({ clientInfo }) => void report({ status: 'success', mcpClient: clientInfo.name }), { once: true })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":";;;;;;;;;;AASA,eAAsB,MAAqB;CACzC,MAAM,EAAE,KAAK,mBAAoB,MAAM,OAAO;CAE9C,MAAM,SAASA,kBAAAA,SAAS;EAAE,SAAS;EAAO,SAASC,aAAAA,QAAQ,OAAO;CAAE,CAAC;CAErE,IAAI;EAEF,QAAQ,OAAA,GAAMC,UAAAA,UAAAA,CAAU,QAAQ,0BAA0B,CAAC;EAC3D,QAAQ,MAAA,GAAKA,UAAAA,UAAAA,CAAU,UAAU,2DAA2D,CAAC;EAG7F,eAAK,CAAC,CAAC,GAAG,eAAe,EAAE,iBAAiB,KAAK,OAAO;GAAE,QAAQ;GAAW,WAAW,WAAW;EAAK,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CAC5H,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,QAAQ,MAAMC,eAAAA,QAAQ,KAAK,CAAC,CAAC,OAAO;EACpC,aAAA,QAAA,WAAmB;CACrB;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
2
|
import { n as toError } from "./errors-DmC83ALX.js";
|
|
3
|
-
import { n as trackRun } from "./Telemetry-
|
|
3
|
+
import { n as trackRun } from "./Telemetry-wyeU72_v.js";
|
|
4
4
|
import { styleText } from "node:util";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
//#region src/runners/mcp/run.ts
|
|
@@ -29,4 +29,4 @@ async function run() {
|
|
|
29
29
|
//#endregion
|
|
30
30
|
export { run };
|
|
31
31
|
|
|
32
|
-
//# sourceMappingURL=run-
|
|
32
|
+
//# sourceMappingURL=run-z960932J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-
|
|
1
|
+
{"version":3,"file":"run-z960932J.js","names":[],"sources":["../src/runners/mcp/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\nimport type * as McpModule from '@kubb/mcp'\nimport { trackRun } from '../../Telemetry.ts'\n\n/**\n * Starts the `@kubb/mcp` server over stdio and reports the outcome to telemetry.\n */\nexport async function run(): Promise<void> {\n const { run: startMcpServer } = (await import('@kubb/mcp')) as typeof McpModule\n\n const report = trackRun({ command: 'mcp', hrStart: process.hrtime() })\n\n try {\n // The MCP stdio transport owns stdout: anything else written there corrupts the JSON-RPC stream.\n console.error(styleText('cyan', '⏳ Starting MCP server...'))\n console.warn(styleText('yellow', 'This feature is still under development, use with caution'))\n const server = startMcpServer()\n // Report once the client introduces itself, so the event names the client (e.g. `claude-code`, `cursor-vscode`).\n server.on('initialize', ({ clientInfo }) => void report({ status: 'success', mcpClient: clientInfo.name }), { once: true })\n } catch (error) {\n await report({ status: 'failed' })\n console.error(toError(error).message)\n process.exitCode = 1\n }\n}\n"],"mappings":";;;;;;;;;AASA,eAAsB,MAAqB;CACzC,MAAM,EAAE,KAAK,mBAAoB,MAAM,OAAO;CAE9C,MAAM,SAAS,SAAS;EAAE,SAAS;EAAO,SAAS,QAAQ,OAAO;CAAE,CAAC;CAErE,IAAI;EAEF,QAAQ,MAAM,UAAU,QAAQ,0BAA0B,CAAC;EAC3D,QAAQ,KAAK,UAAU,UAAU,2DAA2D,CAAC;EAG7F,eAAK,CAAC,CAAC,GAAG,eAAe,EAAE,iBAAiB,KAAK,OAAO;GAAE,QAAQ;GAAW,WAAW,WAAW;EAAK,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CAC5H,SAAS,OAAO;EACd,MAAM,OAAO,EAAE,QAAQ,SAAS,CAAC;EACjC,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC,OAAO;EACpC,QAAQ,WAAW;CACrB;AACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
|
-
import { a as getElapsedMs, i as formatMs } from "./Telemetry-
|
|
3
|
-
import { c as runStudio, i as loadConfigs } from "./run-
|
|
4
|
-
import {
|
|
5
|
-
import { m as createPlainWriter, t as pluralize } from "./text-
|
|
6
|
-
import { n as setupReporters } from "./reporters-
|
|
2
|
+
import { a as getElapsedMs, i as formatMs } from "./Telemetry-wyeU72_v.js";
|
|
3
|
+
import { c as runStudio, i as loadConfigs } from "./run-Bd_ZfPG1.js";
|
|
4
|
+
import { g as read } from "./utils-BDDF8GOv.js";
|
|
5
|
+
import { m as createPlainWriter, t as pluralize } from "./text-DgzXienb.js";
|
|
6
|
+
import { n as setupReporters } from "./reporters-BXNKLBLf.js";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import process from "node:process";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
@@ -247,4 +247,4 @@ const runner = ({ values }) => runStudio(values, (options) => snapshot({
|
|
|
247
247
|
//#endregion
|
|
248
248
|
export { runner };
|
|
249
249
|
|
|
250
|
-
//# sourceMappingURL=snapshot-
|
|
250
|
+
//# sourceMappingURL=snapshot-CLgI_qzL.js.map
|