@kubb/cli 5.10.1 → 5.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Telemetry-BfdvvZus.cjs → Telemetry-BV4GonCV.cjs} +2 -2
- package/dist/Telemetry-BV4GonCV.cjs.map +1 -0
- package/dist/Telemetry-CH2kkxWK.cjs +322 -0
- package/dist/Telemetry-CH2kkxWK.cjs.map +1 -0
- package/dist/{Telemetry-Bf6lUdai.js → Telemetry-Cz9QCzRo.js} +2 -2
- package/dist/Telemetry-Cz9QCzRo.js.map +1 -0
- package/dist/{background-D5K6ecEo.js → background-DFME5huR.js} +30 -7
- package/dist/background-DFME5huR.js.map +1 -0
- package/dist/{background-obsD4Gj2.cjs → background-DVZB1n4j.cjs} +25 -6
- package/dist/background-DVZB1n4j.cjs.map +1 -0
- package/dist/background-WaKtfQWr.cjs +192 -0
- package/dist/background-WaKtfQWr.cjs.map +1 -0
- package/dist/{background-C8doa9-4.js → background-_A5NwvYH.js} +1 -1
- package/dist/{config-CcqzzfB7.cjs → config-DKAqX5sW.cjs} +18 -4
- package/dist/config-DKAqX5sW.cjs.map +1 -0
- package/dist/{config-IMZ26zcb.js → config-DV_7s1m-.js} +19 -5
- package/dist/config-DV_7s1m-.js.map +1 -0
- package/dist/config-OL_izsmp.cjs +113 -0
- package/dist/config-OL_izsmp.cjs.map +1 -0
- package/dist/credentials-xOkTTDWj.cjs +113 -0
- package/dist/credentials-xOkTTDWj.cjs.map +1 -0
- package/dist/index.cjs +65 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +65 -24
- package/dist/index.js.map +1 -1
- package/dist/output-C5g7AtWH.cjs +1008 -0
- package/dist/output-C5g7AtWH.cjs.map +1 -0
- package/dist/{output-mwVt_Vj9.js → output-D_gc1nrM.js} +99 -44
- package/dist/output-D_gc1nrM.js.map +1 -0
- package/dist/{output-DLrxGtuN.cjs → output-nieBFDgM.cjs} +104 -43
- package/dist/output-nieBFDgM.cjs.map +1 -0
- package/dist/{registry-x-_nbYR6.cjs → registry-C8E_G7Xc.cjs} +49 -15
- package/dist/registry-C8E_G7Xc.cjs.map +1 -0
- package/dist/registry-CIpW2zQc.cjs +157 -0
- package/dist/registry-CIpW2zQc.cjs.map +1 -0
- package/dist/{registry-ChqX2AFQ.js → registry-De1vVn1d.js} +50 -16
- package/dist/registry-De1vVn1d.js.map +1 -0
- package/dist/rolldown-runtime-C0BPl7ul.cjs +43 -0
- package/dist/run-BbhrOuK6.cjs +40 -0
- package/dist/{run-1MJA0P5x.cjs.map → run-BbhrOuK6.cjs.map} +1 -1
- package/dist/{run-DHiVlG37.cjs → run-BnLba1gt.cjs} +27 -14
- package/dist/run-BnLba1gt.cjs.map +1 -0
- package/dist/{run-D4vOhfbJ.js → run-Bp47k1W1.js} +2 -2
- package/dist/{run-D4vOhfbJ.js.map → run-Bp47k1W1.js.map} +1 -1
- package/dist/run-BpdJ6X75.cjs +32 -0
- package/dist/{run-B13e9GQz.cjs.map → run-BpdJ6X75.cjs.map} +1 -1
- package/dist/{run-Cm0sJO0h.js → run-CCMlmk-z.js} +1 -1
- package/dist/{run-DTz7gAk1.js → run-CPYD1Lp0.js} +27 -14
- package/dist/run-CPYD1Lp0.js.map +1 -0
- package/dist/run-CSOEGpWZ.cjs +326 -0
- package/dist/run-CSOEGpWZ.cjs.map +1 -0
- package/dist/{run-B13e9GQz.cjs → run-CvE8ZdKG.cjs} +2 -2
- package/dist/run-CvE8ZdKG.cjs.map +1 -0
- package/dist/{run-Cu3pmezx.js → run-DaFK-Uy2.js} +2 -2
- package/dist/{run-Cu3pmezx.js.map → run-DaFK-Uy2.js.map} +1 -1
- package/dist/{run-BAlcXyYw.js → run-Ij84bqza.js} +22 -16
- package/dist/run-Ij84bqza.js.map +1 -0
- package/dist/{run-1MJA0P5x.cjs → run-MFjzBB_M.cjs} +2 -2
- package/dist/run-MFjzBB_M.cjs.map +1 -0
- package/dist/run-hgSZImuK.cjs +345 -0
- package/dist/run-hgSZImuK.cjs.map +1 -0
- package/dist/{run-CUyhuGlK.cjs → run-hyi91b22.cjs} +22 -16
- package/dist/run-hyi91b22.cjs.map +1 -0
- package/dist/{snapshot-DCG-Jf1A.js → snapshot-B6w3BLum.js} +22 -9
- package/dist/snapshot-B6w3BLum.js.map +1 -0
- package/dist/snapshot-DP9Pcnsg.cjs +264 -0
- package/dist/snapshot-DP9Pcnsg.cjs.map +1 -0
- package/dist/{snapshot-C5cthCuU.cjs → snapshot-D_F4XkYQ.cjs} +22 -9
- package/dist/snapshot-D_F4XkYQ.cjs.map +1 -0
- package/dist/studioWorker.js +2 -2
- package/package.json +15 -10
- package/dist/Telemetry-Bf6lUdai.js.map +0 -1
- package/dist/Telemetry-BfdvvZus.cjs.map +0 -1
- package/dist/background-D5K6ecEo.js.map +0 -1
- package/dist/background-obsD4Gj2.cjs.map +0 -1
- package/dist/config-CcqzzfB7.cjs.map +0 -1
- package/dist/config-IMZ26zcb.js.map +0 -1
- package/dist/output-DLrxGtuN.cjs.map +0 -1
- package/dist/output-mwVt_Vj9.js.map +0 -1
- package/dist/registry-ChqX2AFQ.js.map +0 -1
- package/dist/registry-x-_nbYR6.cjs.map +0 -1
- package/dist/run-BAlcXyYw.js.map +0 -1
- package/dist/run-CUyhuGlK.cjs.map +0 -1
- package/dist/run-DHiVlG37.cjs.map +0 -1
- package/dist/run-DTz7gAk1.js.map +0 -1
- package/dist/snapshot-C5cthCuU.cjs.map +0 -1
- package/dist/snapshot-DCG-Jf1A.js.map +0 -1
- package/dist/studioWorker.d.ts +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-DVZB1n4j.cjs","names":["path","getProjectKubbHome","readFile","connectSocket","Diagnostics","delay","prepareConnection","createRequire","x"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { hash, randomBytes } from 'node:crypto'\nimport { readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { Diagnostics } from '@kubb/core'\nimport { x } from 'tinyexec'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state))\n throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Worker identity changed' })\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Cannot verify the background worker. No process was signaled.',\n help: 'Check `worker.log`, then stop the process by hand if it is still running.',\n })\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'The worker has not finished shutting down. Check worker.log and try again.',\n })\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'The project control port is occupied or another worker is starting. Try again after stopping that listener.',\n })\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = x(process.execPath, [...process.execArgv, entry], {\n nodeOptions: { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] },\n }).process\n if (!child)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Background worker failed to start',\n help: 'Run `kubb studio` in the foreground to see why it fails.',\n })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
const require_credentials = require("./credentials-xOkTTDWj.cjs");
|
|
3
|
+
const require_run = require("./run-CSOEGpWZ.cjs");
|
|
4
|
+
require("node:crypto");
|
|
5
|
+
let tinyexec = require("tinyexec");
|
|
6
|
+
let node_fs_promises = require("node:fs/promises");
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
9
|
+
let _kubb_core = require("@kubb/core");
|
|
10
|
+
let node_module = require("node:module");
|
|
11
|
+
let node_net = require("node:net");
|
|
12
|
+
let node_timers_promises = require("node:timers/promises");
|
|
13
|
+
//#region src/runners/studio/background.ts
|
|
14
|
+
const states = [
|
|
15
|
+
"starting",
|
|
16
|
+
"connected",
|
|
17
|
+
"reconnecting",
|
|
18
|
+
"authentication required",
|
|
19
|
+
"stopped"
|
|
20
|
+
];
|
|
21
|
+
const getWorkerLogPath = () => node_path.default.join(require_credentials.getProjectKubbHome(), "worker.log");
|
|
22
|
+
const statePath = () => node_path.default.join(require_credentials.getProjectKubbHome(), "worker.json");
|
|
23
|
+
async function readWorker() {
|
|
24
|
+
try {
|
|
25
|
+
const value = JSON.parse(await (0, node_fs_promises.readFile)(statePath(), "utf8"));
|
|
26
|
+
if (!value || typeof value !== "object") return null;
|
|
27
|
+
const record = value;
|
|
28
|
+
return typeof record.id === "string" && /^[a-f0-9]{32}$/.test(record.id) && Number.isInteger(record.pid) && (record.pid ?? 0) > 1 && Number.isInteger(record.port) && (record.port ?? 0) > 0 && (record.port ?? 0) <= 65535 && states.includes(record.state) ? record : null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function isAlive(pid) {
|
|
34
|
+
try {
|
|
35
|
+
process.kill(pid, 0);
|
|
36
|
+
return true;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return error.code === "EPERM";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */
|
|
42
|
+
function requestWorker(record, command) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const socket = (0, node_net.connect)({
|
|
45
|
+
host: "127.0.0.1",
|
|
46
|
+
port: record.port
|
|
47
|
+
});
|
|
48
|
+
let received = "";
|
|
49
|
+
socket.setTimeout(2e3, () => socket.destroy(/* @__PURE__ */ new Error("Worker control timed out")));
|
|
50
|
+
socket.once("error", reject);
|
|
51
|
+
socket.once("connect", () => socket.write(JSON.stringify({
|
|
52
|
+
id: record.id,
|
|
53
|
+
command
|
|
54
|
+
}) + "\n"));
|
|
55
|
+
socket.on("data", (chunk) => {
|
|
56
|
+
received += chunk.toString();
|
|
57
|
+
if (received.length > 4096) socket.destroy(/* @__PURE__ */ new Error("Invalid worker response"));
|
|
58
|
+
});
|
|
59
|
+
socket.once("end", () => {
|
|
60
|
+
try {
|
|
61
|
+
const response = JSON.parse(received);
|
|
62
|
+
if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state)) throw new _kubb_core.Diagnostics.Error({
|
|
63
|
+
code: _kubb_core.Diagnostics.code.internalError,
|
|
64
|
+
severity: "error",
|
|
65
|
+
message: "Worker identity changed"
|
|
66
|
+
});
|
|
67
|
+
resolve(response);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
reject(error);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function getWorkerStatus() {
|
|
75
|
+
const record = await readWorker();
|
|
76
|
+
if (!record) return {
|
|
77
|
+
running: false,
|
|
78
|
+
state: "stopped"
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
const response = await requestWorker(record, "status");
|
|
82
|
+
return {
|
|
83
|
+
running: true,
|
|
84
|
+
state: response.state,
|
|
85
|
+
pid: response.pid
|
|
86
|
+
};
|
|
87
|
+
} catch {
|
|
88
|
+
return {
|
|
89
|
+
running: false,
|
|
90
|
+
state: record.state === "authentication required" ? record.state : "stopped"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function stopWorker() {
|
|
95
|
+
const record = await readWorker();
|
|
96
|
+
if (!record) return;
|
|
97
|
+
try {
|
|
98
|
+
await requestWorker(record, "stop");
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (error.code !== "ECONNREFUSED" && isAlive(record.pid) && record.state !== "stopped" && record.state !== "authentication required") throw new _kubb_core.Diagnostics.Error({
|
|
101
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
102
|
+
severity: "error",
|
|
103
|
+
message: "Cannot verify the background worker. No process was signaled.",
|
|
104
|
+
help: "Check `worker.log`, then stop the process by hand if it is still running."
|
|
105
|
+
});
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const deadline = Date.now() + 15e3;
|
|
109
|
+
while (Date.now() < deadline) {
|
|
110
|
+
try {
|
|
111
|
+
await requestWorker(record, "status");
|
|
112
|
+
} catch {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
await (0, node_timers_promises.setTimeout)(100);
|
|
116
|
+
}
|
|
117
|
+
throw new _kubb_core.Diagnostics.Error({
|
|
118
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
119
|
+
severity: "error",
|
|
120
|
+
message: "The worker has not finished shutting down. Check worker.log and try again."
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async function startWorker(options) {
|
|
124
|
+
const current = await getWorkerStatus();
|
|
125
|
+
if (current.running) {
|
|
126
|
+
console.log(`Already running (${current.state}, PID ${current.pid}).`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const prepared = await require_run.prepareConnection(options);
|
|
130
|
+
const entry = node_path.default.join(node_path.default.dirname((0, node_module.createRequire)(require("url").pathToFileURL(__filename).href).resolve("@kubb/cli/package.json")), "dist", "studioWorker.js");
|
|
131
|
+
const child = (0, tinyexec.x)(process.execPath, [...process.execArgv, entry], { nodeOptions: {
|
|
132
|
+
cwd: process.cwd(),
|
|
133
|
+
detached: true,
|
|
134
|
+
stdio: [
|
|
135
|
+
"ignore",
|
|
136
|
+
"ignore",
|
|
137
|
+
"ignore",
|
|
138
|
+
"ipc"
|
|
139
|
+
]
|
|
140
|
+
} }).process;
|
|
141
|
+
if (!child) throw new _kubb_core.Diagnostics.Error({
|
|
142
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
143
|
+
severity: "error",
|
|
144
|
+
message: "Background worker failed to start",
|
|
145
|
+
help: "Run `kubb studio` in the foreground to see why it fails."
|
|
146
|
+
});
|
|
147
|
+
try {
|
|
148
|
+
await new Promise((resolve, reject) => {
|
|
149
|
+
const timer = setTimeout(() => done(/* @__PURE__ */ new Error("Background worker startup timed out")), 2e4);
|
|
150
|
+
const done = (error) => {
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
child.removeListener("error", failed);
|
|
153
|
+
child.removeListener("exit", exited);
|
|
154
|
+
child.removeListener("message", ready);
|
|
155
|
+
if (error) reject(error);
|
|
156
|
+
else resolve();
|
|
157
|
+
};
|
|
158
|
+
const failed = (error) => done(error);
|
|
159
|
+
const exited = () => done(/* @__PURE__ */ new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`));
|
|
160
|
+
child.once("error", failed);
|
|
161
|
+
child.once("exit", exited);
|
|
162
|
+
const ready = (message) => {
|
|
163
|
+
if (!message || typeof message !== "object" || !("started" in message) || message.started !== true) return done(/* @__PURE__ */ new Error("Invalid worker startup response"));
|
|
164
|
+
done();
|
|
165
|
+
};
|
|
166
|
+
child.once("message", ready);
|
|
167
|
+
child.send({
|
|
168
|
+
options: {
|
|
169
|
+
...options,
|
|
170
|
+
autoOpen: false
|
|
171
|
+
},
|
|
172
|
+
prepared
|
|
173
|
+
}, (error) => {
|
|
174
|
+
if (error) done(error);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
if (child.connected) child.disconnect();
|
|
178
|
+
child.unref();
|
|
179
|
+
const status = await getWorkerStatus();
|
|
180
|
+
console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
child.kill("SIGTERM");
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
exports.getWorkerLogPath = getWorkerLogPath;
|
|
188
|
+
exports.getWorkerStatus = getWorkerStatus;
|
|
189
|
+
exports.startWorker = startWorker;
|
|
190
|
+
exports.stopWorker = stopWorker;
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=background-WaKtfQWr.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-WaKtfQWr.cjs","names":["path","getProjectKubbHome","readFile","connectSocket","Diagnostics","delay","prepareConnection","createRequire","x"],"sources":["../src/runners/studio/background.ts"],"sourcesContent":["import { hash, randomBytes } from 'node:crypto'\nimport { readFile, rename, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { connect as connectSocket, createServer } from 'node:net'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { Diagnostics } from '@kubb/core'\nimport { x } from 'tinyexec'\nimport { getProjectKubbHome } from './credentials.ts'\nimport { prepareConnection, type PreparedConnection, type StudioOptions, type WorkerState } from './run.ts'\n\nexport type WorkerRecord = { id: string; pid: number; port: number; state: WorkerState }\nconst states: Array<WorkerState> = ['starting', 'connected', 'reconnecting', 'authentication required', 'stopped']\nexport const getWorkerLogPath = () => path.join(getProjectKubbHome(), 'worker.log')\nconst statePath = () => path.join(getProjectKubbHome(), 'worker.json')\n\nasync function readWorker(): Promise<WorkerRecord | null> {\n try {\n const value: unknown = JSON.parse(await readFile(statePath(), 'utf8'))\n if (!value || typeof value !== 'object') return null\n const record = value as Partial<WorkerRecord>\n return typeof record.id === 'string' &&\n /^[a-f0-9]{32}$/.test(record.id) &&\n Number.isInteger(record.pid) &&\n (record.pid ?? 0) > 1 &&\n Number.isInteger(record.port) &&\n (record.port ?? 0) > 0 &&\n (record.port ?? 0) <= 65535 &&\n states.includes(record.state as WorkerState)\n ? (record as WorkerRecord)\n : null\n } catch {\n return null\n }\n}\n\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/** Authenticated loopback IPC; a stored PID never authorizes sending a process signal. */\nfunction requestWorker(record: WorkerRecord, command: 'status' | 'stop'): Promise<WorkerRecord> {\n return new Promise((resolve, reject) => {\n const socket = connectSocket({ host: '127.0.0.1', port: record.port })\n let received = ''\n socket.setTimeout(2_000, () => socket.destroy(new Error('Worker control timed out')))\n socket.once('error', reject)\n socket.once('connect', () => socket.write(JSON.stringify({ id: record.id, command }) + '\\n'))\n socket.on('data', (chunk: Buffer) => {\n received += chunk.toString()\n if (received.length > 4096) socket.destroy(new Error('Invalid worker response'))\n })\n socket.once('end', () => {\n try {\n const response = JSON.parse(received) as WorkerRecord\n if (response.id !== record.id || response.pid !== record.pid || !states.includes(response.state))\n throw new Diagnostics.Error({ code: Diagnostics.code.internalError, severity: 'error', message: 'Worker identity changed' })\n resolve(response)\n } catch (error) {\n reject(error)\n }\n })\n })\n}\n\nexport async function getWorkerStatus(): Promise<{ running: boolean; state: WorkerState; pid?: number }> {\n const record = await readWorker()\n if (!record) return { running: false, state: 'stopped' }\n try {\n const response = await requestWorker(record, 'status')\n return { running: true, state: response.state, pid: response.pid }\n } catch {\n return { running: false, state: record.state === 'authentication required' ? record.state : 'stopped' }\n }\n}\n\nexport async function stopWorker(): Promise<void> {\n const record = await readWorker()\n if (!record) return\n try {\n await requestWorker(record, 'stop')\n } catch (error) {\n if (\n (error as NodeJS.ErrnoException).code !== 'ECONNREFUSED' &&\n isAlive(record.pid) &&\n record.state !== 'stopped' &&\n record.state !== 'authentication required'\n ) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Cannot verify the background worker. No process was signaled.',\n help: 'Check `worker.log`, then stop the process by hand if it is still running.',\n })\n }\n return\n }\n const deadline = Date.now() + 15_000\n while (Date.now() < deadline) {\n try {\n await requestWorker(record, 'status')\n } catch {\n return\n }\n await delay(100)\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'The worker has not finished shutting down. Check worker.log and try again.',\n })\n}\n\n/** The listening port is the project lock, so stale state never needs a PID-based takeover. */\nexport async function serveWorker(shutdown: AbortController) {\n const record: WorkerRecord = { id: randomBytes(16).toString('hex'), pid: process.pid, port: 0, state: 'starting' }\n const server = createServer((socket) => {\n let input = ''\n socket.setTimeout(2_000, () => socket.destroy())\n socket.on('error', () => {})\n socket.on('data', (chunk: Buffer) => {\n input += chunk.toString()\n if (input.length > 4096) {\n socket.destroy()\n return\n }\n if (!input.includes('\\n')) return\n try {\n const request = JSON.parse(input) as { id?: unknown; command?: unknown }\n if (request.id !== record.id || !['status', 'stop'].includes(String(request.command))) {\n socket.destroy()\n return\n }\n socket.end(JSON.stringify(record))\n if (request.command === 'stop') shutdown.abort()\n } catch {\n socket.destroy()\n }\n })\n })\n // Hash the project directory to choose its loopback port; fail on collisions.\n const port = 20_000 + (Number.parseInt(hash('sha256', getProjectKubbHome()).slice(0, 8), 16) % 30_000)\n try {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EADDRINUSE') throw error\n // Let a simultaneous starter finish writing its record before checking ownership.\n await delay(100)\n const existing = await readWorker()\n if (existing?.port === port) {\n try {\n return { existing: await requestWorker(existing, 'status') }\n } catch {\n /* Refuse an unverified listener. */\n }\n }\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'The project control port is occupied or another worker is starting. Try again after stopping that listener.',\n })\n }\n record.port = port\n let saving = Promise.resolve()\n const save = () => {\n const value = JSON.stringify(record)\n saving = saving.then(async () => {\n const temporary = `${statePath()}.${record.id}`\n await writeFile(temporary, value, { mode: 0o600 })\n await rename(temporary, statePath())\n })\n return saving\n }\n try {\n await save()\n } catch (error) {\n server.close()\n throw error\n }\n return {\n async state(state: WorkerState) {\n record.state = state\n await save()\n },\n async close() {\n try {\n if (record.state !== 'authentication required') {\n record.state = 'stopped'\n await save()\n }\n } finally {\n await new Promise<void>((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())))\n }\n },\n }\n}\n\nexport type WorkerLaunch = { options: StudioOptions; prepared: PreparedConnection }\n\nexport async function startWorker(options: StudioOptions): Promise<void> {\n const current = await getWorkerStatus()\n if (current.running) {\n console.log(`Already running (${current.state}, PID ${current.pid}).`)\n return\n }\n const prepared = await prepareConnection(options)\n const entry = path.join(path.dirname(createRequire(import.meta.url).resolve('@kubb/cli/package.json')), 'dist', 'studioWorker.js')\n const child = x(process.execPath, [...process.execArgv, entry], {\n nodeOptions: { cwd: process.cwd(), detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] },\n }).process\n if (!child)\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: 'Background worker failed to start',\n help: 'Run `kubb studio` in the foreground to see why it fails.',\n })\n try {\n const started = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => done(new Error('Background worker startup timed out')), 20_000)\n const done = (error?: Error) => {\n clearTimeout(timer)\n child.removeListener('error', failed)\n child.removeListener('exit', exited)\n child.removeListener('message', ready)\n if (error) reject(error)\n else resolve()\n }\n const failed = (error: Error) => done(error)\n const exited = () => done(new Error(`Background worker exited during startup. Check ${getWorkerLogPath()}`))\n child.once('error', failed)\n child.once('exit', exited)\n const ready = (message: unknown) => {\n if (!message || typeof message !== 'object' || !('started' in message) || message.started !== true)\n return done(new Error('Invalid worker startup response'))\n done()\n }\n child.once('message', ready)\n child.send({ options: { ...options, autoOpen: false }, prepared } satisfies WorkerLaunch, (error) => {\n if (error) done(error)\n })\n })\n await started\n if (child.connected) child.disconnect()\n child.unref()\n const status = await getWorkerStatus()\n console.log(`Background worker ${status.state} (PID ${status.pid ?? child.pid}). Logs: ${getWorkerLogPath()}`)\n } catch (error) {\n // This is the child we just spawned, not a PID recovered from disk.\n child.kill('SIGTERM')\n throw error\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as getWorkerLogPath, n as getWorkerStatus, i as startWorker, a as stopWorker } from "./background-
|
|
1
|
+
export { t as getWorkerLogPath, n as getWorkerStatus, i as startWorker, a as stopWorker } from "./background-DFME5huR.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-CPE0t6oh.cjs");
|
|
2
|
-
const
|
|
2
|
+
const require_Telemetry = require("./Telemetry-BV4GonCV.cjs");
|
|
3
|
+
const require_output = require("./output-nieBFDgM.cjs");
|
|
3
4
|
let node_process = require("node:process");
|
|
4
5
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
5
6
|
let node_path = require("node:path");
|
|
@@ -56,7 +57,13 @@ function selectReporters(reporters, names) {
|
|
|
56
57
|
/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */
|
|
57
58
|
async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
58
59
|
const file = configPath ? (0, node_path.resolve)(configPath) : require_output.findConfigFile();
|
|
59
|
-
if (!file) throw new Error(
|
|
60
|
+
if (!file) throw new _kubb_core.Diagnostics.Error({
|
|
61
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
62
|
+
severity: "error",
|
|
63
|
+
message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${require_output.CONFIG_EXTENSIONS.join(", ")}) in ${node_process.default.cwd()}, its .config/ and configs/ folders, and each parent folder.`,
|
|
64
|
+
help: "Run `kubb init` to create one, or pass a path with `--config`.",
|
|
65
|
+
location: { kind: "config" }
|
|
66
|
+
});
|
|
60
67
|
let configs;
|
|
61
68
|
try {
|
|
62
69
|
configs = await require_output.loadConfigFile(file, {
|
|
@@ -66,7 +73,14 @@ async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
|
66
73
|
logLevel
|
|
67
74
|
});
|
|
68
75
|
} catch (error) {
|
|
69
|
-
throw new Error(
|
|
76
|
+
throw new _kubb_core.Diagnostics.Error({
|
|
77
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
78
|
+
severity: "error",
|
|
79
|
+
message: `Config failed loading: ${file}`,
|
|
80
|
+
help: "Fix the error the config file throws, shown under `caused by:`.",
|
|
81
|
+
location: { kind: "config" },
|
|
82
|
+
cause: require_Telemetry.toError(error)
|
|
83
|
+
});
|
|
70
84
|
}
|
|
71
85
|
return {
|
|
72
86
|
configPath: file,
|
|
@@ -96,4 +110,4 @@ Object.defineProperty(exports, "setupReporters", {
|
|
|
96
110
|
}
|
|
97
111
|
});
|
|
98
112
|
|
|
99
|
-
//# sourceMappingURL=config-
|
|
113
|
+
//# sourceMappingURL=config-DKAqX5sW.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-DKAqX5sW.cjs","names":["process","isRichOutput","clackLogger","plainLogger","createCliReporter","resolve","findConfigFile","Diagnostics","CONFIG_EXTENSIONS","process","loadConfigFile","toError"],"sources":["../src/loggers/reporters.ts","../src/config.ts"],"sourcesContent":["import process from 'node:process'\nimport type { Config, Hookable, KubbHooks, Reporter, ReporterContext, ReporterPluginFiles } from '@kubb/core'\nimport { createCliReporter } from '@kubb/core'\nimport { isRichOutput } from '../utils/env.ts'\nimport type { Logger, LoggerOptions } from './defineLogger.ts'\nimport { clackLogger } from './clackLogger.ts'\nimport { plainLogger } from './plainLogger.ts'\n\n/** Bridges a {@link Reporter} onto the hook emitter: calls `report` with each config's {@link GenerationResult} on `kubb:generation:end`. */\nfunction installReporter(context: Hookable<KubbHooks>, reporter: Reporter, ctx: ReporterContext): void {\n const pluginFiles = reporter.needsPluginFiles ? new Map<Config, Map<string, Set<string>>>() : undefined\n\n if (pluginFiles) {\n context.hook('kubb:plugin:end', ({ config, plugin, files }) => {\n const filesByPlugin = pluginFiles.get(config) ?? new Map<string, Set<string>>()\n const seen = new Set([...filesByPlugin.values()].flatMap((paths) => [...paths]))\n const added = files.filter((file) => !seen.has(file.path)).map((file) => file.path)\n\n if (added.length) filesByPlugin.set(plugin.name, new Set([...(filesByPlugin.get(plugin.name) ?? []), ...added]))\n\n pluginFiles.set(config, filesByPlugin)\n })\n }\n\n context.hook('kubb:generation:end', async ({ config, diagnostics = [], filesCreated = 0, status = 'success', hrStart = process.hrtime() }) => {\n const files = pluginFiles?.get(config)\n const grouped: ReporterPluginFiles | undefined = files && [...files].map(([plugin, paths]) => ({ plugin, files: [...paths] }))\n\n await reporter.report({ config, diagnostics, filesCreated, status, hrStart, pluginFiles: grouped }, ctx)\n\n pluginFiles?.delete(config)\n })\n\n if (reporter.drain) {\n context.hook('kubb:lifecycle:end', () => reporter.drain?.(ctx))\n }\n}\n\n/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */\nfunction setupReporters(\n context: Hookable<KubbHooks>,\n {\n logLevel,\n reporters,\n logger: forcedLogger,\n }: LoggerOptions & {\n reporters: ReadonlyArray<Reporter>\n /** Overrides the terminal-based pick, e.g. the plain logger for `kubb studio snapshot`. */\n logger?: Logger\n },\n): void {\n const hasJson = reporters.some((reporter) => reporter.name === 'json')\n const ctx: ReporterContext = { logLevel }\n\n for (const reporter of reporters) {\n if (reporter.name !== 'cli') {\n installReporter(context, reporter, ctx)\n continue\n }\n\n if (hasJson) {\n continue\n }\n\n const logger = forcedLogger ?? (isRichOutput() ? clackLogger : plainLogger)\n const handle = logger(context, { logLevel })\n\n // The summary belongs inside the group the logger opened for this config, so the logger writes it.\n installReporter(context, createCliReporter({ render: handle?.renderSummary }), ctx)\n }\n}\n\nexport default setupReporters\n\n/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */\nexport function selectReporters(reporters: ReadonlyArray<Reporter>, names: ReadonlyArray<string>): Array<Reporter> {\n return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? [])\n}\n","import { resolve } from 'node:path'\nimport process from 'node:process'\nimport { CONFIG_EXTENSIONS, findConfigFile, loadConfigFile } from '@internals/shared'\nimport { type CLIOptions, type Config, Diagnostics } from '@kubb/core'\nimport { toError } from '@internals/utils'\n\ntype GetConfigsOptions = {\n /** Explicit path to the Kubb config file. When omitted, the loader searches up from `process.cwd()`. */\n configPath?: string\n /** OpenAPI input path or URL that overrides `config.input` for this run. */\n input?: string\n /** Watch flag forwarded to the user's `defineConfig` function. */\n watch?: boolean\n /** Log level forwarded to the user's `defineConfig` function. */\n logLevel?: CLIOptions['logLevel']\n}\n\ntype GetConfigsResult = {\n /** Absolute path to the resolved config file. */\n configPath: string\n /** Resolved and normalized Kubb configs, each guaranteed to have a `plugins` array. */\n configs: Array<Config>\n}\n\n/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */\nexport async function getConfigs({ configPath, input, watch, logLevel }: GetConfigsOptions): Promise<GetConfigsResult> {\n const file = configPath ? resolve(configPath) : findConfigFile()\n if (!file) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${CONFIG_EXTENSIONS.join(', ')}) in ${process.cwd()}, its .config/ and configs/ folders, and each parent folder.`,\n help: 'Run `kubb init` to create one, or pass a path with `--config`.',\n location: { kind: 'config' },\n })\n }\n\n let configs: Array<Config>\n try {\n configs = await loadConfigFile<Config>(file, { config: configPath, input, watch, logLevel } satisfies CLIOptions)\n } catch (error) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Config failed loading: ${file}`,\n help: 'Fix the error the config file throws, shown under `caused by:`.',\n location: { kind: 'config' },\n cause: toError(error),\n })\n }\n\n return { configPath: file, configs: configs.map((item) => ({ ...item, plugins: item.plugins ?? [] })) }\n}\n"],"mappings":";;;;;;;;;AASA,SAAS,gBAAgB,SAA8B,UAAoB,KAA4B;CACrG,MAAM,cAAc,SAAS,mCAAmB,IAAI,IAAsC,IAAI,KAAA;CAE9F,IAAI,aACF,QAAQ,KAAK,oBAAoB,EAAE,QAAQ,QAAQ,YAAY;EAC7D,MAAM,gBAAgB,YAAY,IAAI,MAAM,qBAAK,IAAI,IAAyB;EAC9E,MAAM,OAAO,IAAI,IAAI,CAAC,GAAG,cAAc,OAAO,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC;EAC/E,MAAM,QAAQ,MAAM,QAAQ,SAAS,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,KAAK,IAAI;EAElF,IAAI,MAAM,QAAQ,cAAc,IAAI,OAAO,sBAAM,IAAI,IAAI,CAAC,GAAI,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC,GAAI,GAAG,KAAK,CAAC,CAAC;EAE/G,YAAY,IAAI,QAAQ,aAAa;CACvC,CAAC;CAGH,QAAQ,KAAK,uBAAuB,OAAO,EAAE,QAAQ,cAAc,CAAC,GAAG,eAAe,GAAG,SAAS,WAAW,UAAUA,aAAAA,QAAQ,OAAO,QAAQ;EAC5I,MAAM,QAAQ,aAAa,IAAI,MAAM;EACrC,MAAM,UAA2C,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,YAAY;GAAE;GAAQ,OAAO,CAAC,GAAG,KAAK;EAAE,EAAE;EAE7H,MAAM,SAAS,OAAO;GAAE;GAAQ;GAAa;GAAc;GAAQ;GAAS,aAAa;EAAQ,GAAG,GAAG;EAEvG,aAAa,OAAO,MAAM;CAC5B,CAAC;CAED,IAAI,SAAS,OACX,QAAQ,KAAK,4BAA4B,SAAS,QAAQ,GAAG,CAAC;AAElE;;AAGA,SAAS,eACP,SACA,EACE,UACA,WACA,QAAQ,gBAMJ;CACN,MAAM,UAAU,UAAU,MAAM,aAAa,SAAS,SAAS,MAAM;CACrE,MAAM,MAAuB,EAAE,SAAS;CAExC,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI,SAAS,SAAS,OAAO;GAC3B,gBAAgB,SAAS,UAAU,GAAG;GACtC;EACF;EAEA,IAAI,SACF;EAIF,MAAM,UADS,iBAAiBC,eAAAA,aAAa,IAAIC,eAAAA,cAAcC,eAAAA,aAAAA,CACzC,SAAS,EAAE,SAAS,CAAC;EAG3C,gBAAgB,UAAA,GAASC,WAAAA,kBAAAA,CAAkB,EAAE,QAAQ,QAAQ,cAAc,CAAC,GAAG,GAAG;CACpF;AACF;;AAKA,SAAgB,gBAAgB,WAAoC,OAA+C;CACjH,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,SAAS,UAAU,MAAM,aAAa,SAAS,SAAS,IAAI,KAAK,CAAC,CAAC;AACzG;;;;ACpDA,eAAsB,WAAW,EAAE,YAAY,OAAO,OAAO,YAA0D;CACrH,MAAM,OAAO,cAAA,GAAaC,UAAAA,QAAAA,CAAQ,UAAU,IAAIC,eAAAA,eAAe;CAC/D,IAAI,CAAC,MACH,MAAM,IAAIC,WAAAA,YAAY,MAAM;EAC1B,MAAMA,WAAAA,YAAY,KAAK;EACvB,UAAU;EACV,SAAS,iEAAiEC,eAAAA,kBAAkB,KAAK,IAAI,EAAE,OAAOC,aAAAA,QAAQ,IAAI,EAAE;EAC5H,MAAM;EACN,UAAU,EAAE,MAAM,SAAS;CAC7B,CAAC;CAGH,IAAI;CACJ,IAAI;EACF,UAAU,MAAMC,eAAAA,eAAuB,MAAM;GAAE,QAAQ;GAAY;GAAO;GAAO;EAAS,CAAsB;CAClH,SAAS,OAAO;EACd,MAAM,IAAIH,WAAAA,YAAY,MAAM;GAC1B,MAAMA,WAAAA,YAAY,KAAK;GACvB,UAAU;GACV,SAAS,0BAA0B;GACnC,MAAM;GACN,UAAU,EAAE,MAAM,SAAS;GAC3B,OAAOI,kBAAAA,QAAQ,KAAK;EACtB,CAAC;CACH;CAEA,OAAO;EAAE,YAAY;EAAM,SAAS,QAAQ,KAAK,UAAU;GAAE,GAAG;GAAM,SAAS,KAAK,WAAW,CAAC;EAAE,EAAE;CAAE;AACxG"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import "./rolldown-runtime-CRm0XQPb.js";
|
|
2
|
-
import {
|
|
2
|
+
import { l as toError } from "./Telemetry-Cz9QCzRo.js";
|
|
3
|
+
import { _ as isRichOutput, b as CONFIG_EXTENSIONS, m as clackLogger, p as plainLogger, v as findConfigFile, y as loadConfigFile } from "./output-D_gc1nrM.js";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { resolve } from "node:path";
|
|
5
|
-
import { createCliReporter } from "@kubb/core";
|
|
6
|
+
import { Diagnostics, createCliReporter } from "@kubb/core";
|
|
6
7
|
//#region src/loggers/reporters.ts
|
|
7
8
|
/** Bridges a {@link Reporter} onto the hook emitter: calls `report` with each config's {@link GenerationResult} on `kubb:generation:end`. */
|
|
8
9
|
function installReporter(context, reporter, ctx) {
|
|
@@ -55,7 +56,13 @@ function selectReporters(reporters, names) {
|
|
|
55
56
|
/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */
|
|
56
57
|
async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
57
58
|
const file = configPath ? resolve(configPath) : findConfigFile();
|
|
58
|
-
if (!file) throw new Error(
|
|
59
|
+
if (!file) throw new Diagnostics.Error({
|
|
60
|
+
code: Diagnostics.code.unknown,
|
|
61
|
+
severity: "error",
|
|
62
|
+
message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${CONFIG_EXTENSIONS.join(", ")}) in ${process.cwd()}, its .config/ and configs/ folders, and each parent folder.`,
|
|
63
|
+
help: "Run `kubb init` to create one, or pass a path with `--config`.",
|
|
64
|
+
location: { kind: "config" }
|
|
65
|
+
});
|
|
59
66
|
let configs;
|
|
60
67
|
try {
|
|
61
68
|
configs = await loadConfigFile(file, {
|
|
@@ -65,7 +72,14 @@ async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
|
65
72
|
logLevel
|
|
66
73
|
});
|
|
67
74
|
} catch (error) {
|
|
68
|
-
throw new Error(
|
|
75
|
+
throw new Diagnostics.Error({
|
|
76
|
+
code: Diagnostics.code.unknown,
|
|
77
|
+
severity: "error",
|
|
78
|
+
message: `Config failed loading: ${file}`,
|
|
79
|
+
help: "Fix the error the config file throws, shown under `caused by:`.",
|
|
80
|
+
location: { kind: "config" },
|
|
81
|
+
cause: toError(error)
|
|
82
|
+
});
|
|
69
83
|
}
|
|
70
84
|
return {
|
|
71
85
|
configPath: file,
|
|
@@ -78,4 +92,4 @@ async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
|
78
92
|
//#endregion
|
|
79
93
|
export { selectReporters as n, setupReporters as r, getConfigs as t };
|
|
80
94
|
|
|
81
|
-
//# sourceMappingURL=config-
|
|
95
|
+
//# sourceMappingURL=config-DV_7s1m-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-DV_7s1m-.js","names":[],"sources":["../src/loggers/reporters.ts","../src/config.ts"],"sourcesContent":["import process from 'node:process'\nimport type { Config, Hookable, KubbHooks, Reporter, ReporterContext, ReporterPluginFiles } from '@kubb/core'\nimport { createCliReporter } from '@kubb/core'\nimport { isRichOutput } from '../utils/env.ts'\nimport type { Logger, LoggerOptions } from './defineLogger.ts'\nimport { clackLogger } from './clackLogger.ts'\nimport { plainLogger } from './plainLogger.ts'\n\n/** Bridges a {@link Reporter} onto the hook emitter: calls `report` with each config's {@link GenerationResult} on `kubb:generation:end`. */\nfunction installReporter(context: Hookable<KubbHooks>, reporter: Reporter, ctx: ReporterContext): void {\n const pluginFiles = reporter.needsPluginFiles ? new Map<Config, Map<string, Set<string>>>() : undefined\n\n if (pluginFiles) {\n context.hook('kubb:plugin:end', ({ config, plugin, files }) => {\n const filesByPlugin = pluginFiles.get(config) ?? new Map<string, Set<string>>()\n const seen = new Set([...filesByPlugin.values()].flatMap((paths) => [...paths]))\n const added = files.filter((file) => !seen.has(file.path)).map((file) => file.path)\n\n if (added.length) filesByPlugin.set(plugin.name, new Set([...(filesByPlugin.get(plugin.name) ?? []), ...added]))\n\n pluginFiles.set(config, filesByPlugin)\n })\n }\n\n context.hook('kubb:generation:end', async ({ config, diagnostics = [], filesCreated = 0, status = 'success', hrStart = process.hrtime() }) => {\n const files = pluginFiles?.get(config)\n const grouped: ReporterPluginFiles | undefined = files && [...files].map(([plugin, paths]) => ({ plugin, files: [...paths] }))\n\n await reporter.report({ config, diagnostics, filesCreated, status, hrStart, pluginFiles: grouped }, ctx)\n\n pluginFiles?.delete(config)\n })\n\n if (reporter.drain) {\n context.hook('kubb:lifecycle:end', () => reporter.drain?.(ctx))\n }\n}\n\n/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */\nfunction setupReporters(\n context: Hookable<KubbHooks>,\n {\n logLevel,\n reporters,\n logger: forcedLogger,\n }: LoggerOptions & {\n reporters: ReadonlyArray<Reporter>\n /** Overrides the terminal-based pick, e.g. the plain logger for `kubb studio snapshot`. */\n logger?: Logger\n },\n): void {\n const hasJson = reporters.some((reporter) => reporter.name === 'json')\n const ctx: ReporterContext = { logLevel }\n\n for (const reporter of reporters) {\n if (reporter.name !== 'cli') {\n installReporter(context, reporter, ctx)\n continue\n }\n\n if (hasJson) {\n continue\n }\n\n const logger = forcedLogger ?? (isRichOutput() ? clackLogger : plainLogger)\n const handle = logger(context, { logLevel })\n\n // The summary belongs inside the group the logger opened for this config, so the logger writes it.\n installReporter(context, createCliReporter({ render: handle?.renderSummary }), ctx)\n }\n}\n\nexport default setupReporters\n\n/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */\nexport function selectReporters(reporters: ReadonlyArray<Reporter>, names: ReadonlyArray<string>): Array<Reporter> {\n return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? [])\n}\n","import { resolve } from 'node:path'\nimport process from 'node:process'\nimport { CONFIG_EXTENSIONS, findConfigFile, loadConfigFile } from '@internals/shared'\nimport { type CLIOptions, type Config, Diagnostics } from '@kubb/core'\nimport { toError } from '@internals/utils'\n\ntype GetConfigsOptions = {\n /** Explicit path to the Kubb config file. When omitted, the loader searches up from `process.cwd()`. */\n configPath?: string\n /** OpenAPI input path or URL that overrides `config.input` for this run. */\n input?: string\n /** Watch flag forwarded to the user's `defineConfig` function. */\n watch?: boolean\n /** Log level forwarded to the user's `defineConfig` function. */\n logLevel?: CLIOptions['logLevel']\n}\n\ntype GetConfigsResult = {\n /** Absolute path to the resolved config file. */\n configPath: string\n /** Resolved and normalized Kubb configs, each guaranteed to have a `plugins` array. */\n configs: Array<Config>\n}\n\n/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */\nexport async function getConfigs({ configPath, input, watch, logLevel }: GetConfigsOptions): Promise<GetConfigsResult> {\n const file = configPath ? resolve(configPath) : findConfigFile()\n if (!file) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${CONFIG_EXTENSIONS.join(', ')}) in ${process.cwd()}, its .config/ and configs/ folders, and each parent folder.`,\n help: 'Run `kubb init` to create one, or pass a path with `--config`.',\n location: { kind: 'config' },\n })\n }\n\n let configs: Array<Config>\n try {\n configs = await loadConfigFile<Config>(file, { config: configPath, input, watch, logLevel } satisfies CLIOptions)\n } catch (error) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Config failed loading: ${file}`,\n help: 'Fix the error the config file throws, shown under `caused by:`.',\n location: { kind: 'config' },\n cause: toError(error),\n })\n }\n\n return { configPath: file, configs: configs.map((item) => ({ ...item, plugins: item.plugins ?? [] })) }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
const require_Telemetry = require("./Telemetry-CH2kkxWK.cjs");
|
|
3
|
+
const require_output = require("./output-C5g7AtWH.cjs");
|
|
4
|
+
let node_process = require("node:process");
|
|
5
|
+
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
let _kubb_core = require("@kubb/core");
|
|
8
|
+
//#region src/loggers/reporters.ts
|
|
9
|
+
/** Bridges a {@link Reporter} onto the hook emitter: calls `report` with each config's {@link GenerationResult} on `kubb:generation:end`. */
|
|
10
|
+
function installReporter(context, reporter, ctx) {
|
|
11
|
+
const pluginFiles = reporter.needsPluginFiles ? /* @__PURE__ */ new Map() : void 0;
|
|
12
|
+
if (pluginFiles) context.hook("kubb:plugin:end", ({ config, plugin, files }) => {
|
|
13
|
+
const filesByPlugin = pluginFiles.get(config) ?? /* @__PURE__ */ new Map();
|
|
14
|
+
const seen = new Set([...filesByPlugin.values()].flatMap((paths) => [...paths]));
|
|
15
|
+
const added = files.filter((file) => !seen.has(file.path)).map((file) => file.path);
|
|
16
|
+
if (added.length) filesByPlugin.set(plugin.name, /* @__PURE__ */ new Set([...filesByPlugin.get(plugin.name) ?? [], ...added]));
|
|
17
|
+
pluginFiles.set(config, filesByPlugin);
|
|
18
|
+
});
|
|
19
|
+
context.hook("kubb:generation:end", async ({ config, diagnostics = [], filesCreated = 0, status = "success", hrStart = node_process.default.hrtime() }) => {
|
|
20
|
+
const files = pluginFiles?.get(config);
|
|
21
|
+
const grouped = files && [...files].map(([plugin, paths]) => ({
|
|
22
|
+
plugin,
|
|
23
|
+
files: [...paths]
|
|
24
|
+
}));
|
|
25
|
+
await reporter.report({
|
|
26
|
+
config,
|
|
27
|
+
diagnostics,
|
|
28
|
+
filesCreated,
|
|
29
|
+
status,
|
|
30
|
+
hrStart,
|
|
31
|
+
pluginFiles: grouped
|
|
32
|
+
}, ctx);
|
|
33
|
+
pluginFiles?.delete(config);
|
|
34
|
+
});
|
|
35
|
+
if (reporter.drain) context.hook("kubb:lifecycle:end", () => reporter.drain?.(ctx));
|
|
36
|
+
}
|
|
37
|
+
/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */
|
|
38
|
+
function setupReporters(context, { logLevel, reporters, logger: forcedLogger }) {
|
|
39
|
+
const hasJson = reporters.some((reporter) => reporter.name === "json");
|
|
40
|
+
const ctx = { logLevel };
|
|
41
|
+
for (const reporter of reporters) {
|
|
42
|
+
if (reporter.name !== "cli") {
|
|
43
|
+
installReporter(context, reporter, ctx);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (hasJson) continue;
|
|
47
|
+
const handle = (forcedLogger ?? (require_output.isRichOutput() ? require_output.clackLogger : require_output.plainLogger))(context, { logLevel });
|
|
48
|
+
installReporter(context, (0, _kubb_core.createCliReporter)({ render: handle?.renderSummary }), ctx);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */
|
|
52
|
+
function selectReporters(reporters, names) {
|
|
53
|
+
return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? []);
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/config.ts
|
|
57
|
+
/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */
|
|
58
|
+
async function getConfigs({ configPath, input, watch, logLevel }) {
|
|
59
|
+
const file = configPath ? (0, node_path.resolve)(configPath) : require_output.findConfigFile();
|
|
60
|
+
if (!file) throw new _kubb_core.Diagnostics.Error({
|
|
61
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
62
|
+
severity: "error",
|
|
63
|
+
message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${require_output.CONFIG_EXTENSIONS.join(", ")}) in ${node_process.default.cwd()}, its .config/ and configs/ folders, and each parent folder.`,
|
|
64
|
+
help: "Run `kubb init` to create one, or pass a path with `--config`.",
|
|
65
|
+
location: { kind: "config" }
|
|
66
|
+
});
|
|
67
|
+
let configs;
|
|
68
|
+
try {
|
|
69
|
+
configs = await require_output.loadConfigFile(file, {
|
|
70
|
+
config: configPath,
|
|
71
|
+
input,
|
|
72
|
+
watch,
|
|
73
|
+
logLevel
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
throw new _kubb_core.Diagnostics.Error({
|
|
77
|
+
code: _kubb_core.Diagnostics.code.unknown,
|
|
78
|
+
severity: "error",
|
|
79
|
+
message: `Config failed loading: ${file}`,
|
|
80
|
+
help: "Fix the error the config file throws, shown under `caused by:`.",
|
|
81
|
+
location: { kind: "config" },
|
|
82
|
+
cause: require_Telemetry.toError(error)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
configPath: file,
|
|
87
|
+
configs: configs.map((item) => ({
|
|
88
|
+
...item,
|
|
89
|
+
plugins: item.plugins ?? []
|
|
90
|
+
}))
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
Object.defineProperty(exports, "getConfigs", {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get: function() {
|
|
97
|
+
return getConfigs;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, "selectReporters", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function() {
|
|
103
|
+
return selectReporters;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
Object.defineProperty(exports, "setupReporters", {
|
|
107
|
+
enumerable: true,
|
|
108
|
+
get: function() {
|
|
109
|
+
return setupReporters;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=config-OL_izsmp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-OL_izsmp.cjs","names":["process","isRichOutput","clackLogger","plainLogger","createCliReporter","resolve","findConfigFile","Diagnostics","CONFIG_EXTENSIONS","process","loadConfigFile","toError"],"sources":["../src/loggers/reporters.ts","../src/config.ts"],"sourcesContent":["import process from 'node:process'\nimport type { Config, Hookable, KubbHooks, Reporter, ReporterContext, ReporterPluginFiles } from '@kubb/core'\nimport { createCliReporter } from '@kubb/core'\nimport { isRichOutput } from '../utils/env.ts'\nimport type { Logger, LoggerOptions } from './defineLogger.ts'\nimport { clackLogger } from './clackLogger.ts'\nimport { plainLogger } from './plainLogger.ts'\n\n/** Bridges a {@link Reporter} onto the hook emitter: calls `report` with each config's {@link GenerationResult} on `kubb:generation:end`. */\nfunction installReporter(context: Hookable<KubbHooks>, reporter: Reporter, ctx: ReporterContext): void {\n const pluginFiles = reporter.needsPluginFiles ? new Map<Config, Map<string, Set<string>>>() : undefined\n\n if (pluginFiles) {\n context.hook('kubb:plugin:end', ({ config, plugin, files }) => {\n const filesByPlugin = pluginFiles.get(config) ?? new Map<string, Set<string>>()\n const seen = new Set([...filesByPlugin.values()].flatMap((paths) => [...paths]))\n const added = files.filter((file) => !seen.has(file.path)).map((file) => file.path)\n\n if (added.length) filesByPlugin.set(plugin.name, new Set([...(filesByPlugin.get(plugin.name) ?? []), ...added]))\n\n pluginFiles.set(config, filesByPlugin)\n })\n }\n\n context.hook('kubb:generation:end', async ({ config, diagnostics = [], filesCreated = 0, status = 'success', hrStart = process.hrtime() }) => {\n const files = pluginFiles?.get(config)\n const grouped: ReporterPluginFiles | undefined = files && [...files].map(([plugin, paths]) => ({ plugin, files: [...paths] }))\n\n await reporter.report({ config, diagnostics, filesCreated, status, hrStart, pluginFiles: grouped }, ctx)\n\n pluginFiles?.delete(config)\n })\n\n if (reporter.drain) {\n context.hook('kubb:lifecycle:end', () => reporter.drain?.(ctx))\n }\n}\n\n/** Installs the live logger and wires the selected reporters. `cli` renders its summary through the logger, and is skipped when `json` owns stdout. */\nfunction setupReporters(\n context: Hookable<KubbHooks>,\n {\n logLevel,\n reporters,\n logger: forcedLogger,\n }: LoggerOptions & {\n reporters: ReadonlyArray<Reporter>\n /** Overrides the terminal-based pick, e.g. the plain logger for `kubb studio snapshot`. */\n logger?: Logger\n },\n): void {\n const hasJson = reporters.some((reporter) => reporter.name === 'json')\n const ctx: ReporterContext = { logLevel }\n\n for (const reporter of reporters) {\n if (reporter.name !== 'cli') {\n installReporter(context, reporter, ctx)\n continue\n }\n\n if (hasJson) {\n continue\n }\n\n const logger = forcedLogger ?? (isRichOutput() ? clackLogger : plainLogger)\n const handle = logger(context, { logLevel })\n\n // The summary belongs inside the group the logger opened for this config, so the logger writes it.\n installReporter(context, createCliReporter({ render: handle?.renderSummary }), ctx)\n }\n}\n\nexport default setupReporters\n\n/** Picks the reporters whose `name` is in `names`, in the given order (the CLI maps `--reporter` to this); duplicates and unknown names are skipped. */\nexport function selectReporters(reporters: ReadonlyArray<Reporter>, names: ReadonlyArray<string>): Array<Reporter> {\n return [...new Set(names)].flatMap((name) => reporters.find((reporter) => reporter.name === name) ?? [])\n}\n","import { resolve } from 'node:path'\nimport process from 'node:process'\nimport { CONFIG_EXTENSIONS, findConfigFile, loadConfigFile } from '@internals/shared'\nimport { type CLIOptions, type Config, Diagnostics } from '@kubb/core'\nimport { toError } from '@internals/utils'\n\ntype GetConfigsOptions = {\n /** Explicit path to the Kubb config file. When omitted, the loader searches up from `process.cwd()`. */\n configPath?: string\n /** OpenAPI input path or URL that overrides `config.input` for this run. */\n input?: string\n /** Watch flag forwarded to the user's `defineConfig` function. */\n watch?: boolean\n /** Log level forwarded to the user's `defineConfig` function. */\n logLevel?: CLIOptions['logLevel']\n}\n\ntype GetConfigsResult = {\n /** Absolute path to the resolved config file. */\n configPath: string\n /** Resolved and normalized Kubb configs, each guaranteed to have a `plugins` array. */\n configs: Array<Config>\n}\n\n/** Discovers the Kubb config and resolves it into normalized configs, each guaranteed to have a `plugins` array. */\nexport async function getConfigs({ configPath, input, watch, logLevel }: GetConfigsOptions): Promise<GetConfigsResult> {\n const file = configPath ? resolve(configPath) : findConfigFile()\n if (!file) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `No Kubb config found. Looked for kubb.config.* and .kubbrc.* (${CONFIG_EXTENSIONS.join(', ')}) in ${process.cwd()}, its .config/ and configs/ folders, and each parent folder.`,\n help: 'Run `kubb init` to create one, or pass a path with `--config`.',\n location: { kind: 'config' },\n })\n }\n\n let configs: Array<Config>\n try {\n configs = await loadConfigFile<Config>(file, { config: configPath, input, watch, logLevel } satisfies CLIOptions)\n } catch (error) {\n throw new Diagnostics.Error({\n code: Diagnostics.code.unknown,\n severity: 'error',\n message: `Config failed loading: ${file}`,\n help: 'Fix the error the config file throws, shown under `caused by:`.',\n location: { kind: 'config' },\n cause: toError(error),\n })\n }\n\n return { configPath: file, configs: configs.map((item) => ({ ...item, plugins: item.plugins ?? [] })) }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
+
let node_crypto = require("node:crypto");
|
|
3
|
+
let node_process = require("node:process");
|
|
4
|
+
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
7
|
+
let _kubb_core = require("@kubb/core");
|
|
8
|
+
//#region src/runners/studio/credentials.ts
|
|
9
|
+
var credentials_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
10
|
+
clearCredentials: () => clearCredentials,
|
|
11
|
+
getCredentialsPath: () => getCredentialsPath,
|
|
12
|
+
getMachineId: () => getMachineId,
|
|
13
|
+
getProjectKubbHome: () => getProjectKubbHome,
|
|
14
|
+
readCredentials: () => readCredentials,
|
|
15
|
+
writeCredentials: () => writeCredentials
|
|
16
|
+
});
|
|
17
|
+
const projectBase = (project = node_process.default.cwd()) => node_path.default.join("projects", (0, node_crypto.hash)("sha256", project));
|
|
18
|
+
/**
|
|
19
|
+
* Root for the credential and machine identity of the current project, inside `KUBB_HOME`.
|
|
20
|
+
*
|
|
21
|
+
* Studio agents are project connections, so two projects on one machine must not share the same
|
|
22
|
+
* persisted token or machine secret.
|
|
23
|
+
*/
|
|
24
|
+
function getProjectKubbHome(project = node_process.default.cwd()) {
|
|
25
|
+
return (0, _kubb_core.resolveKubbDir)(projectBase(project));
|
|
26
|
+
}
|
|
27
|
+
const projectStorage = () => (0, _kubb_core.kubbStorage)({ base: projectBase() });
|
|
28
|
+
const CREDENTIALS_FILENAME = "credentials.json";
|
|
29
|
+
/**
|
|
30
|
+
* Absolute path of the stored credential, so callers can name it in output without rebuilding it.
|
|
31
|
+
*/
|
|
32
|
+
function getCredentialsPath() {
|
|
33
|
+
return node_path.default.join(getProjectKubbHome(), CREDENTIALS_FILENAME);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Reads the stored credential, or null when this machine has not paired yet or the file is
|
|
37
|
+
* unreadable or corrupt. A bad file is treated as "not paired" so `kubb studio login` can
|
|
38
|
+
* overwrite it rather than the CLI dying on it.
|
|
39
|
+
*/
|
|
40
|
+
async function readCredentials() {
|
|
41
|
+
const stored = await projectStorage().getItem(CREDENTIALS_FILENAME).catch(() => null);
|
|
42
|
+
return typeof stored?.token === "string" && stored.token !== "" ? stored : null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Writes the credential into the project folder, which only its owner can open.
|
|
46
|
+
*/
|
|
47
|
+
async function writeCredentials(credentials) {
|
|
48
|
+
await projectStorage().setItem(CREDENTIALS_FILENAME, credentials);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Forgets the stored credential. Succeeds when there was nothing to forget.
|
|
52
|
+
*/
|
|
53
|
+
async function clearCredentials() {
|
|
54
|
+
await projectStorage().removeItem(CREDENTIALS_FILENAME);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reads this project's machine secret, creating it on first use. Pairing sends its hash, so pairing
|
|
58
|
+
* the same project again rotates one agent's token instead of creating a second agent. It lives
|
|
59
|
+
* apart from the credential, which {@link clearCredentials} deletes.
|
|
60
|
+
*/
|
|
61
|
+
async function getMachineId() {
|
|
62
|
+
const storage = projectStorage();
|
|
63
|
+
const stored = await storage.getItem("machine-secret").catch(() => null);
|
|
64
|
+
if (typeof stored === "string" && stored.trim()) return stored.trim();
|
|
65
|
+
const secret = (0, node_crypto.randomBytes)(32).toString("hex");
|
|
66
|
+
await storage.setItem("machine-secret", secret);
|
|
67
|
+
return secret;
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
Object.defineProperty(exports, "clearCredentials", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
get: function() {
|
|
73
|
+
return clearCredentials;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(exports, "credentials_exports", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function() {
|
|
79
|
+
return credentials_exports;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(exports, "getCredentialsPath", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function() {
|
|
85
|
+
return getCredentialsPath;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(exports, "getMachineId", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
get: function() {
|
|
91
|
+
return getMachineId;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
Object.defineProperty(exports, "getProjectKubbHome", {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get: function() {
|
|
97
|
+
return getProjectKubbHome;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, "readCredentials", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function() {
|
|
103
|
+
return readCredentials;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
Object.defineProperty(exports, "writeCredentials", {
|
|
107
|
+
enumerable: true,
|
|
108
|
+
get: function() {
|
|
109
|
+
return writeCredentials;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=credentials-xOkTTDWj.cjs.map
|