@kubb/cli 5.10.3 → 5.11.0

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.
Files changed (69) hide show
  1. package/dist/{Telemetry-Cz9QCzRo.js → Telemetry-D54bKqiZ.js} +2 -2
  2. package/dist/{Telemetry-Cz9QCzRo.js.map → Telemetry-D54bKqiZ.js.map} +1 -1
  3. package/dist/{Telemetry-BV4GonCV.cjs → Telemetry-emCunBZD.cjs} +2 -2
  4. package/dist/{Telemetry-BV4GonCV.cjs.map → Telemetry-emCunBZD.cjs.map} +1 -1
  5. package/dist/{background-DFME5huR.js → background-CazP2t3p.js} +2 -2
  6. package/dist/{background-DFME5huR.js.map → background-CazP2t3p.js.map} +1 -1
  7. package/dist/{background-DVZB1n4j.cjs → background-D1q5qKbD.cjs} +2 -2
  8. package/dist/{background-DVZB1n4j.cjs.map → background-D1q5qKbD.cjs.map} +1 -1
  9. package/dist/{background-_A5NwvYH.js → background-D_Ffper-.js} +1 -1
  10. package/dist/{config-DV_7s1m-.js → config-AxC9X28n.js} +3 -3
  11. package/dist/{config-DV_7s1m-.js.map → config-AxC9X28n.js.map} +1 -1
  12. package/dist/{config-DKAqX5sW.cjs → config-ChrJbiHE.cjs} +3 -3
  13. package/dist/{config-OL_izsmp.cjs.map → config-ChrJbiHE.cjs.map} +1 -1
  14. package/dist/index.cjs +15 -15
  15. package/dist/index.js +15 -15
  16. package/dist/{output-D_gc1nrM.js → output-Bh9zt0Bs.js} +2 -2
  17. package/dist/{output-D_gc1nrM.js.map → output-Bh9zt0Bs.js.map} +1 -1
  18. package/dist/{output-nieBFDgM.cjs → output-DTljL9Ws.cjs} +2 -2
  19. package/dist/{output-nieBFDgM.cjs.map → output-DTljL9Ws.cjs.map} +1 -1
  20. package/dist/{registry-C8E_G7Xc.cjs → registry-BXY6IkwJ.cjs} +2 -2
  21. package/dist/{registry-C8E_G7Xc.cjs.map → registry-BXY6IkwJ.cjs.map} +1 -1
  22. package/dist/{registry-De1vVn1d.js → registry-pGRX9C6u.js} +2 -2
  23. package/dist/{registry-De1vVn1d.js.map → registry-pGRX9C6u.js.map} +1 -1
  24. package/dist/{run-hyi91b22.cjs → run-5-nCbBHG.cjs} +5 -5
  25. package/dist/{run-hgSZImuK.cjs.map → run-5-nCbBHG.cjs.map} +1 -1
  26. package/dist/{run-CCMlmk-z.js → run-BEnJOcry.js} +1 -1
  27. package/dist/{run-CvE8ZdKG.cjs → run-CF08-tw4.cjs} +2 -2
  28. package/dist/{run-BpdJ6X75.cjs.map → run-CF08-tw4.cjs.map} +1 -1
  29. package/dist/{run-DaFK-Uy2.js → run-CFp3FPGw.js} +2 -2
  30. package/dist/{run-DaFK-Uy2.js.map → run-CFp3FPGw.js.map} +1 -1
  31. package/dist/{run-CPYD1Lp0.js → run-CXDiBAu2.js} +5 -5
  32. package/dist/{run-CPYD1Lp0.js.map → run-CXDiBAu2.js.map} +1 -1
  33. package/dist/{run-Bp47k1W1.js → run-CgjQy13a.js} +2 -2
  34. package/dist/{run-Bp47k1W1.js.map → run-CgjQy13a.js.map} +1 -1
  35. package/dist/{run-Ij84bqza.js → run-CkyawufO.js} +5 -5
  36. package/dist/{run-Ij84bqza.js.map → run-CkyawufO.js.map} +1 -1
  37. package/dist/{run-MFjzBB_M.cjs → run-DAobECOj.cjs} +2 -2
  38. package/dist/{run-BbhrOuK6.cjs.map → run-DAobECOj.cjs.map} +1 -1
  39. package/dist/{run-BnLba1gt.cjs → run-DTulgo15.cjs} +5 -5
  40. package/dist/{run-BnLba1gt.cjs.map → run-DTulgo15.cjs.map} +1 -1
  41. package/dist/{snapshot-B6w3BLum.js → snapshot-9yYp872a.js} +5 -5
  42. package/dist/{snapshot-B6w3BLum.js.map → snapshot-9yYp872a.js.map} +1 -1
  43. package/dist/{snapshot-D_F4XkYQ.cjs → snapshot-CWfVxcnq.cjs} +5 -5
  44. package/dist/{snapshot-D_F4XkYQ.cjs.map → snapshot-CWfVxcnq.cjs.map} +1 -1
  45. package/dist/studioWorker.js +2 -2
  46. package/package.json +8 -8
  47. package/dist/Telemetry-CH2kkxWK.cjs +0 -322
  48. package/dist/Telemetry-CH2kkxWK.cjs.map +0 -1
  49. package/dist/background-WaKtfQWr.cjs +0 -192
  50. package/dist/background-WaKtfQWr.cjs.map +0 -1
  51. package/dist/config-DKAqX5sW.cjs.map +0 -1
  52. package/dist/config-OL_izsmp.cjs +0 -113
  53. package/dist/credentials-xOkTTDWj.cjs +0 -113
  54. package/dist/credentials-xOkTTDWj.cjs.map +0 -1
  55. package/dist/output-C5g7AtWH.cjs +0 -1008
  56. package/dist/output-C5g7AtWH.cjs.map +0 -1
  57. package/dist/registry-CIpW2zQc.cjs +0 -157
  58. package/dist/registry-CIpW2zQc.cjs.map +0 -1
  59. package/dist/rolldown-runtime-C0BPl7ul.cjs +0 -43
  60. package/dist/run-BbhrOuK6.cjs +0 -40
  61. package/dist/run-BpdJ6X75.cjs +0 -32
  62. package/dist/run-CSOEGpWZ.cjs +0 -326
  63. package/dist/run-CSOEGpWZ.cjs.map +0 -1
  64. package/dist/run-CvE8ZdKG.cjs.map +0 -1
  65. package/dist/run-MFjzBB_M.cjs.map +0 -1
  66. package/dist/run-hgSZImuK.cjs +0 -345
  67. package/dist/run-hyi91b22.cjs.map +0 -1
  68. package/dist/snapshot-DP9Pcnsg.cjs +0 -264
  69. package/dist/snapshot-DP9Pcnsg.cjs.map +0 -1
@@ -1,345 +0,0 @@
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
- const require_registry = require("./registry-CIpW2zQc.cjs");
5
- const require_config = require("./config-OL_izsmp.cjs");
6
- let node_util = require("node:util");
7
- let node_process = require("node:process");
8
- node_process = require_rolldown_runtime.__toESM(node_process, 1);
9
- let node_path = require("node:path");
10
- node_path = require_rolldown_runtime.__toESM(node_path, 1);
11
- let _kubb_core = require("@kubb/core");
12
- //#region src/runners/generate/utils.ts
13
- /** Glob pattern for paths the file watcher ignores. */
14
- const WATCHER_IGNORED_PATHS = "**/{.git,node_modules}/**";
15
- /**
16
- * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits several) into one rebuild.
17
- * It outlasts chokidar's 100 ms atomic-save window, which holds back the event of a write-then-rename save.
18
- */
19
- const WATCHER_DEBOUNCE_MS = 250;
20
- /** Interval in milliseconds between polls of a remote `input` URL in watch mode, which emits no filesystem events. */
21
- const URL_WATCHER_INTERVAL_MS = 2e3;
22
- /** Upper bound in milliseconds for one URL watcher request, headers and body read, so a hung server never stalls polling. */
23
- const URL_WATCHER_TIMEOUT_MS = 1e4;
24
- /**
25
- * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight
26
- * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.
27
- * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should
28
- * coalesce into a single trailing run.
29
- *
30
- * @example
31
- * ```ts
32
- * const rebuild = createSerialRunner({
33
- * run: () => build(),
34
- * onError: (error) => log.error(error.message),
35
- * })
36
- * watcher.on('change', () => void rebuild())
37
- * ```
38
- */
39
- function createSerialRunner({ run, onError }) {
40
- let running = false;
41
- let dirty = false;
42
- return async () => {
43
- if (running) {
44
- dirty = true;
45
- return;
46
- }
47
- running = true;
48
- do {
49
- dirty = false;
50
- try {
51
- await run();
52
- } catch (error) {
53
- onError(require_Telemetry.toError(error));
54
- }
55
- } while (dirty);
56
- running = false;
57
- };
58
- }
59
- /**
60
- * Starts a file watcher on the given paths and calls `cb` on any change.
61
- * Ignores `.git` and `node_modules` directories. Event bursts (an editor save emits several)
62
- * are debounced into one build, and builds never overlap: changes during a build queue exactly
63
- * one rebuild. Resolves to a function that stops watching.
64
- */
65
- async function startWatcher(path, cb, log = {
66
- info: console.log,
67
- error: console.log
68
- }) {
69
- const { watch } = await import("chokidar");
70
- const watcher = watch(path, {
71
- ignorePermissionErrors: true,
72
- ignored: WATCHER_IGNORED_PATHS,
73
- ignoreInitial: true
74
- });
75
- node_process.default.once("SIGINT", () => {
76
- watcher.close();
77
- });
78
- node_process.default.once("SIGTERM", () => {
79
- watcher.close();
80
- });
81
- const runBuild = createSerialRunner({
82
- run: () => cb(path),
83
- onError: () => log.error((0, node_util.styleText)("red", "Watcher failed"))
84
- });
85
- let debounceTimer = null;
86
- watcher.on("all", (type, file) => {
87
- log.info((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${type} ${file}`)));
88
- if (debounceTimer) clearTimeout(debounceTimer);
89
- debounceTimer = setTimeout(() => {
90
- debounceTimer = null;
91
- runBuild();
92
- }, WATCHER_DEBOUNCE_MS);
93
- });
94
- return async () => {
95
- if (debounceTimer) clearTimeout(debounceTimer);
96
- await watcher.close();
97
- };
98
- }
99
- /**
100
- * Fetches the body of a remote spec URL, `undefined` when the server does not answer with a
101
- * readable 2xx body before `signal` aborts. The caller seeds `startUrlWatcher` with the result, so
102
- * the watcher compares polls against the content the initial build ran on.
103
- */
104
- async function fetchUrlBody(url, signal = AbortSignal.timeout(URL_WATCHER_TIMEOUT_MS)) {
105
- try {
106
- const response = await fetch(url, { signal });
107
- if (!response.ok) return void 0;
108
- return await response.text();
109
- } catch {
110
- return;
111
- }
112
- }
113
- /**
114
- * Polls a remote spec URL and calls `cb` whenever the response body changes. A remote document
115
- * emits no filesystem events, so this is the URL counterpart of `startWatcher`.
116
- *
117
- * `initialBody` seeds the change detection, so an edit landing between the initial build and the
118
- * first poll still rebuilds. An unreachable server (the API restarting between saves) is reported
119
- * once per outage and polling continues; after it recovers, a rebuild happens only when the body
120
- * actually differs from the last one seen, so a plain restart with an unchanged spec stays quiet.
121
- * Each request is aborted after `timeoutMs`, so a hung response delays at most one poll.
122
- *
123
- * Returns a function that stops polling and aborts the in-flight request, so callers (and tests)
124
- * can shut the watcher down without signaling the process.
125
- */
126
- function startUrlWatcher(url, cb, options = {}) {
127
- const { log = {
128
- info: console.log,
129
- error: console.log
130
- }, intervalMs = URL_WATCHER_INTERVAL_MS, timeoutMs = URL_WATCHER_TIMEOUT_MS, initialBody } = options;
131
- let lastBody = initialBody;
132
- let offline = false;
133
- let timer = null;
134
- let controller = null;
135
- let stopped = false;
136
- const stop = () => {
137
- stopped = true;
138
- if (timer) clearTimeout(timer);
139
- controller?.abort();
140
- };
141
- node_process.default.once("SIGINT", stop);
142
- node_process.default.once("SIGTERM", stop);
143
- const runBuild = createSerialRunner({
144
- run: () => cb([url]),
145
- onError: () => log.error((0, node_util.styleText)("red", "Watcher failed"))
146
- });
147
- const schedule = () => {
148
- if (!stopped) timer = setTimeout(() => void poll(), intervalMs);
149
- };
150
- const poll = async () => {
151
- controller = new AbortController();
152
- const body = await fetchUrlBody(url, AbortSignal.any([controller.signal, AbortSignal.timeout(timeoutMs)]));
153
- if (body === void 0) {
154
- if (!offline && !stopped) {
155
- offline = true;
156
- log.error((0, node_util.styleText)("red", `Cannot reach ${url}, polling until it responds again`));
157
- }
158
- schedule();
159
- return;
160
- }
161
- if (offline) {
162
- offline = false;
163
- log.info((0, node_util.styleText)("yellow", `${url} is reachable again`));
164
- }
165
- const changed = lastBody !== void 0 && body !== lastBody;
166
- if (changed) log.info((0, node_util.styleText)("yellow", (0, node_util.styleText)("bold", `Change detected: ${url}`)));
167
- if (changed || lastBody === void 0) runBuild();
168
- lastBody = body;
169
- schedule();
170
- };
171
- poll();
172
- return stop;
173
- }
174
- //#endregion
175
- //#region src/runners/generate/run.ts
176
- /** NPM registry endpoint used to check for @kubb/cli updates. */
177
- const KUBB_NPM_PACKAGE_URL = "https://registry.npmjs.org/@kubb/cli/latest";
178
- /** Upper bound in milliseconds for the npm update check, so a slow registry never stalls a run. */
179
- const UPDATE_CHECK_TIMEOUT_MS = 3e3;
180
- async function generate(options) {
181
- const { input, hooks, dryRun = false } = options;
182
- const report = require_Telemetry.trackRun({
183
- command: "generate",
184
- hrStart: node_process.default.hrtime()
185
- });
186
- const config = {
187
- ...options.config,
188
- input: input ?? options.config.input,
189
- storage: dryRun ? (0, _kubb_core.memoryStorage)() : options.config.storage,
190
- output: dryRun ? {
191
- ...options.config.output,
192
- format: false,
193
- lint: false,
194
- postGenerate: []
195
- } : options.config.output
196
- };
197
- const kubb = (0, _kubb_core.createKubb)(config, { hooks });
198
- const result = await kubb.generate();
199
- if (dryRun) await hooks.callHook("kubb:info", {
200
- message: "Dry run: no files were written",
201
- info: `${result.files.length} file(s) would be generated`
202
- });
203
- await report({
204
- plugins: kubb.config.plugins.flatMap((p) => p && typeof p === "object" ? [{
205
- name: p.meta?.name ?? p.name ?? "",
206
- options: p.options ?? {}
207
- }] : []),
208
- filesCreated: result.files.length,
209
- status: result.success ? "success" : "failed"
210
- });
211
- return result.success;
212
- }
213
- async function checkForUpdate(hooks) {
214
- try {
215
- const data = await (await fetch(KUBB_NPM_PACKAGE_URL, { signal: AbortSignal.timeout(UPDATE_CHECK_TIMEOUT_MS) })).json();
216
- if (data.version && require_registry.isOutdated({
217
- installed: require_Telemetry.version,
218
- latest: data.version
219
- })) await _kubb_core.Diagnostics.emit(hooks, _kubb_core.Diagnostics.update({
220
- currentVersion: require_Telemetry.version,
221
- latestVersion: data.version
222
- }));
223
- } catch {}
224
- }
225
- /**
226
- * Runs the full Kubb generation lifecycle for the given CLI options.
227
- * Loads configs, sets up the reporters (CLI `--reporter` picks which of `config.reporters` to trigger),
228
- * checks for a newer version, and calls `generate` for each config entry.
229
- */
230
- async function run({ input, configPath, logLevel: logLevelKey, watch, reporters: cliReporters, dryRun }) {
231
- const logLevel = _kubb_core.logLevel[logLevelKey] ?? _kubb_core.logLevel.info;
232
- const hooks = new _kubb_core.Hookable();
233
- const requestedNames = cliReporters?.length ? cliReporters : ["cli"];
234
- const json = requestedNames.includes("json");
235
- const quiet = logLevel <= _kubb_core.logLevel.silent || json;
236
- const errorHooks = json ? new _kubb_core.Hookable() : hooks;
237
- if (json) require_config.setupReporters(errorHooks, {
238
- logLevel,
239
- reporters: [_kubb_core.cliReporter],
240
- logger: require_output.createPlainLogger(console.error)
241
- });
242
- if (!quiet) {
243
- require_output.logBanner(require_Telemetry.version);
244
- require_output.logIntro({ title: "Configuration" });
245
- }
246
- const configSpinner = require_output.createSpinner();
247
- let configs;
248
- let resolvedConfigPath;
249
- try {
250
- if (!quiet) configSpinner.start("Loading config");
251
- const loaded = await require_config.getConfigs({
252
- configPath,
253
- input,
254
- watch,
255
- logLevel: logLevelKey
256
- });
257
- configs = loaded.configs;
258
- resolvedConfigPath = loaded.configPath;
259
- if (!quiet) configSpinner.stop(`Loaded ${(0, node_util.styleText)("dim", node_path.default.relative(node_process.default.cwd(), resolvedConfigPath))}`);
260
- } catch (error) {
261
- if (!quiet) configSpinner.error("Config failed loading");
262
- if (!json) require_config.setupReporters(hooks, {
263
- logLevel,
264
- reporters: [_kubb_core.cliReporter]
265
- });
266
- await _kubb_core.Diagnostics.emit(errorHooks, error);
267
- if (!quiet) require_output.logOutro((0, node_util.styleText)("red", "✗ Configuration failed"));
268
- node_process.default.exit(1);
269
- }
270
- const available = configs[0]?.reporters?.length ? configs[0].reporters : [
271
- _kubb_core.cliReporter,
272
- _kubb_core.jsonReporter,
273
- _kubb_core.fileReporter,
274
- _kubb_core.htmlReporter
275
- ];
276
- const reporters = require_config.selectReporters(available, requestedNames);
277
- require_config.setupReporters(hooks, {
278
- logLevel,
279
- reporters
280
- });
281
- await hooks.callHook("kubb:lifecycle:start", { version: require_Telemetry.version });
282
- await checkForUpdate(hooks);
283
- if (!quiet) require_output.logOutro(`${require_output.pluralize(configs.length, "config")} ready`);
284
- try {
285
- let anyFailed = false;
286
- for (const config of configs) {
287
- const effectiveInput = input ?? config.input;
288
- const inputKind = typeof effectiveInput === "string" ? (0, _kubb_core.getInputKind)(effectiveInput) : void 0;
289
- const watchPath = inputKind === "file" || inputKind === "url" ? effectiveInput : void 0;
290
- if (watchPath && watch) {
291
- const watchedPaths = [watchPath];
292
- const build = async (paths) => {
293
- const succeeded = await generate({
294
- input,
295
- config,
296
- hooks,
297
- dryRun
298
- });
299
- require_output.logStep((0, node_util.styleText)("yellow", `Watching for changes in ${paths.join(" and ")}`));
300
- if (succeeded) {
301
- require_output.logSpacer();
302
- require_output.logTip();
303
- }
304
- };
305
- const initialBody = inputKind === "url" ? await fetchUrlBody(watchPath) : void 0;
306
- try {
307
- await build(watchedPaths);
308
- } catch (buildError) {
309
- await _kubb_core.Diagnostics.emit(errorHooks, buildError);
310
- }
311
- if (inputKind === "url") startUrlWatcher(watchPath, build, {
312
- log: {
313
- info: require_output.logInfo,
314
- error: require_output.logError
315
- },
316
- initialBody
317
- });
318
- else await startWatcher(watchedPaths, build, {
319
- info: require_output.logInfo,
320
- error: require_output.logError
321
- });
322
- } else try {
323
- if (!await generate({
324
- input,
325
- config,
326
- hooks,
327
- dryRun
328
- })) anyFailed = true;
329
- } catch (configError) {
330
- await _kubb_core.Diagnostics.emit(errorHooks, configError);
331
- anyFailed = true;
332
- }
333
- }
334
- await hooks.callHook("kubb:lifecycle:end");
335
- if (!quiet && !watch && !anyFailed) require_output.logTip();
336
- if (anyFailed) node_process.default.exit(1);
337
- } catch (error) {
338
- await _kubb_core.Diagnostics.emit(errorHooks, error);
339
- node_process.default.exit(1);
340
- }
341
- }
342
- //#endregion
343
- exports.run = run;
344
-
345
- //# sourceMappingURL=run-hgSZImuK.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run-hyi91b22.cjs","names":["toError","styleText","trackRun","process","memoryStorage","createKubb","isOutdated","version","Diagnostics","logLevelMap","Hookable","cliReporter","createPlainLogger","createSpinner","getConfigs","styleText","path","jsonReporter","fileReporter","htmlReporter","selectReporters","pluralize","getInputKind","logInfo","logError"],"sources":["../src/runners/generate/utils.ts","../src/runners/generate/run.ts"],"sourcesContent":["import process from 'node:process'\nimport { styleText } from 'node:util'\nimport { toError } from '@internals/utils'\n\n/** Glob pattern for paths the file watcher ignores. */\nconst WATCHER_IGNORED_PATHS = '**/{.git,node_modules}/**' as const\n\n/**\n * Quiet window in milliseconds that collapses a burst of watcher events (an editor save emits several) into one rebuild.\n * It outlasts chokidar's 100 ms atomic-save window, which holds back the event of a write-then-rename save.\n */\nconst WATCHER_DEBOUNCE_MS = 250\n\n/** Interval in milliseconds between polls of a remote `input` URL in watch mode, which emits no filesystem events. */\nconst URL_WATCHER_INTERVAL_MS = 2_000\n\n/** Upper bound in milliseconds for one URL watcher request, headers and body read, so a hung server never stalls polling. */\nconst URL_WATCHER_TIMEOUT_MS = 10_000\n\ntype SerialRunnerOptions = {\n /**\n * The async work to serialize.\n */\n run(): Promise<void>\n /**\n * Receives errors thrown by `run`, so a failure never rejects the returned trigger.\n */\n onError(error: Error): void\n}\n\n/**\n * Wraps `run` so invocations never overlap: a trigger that lands while a run is in flight\n * marks it dirty and runs once more after it finishes, no matter how many triggers arrived.\n * Useful for event-driven reruns (a file watcher, a queue drain) where bursts should\n * coalesce into a single trailing run.\n *\n * @example\n * ```ts\n * const rebuild = createSerialRunner({\n * run: () => build(),\n * onError: (error) => log.error(error.message),\n * })\n * watcher.on('change', () => void rebuild())\n * ```\n */\nexport function createSerialRunner({ run, onError }: SerialRunnerOptions): () => Promise<void> {\n let running = false\n let dirty = false\n\n return async (): Promise<void> => {\n if (running) {\n dirty = true\n return\n }\n running = true\n do {\n dirty = false\n try {\n await run()\n } catch (error) {\n onError(toError(error))\n }\n } while (dirty)\n running = false\n }\n}\n\ntype WatcherLog = {\n info: (message: string) => void\n error: (message: string) => void\n}\n\n/**\n * Starts a file watcher on the given paths and calls `cb` on any change.\n * Ignores `.git` and `node_modules` directories. Event bursts (an editor save emits several)\n * are debounced into one build, and builds never overlap: changes during a build queue exactly\n * one rebuild. Resolves to a function that stops watching.\n */\nexport async function startWatcher(\n path: Array<string>,\n cb: (path: Array<string>) => Promise<void>,\n log: WatcherLog = { info: console.log, error: console.log },\n): Promise<() => Promise<void>> {\n const { watch } = await import('chokidar')\n // `ignoreInitial` skips the `add` events chokidar fires for existing files at startup, which\n // would otherwise rebuild right after the initial run.\n const watcher = watch(path, { ignorePermissionErrors: true, ignored: WATCHER_IGNORED_PATHS, ignoreInitial: true })\n\n process.once('SIGINT', () => {\n watcher.close()\n })\n process.once('SIGTERM', () => {\n watcher.close()\n })\n\n // Bursts never overlap builds on the shared hooks emitter: a change during a build\n // queues exactly one rerun.\n const runBuild = createSerialRunner({\n run: () => cb(path),\n onError: () => log.error(styleText('red', 'Watcher failed')),\n })\n let debounceTimer: ReturnType<typeof setTimeout> | null = null\n\n watcher.on('all', (type, file) => {\n log.info(styleText('yellow', styleText('bold', `Change detected: ${type} ${file}`)))\n if (debounceTimer) clearTimeout(debounceTimer)\n debounceTimer = setTimeout(() => {\n debounceTimer = null\n void runBuild()\n }, WATCHER_DEBOUNCE_MS)\n })\n\n return async () => {\n if (debounceTimer) clearTimeout(debounceTimer)\n await watcher.close()\n }\n}\n\n/**\n * Fetches the body of a remote spec URL, `undefined` when the server does not answer with a\n * readable 2xx body before `signal` aborts. The caller seeds `startUrlWatcher` with the result, so\n * the watcher compares polls against the content the initial build ran on.\n */\nexport async function fetchUrlBody(url: string, signal: AbortSignal = AbortSignal.timeout(URL_WATCHER_TIMEOUT_MS)): Promise<string | undefined> {\n try {\n const response = await fetch(url, { signal })\n if (!response.ok) return undefined\n return await response.text()\n } catch {\n return undefined\n }\n}\n\ntype UrlWatcherOptions = {\n /**\n * Sink for watcher messages, `console.log` by default.\n */\n log?: WatcherLog\n /**\n * Time in milliseconds between polls.\n */\n intervalMs?: number\n /**\n * Upper bound in milliseconds for one poll request, covering headers and body read.\n */\n timeoutMs?: number\n /**\n * Body the initial build ran against, the baseline for change detection. When omitted (the\n * server was unreachable at startup), the first successful poll rebuilds so the output catches\n * up as soon as the server responds.\n */\n initialBody?: string\n}\n\n/**\n * Polls a remote spec URL and calls `cb` whenever the response body changes. A remote document\n * emits no filesystem events, so this is the URL counterpart of `startWatcher`.\n *\n * `initialBody` seeds the change detection, so an edit landing between the initial build and the\n * first poll still rebuilds. An unreachable server (the API restarting between saves) is reported\n * once per outage and polling continues; after it recovers, a rebuild happens only when the body\n * actually differs from the last one seen, so a plain restart with an unchanged spec stays quiet.\n * Each request is aborted after `timeoutMs`, so a hung response delays at most one poll.\n *\n * Returns a function that stops polling and aborts the in-flight request, so callers (and tests)\n * can shut the watcher down without signaling the process.\n */\nexport function startUrlWatcher(url: string, cb: (path: Array<string>) => Promise<void>, options: UrlWatcherOptions = {}): () => void {\n const { log = { info: console.log, error: console.log }, intervalMs = URL_WATCHER_INTERVAL_MS, timeoutMs = URL_WATCHER_TIMEOUT_MS, initialBody } = options\n\n let lastBody = initialBody\n let offline = false\n let timer: ReturnType<typeof setTimeout> | null = null\n let controller: AbortController | null = null\n let stopped = false\n\n const stop = () => {\n stopped = true\n if (timer) clearTimeout(timer)\n controller?.abort()\n }\n process.once('SIGINT', stop)\n process.once('SIGTERM', stop)\n\n // Builds never overlap on the shared hooks emitter: a change during a build queues exactly\n // one rerun.\n const runBuild = createSerialRunner({\n run: () => cb([url]),\n onError: () => log.error(styleText('red', 'Watcher failed')),\n })\n\n const schedule = () => {\n if (!stopped) {\n timer = setTimeout(() => void poll(), intervalMs)\n }\n }\n\n const poll = async (): Promise<void> => {\n controller = new AbortController()\n // The signal also aborts the body read, so a response that stalls mid-stream still times out.\n const body = await fetchUrlBody(url, AbortSignal.any([controller.signal, AbortSignal.timeout(timeoutMs)]))\n\n if (body === undefined) {\n // `lastBody` survives the outage so recovery rebuilds only on real content changes.\n if (!offline && !stopped) {\n offline = true\n log.error(styleText('red', `Cannot reach ${url}, polling until it responds again`))\n }\n schedule()\n return\n }\n\n if (offline) {\n offline = false\n log.info(styleText('yellow', `${url} is reachable again`))\n }\n const changed = lastBody !== undefined && body !== lastBody\n if (changed) {\n log.info(styleText('yellow', styleText('bold', `Change detected: ${url}`)))\n }\n if (changed || lastBody === undefined) {\n void runBuild()\n }\n lastBody = body\n schedule()\n }\n\n void poll()\n\n return stop\n}\n","import path from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { formatters, 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 '../../loggers/createLogger.ts'\nimport setupReporters, { selectReporters } from '../../loggers/reporters.ts'\nimport { createPlainLogger } from '../../loggers/plainLogger.ts'\nimport { createSpinner, logBanner, logError, logInfo, logIntro, logOutro, logSpacer, logStep, logTip } from '../../loggers/output.ts'\nimport { getConfigs } from '../../config.ts'\nimport { isOutdated } from '../../utils/registry.ts'\nimport { fetchUrlBody, startUrlWatcher, startWatcher } 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, and skips formatting, linting,\n * and post-generate commands.\n */\n dryRun?: boolean\n}\n\nasync 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 if (dryRun) {\n await hooks.callHook('kubb:info', { message: 'Dry run: no files were written', info: `${result.files.length} file(s) would be generated` })\n }\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\nasync function checkForUpdate(hooks: Hookable<KubbHooks>): Promise<void> {\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 if (data.version && isOutdated({ installed: version, latest: data.version })) {\n await Diagnostics.emit(hooks, Diagnostics.update({ currentVersion: version, latestVersion: data.version }))\n }\n } catch {\n // Ignore network errors\n }\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 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], logger: createPlainLogger(console.error) })\n\n if (!quiet) {\n logBanner(version)\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 getConfigs({\n configPath,\n input,\n watch,\n logLevel: logLevelKey as CLIOptions['logLevel'],\n })\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 })\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)\n\n if (!quiet) logOutro(`${pluralize(configs.length, 'config')} ready`)\n\n try {\n let anyFailed = false\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' || inputKind === 'url' ? (effectiveInput as string) : undefined\n if (watchPath && watch) {\n const watchedPaths = [watchPath]\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 (paths: Array<string>) => {\n const succeeded = await generate({ input, config, hooks, dryRun })\n logStep(styleText('yellow', `Watching for changes in ${paths.join(' and ')}`))\n if (succeeded) {\n logSpacer()\n logTip()\n }\n }\n\n // For a URL input, capture the document before the build: it becomes the watcher's\n // change-detection baseline, so an edit landing before the first poll still rebuilds.\n // When the server is down the baseline stays undefined and the watcher rebuilds on its\n // first successful poll, so recovery with an unchanged document still generates output.\n const initialBody = inputKind === 'url' ? await fetchUrlBody(watchPath) : undefined\n\n // The watchers ignore their startup state, so run the first build here; a failing one keeps watching so the user can fix the input.\n try {\n await build(watchedPaths)\n } catch (buildError) {\n await Diagnostics.emit(errorHooks, buildError)\n }\n\n if (inputKind === 'url') {\n startUrlWatcher(watchPath, build, { log: { info: logInfo, error: logError }, initialBody })\n } else {\n await startWatcher(watchedPaths, build, { info: logInfo, error: logError })\n }\n } else {\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,264 +0,0 @@
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
- const require_config = require("./config-OL_izsmp.cjs");
5
- const require_run = require("./run-CSOEGpWZ.cjs");
6
- let node_util = require("node:util");
7
- let node_process = require("node:process");
8
- node_process = require_rolldown_runtime.__toESM(node_process, 1);
9
- let node_fs_promises = require("node:fs/promises");
10
- let node_path = require("node:path");
11
- let _kubb_core = require("@kubb/core");
12
- let node_fs = require("node:fs");
13
- let _kubb_studio = require("@kubb/studio");
14
- //#region ../../internals/utils/src/fs.ts
15
- /**
16
- * Reads the file at `path` as a UTF-8 string.
17
- * Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
18
- *
19
- * @example
20
- * ```ts
21
- * const source = await read('./src/Pet.ts')
22
- * ```
23
- */
24
- async function read(path) {
25
- if (require_Telemetry.runtime.isBun) return Bun.file(path).text();
26
- return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
27
- }
28
- //#endregion
29
- //#region src/runners/studio/ci.ts
30
- function readGithubPullRequest(eventPath) {
31
- if (!eventPath) return;
32
- try {
33
- const event = JSON.parse((0, node_fs.readFileSync)(eventPath, "utf8"));
34
- return event.pull_request?.number ? event.pull_request : void 0;
35
- } catch {
36
- return;
37
- }
38
- }
39
- /** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */
40
- function gitlabRefSlug(ref) {
41
- return ref.toLowerCase().replace(/[^a-z0-9]/gu, "-").slice(0, 63).replace(/^-+|-+$/g, "");
42
- }
43
- /**
44
- * Detects the CI provider from its environment variables and derives a stable identity from it.
45
- * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
46
- * always registered agents under, so an existing repository keeps reusing its agent.
47
- */
48
- function detectCi(env = node_process.default.env) {
49
- if (env.GITHUB_ACTIONS) {
50
- const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
51
- const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
52
- const branch = env.GITHUB_REF?.startsWith("refs/heads/") ? env.GITHUB_REF.slice(11) : void 0;
53
- const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? "";
54
- const baseBranch = pullRequest?.base?.ref;
55
- return {
56
- id: `gh:${repositoryId}:${scope}`,
57
- name: `${env.GITHUB_REPOSITORY ?? "github"}#${pullRequest?.number ?? branch ?? scope}`,
58
- commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,
59
- base: baseBranch ? {
60
- branch: baseBranch,
61
- id: `gh:${repositoryId}:refs/heads/${baseBranch}`
62
- } : void 0
63
- };
64
- }
65
- if (env.GITLAB_CI) {
66
- const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
67
- const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
68
- return {
69
- id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
70
- name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
71
- commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,
72
- base: baseBranch ? {
73
- branch: baseBranch,
74
- id: `gl:${env.CI_PROJECT_ID ?? ""}:${gitlabRefSlug(baseBranch)}`
75
- } : void 0
76
- };
77
- }
78
- if (env.BITBUCKET_BUILD_NUMBER) {
79
- const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? "";
80
- return {
81
- id: `bb:${env.BITBUCKET_REPO_UUID ?? ""}:${scope}`,
82
- name: `${env.BITBUCKET_REPO_FULL_NAME ?? "bitbucket"}#${scope}`,
83
- commit: env.BITBUCKET_COMMIT
84
- };
85
- }
86
- if (env.CIRCLECI) {
87
- const owner = env.CIRCLE_PROJECT_USERNAME ?? "";
88
- const project = env.CIRCLE_PROJECT_REPONAME ?? "circleci";
89
- const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? "";
90
- return {
91
- id: `circle:${owner}:${project}:${scope}`,
92
- name: `${owner ? `${owner}/` : ""}${project}#${scope}`,
93
- commit: env.CIRCLE_SHA1
94
- };
95
- }
96
- return null;
97
- }
98
- //#endregion
99
- //#region src/runners/studio/snapshot.ts
100
- /**
101
- * Walks up from `directory` to the first package.json with a name and a version.
102
- */
103
- async function findPackageJson(directory) {
104
- const packageJson = JSON.parse(await read((0, node_path.join)(directory, "package.json")).catch(() => "{}"));
105
- if (packageJson.name && packageJson.version) return {
106
- name: packageJson.name,
107
- version: packageJson.version
108
- };
109
- const parent = (0, node_path.dirname)(directory);
110
- if (parent === directory) throw new _kubb_core.Diagnostics.Error({
111
- code: _kubb_core.Diagnostics.code.unknown,
112
- severity: "error",
113
- message: `No package.json with a name and a version found above ${node_process.default.cwd()}`,
114
- help: "Pass `--name` and `--version`, or run from a package with a package.json."
115
- });
116
- return findPackageJson(parent);
117
- }
118
- /** Reads package.json only for whichever of name/version --name and --version did not supply. */
119
- async function resolvePackageMetadata(options) {
120
- if (options.name && options.packageVersion) return {
121
- name: options.name,
122
- version: options.packageVersion
123
- };
124
- const found = await findPackageJson(node_process.default.cwd());
125
- return {
126
- name: options.name ?? found.name,
127
- version: options.packageVersion ?? found.version
128
- };
129
- }
130
- function resolveToken(options) {
131
- const token = options.token ?? node_process.default.env.KUBB_TOKEN;
132
- if (!token) throw new _kubb_core.Diagnostics.Error({
133
- code: _kubb_core.Diagnostics.code.unknown,
134
- severity: "error",
135
- message: "An organization CI API key is required. Pass --token or set KUBB_TOKEN."
136
- });
137
- return token;
138
- }
139
- function resolveCiIdentity(options) {
140
- const detected = detectCi();
141
- const ci = options.id ? {
142
- id: options.id,
143
- name: detected?.name ?? options.id,
144
- commit: detected?.commit
145
- } : detected;
146
- if (!ci) throw new _kubb_core.Diagnostics.Error({
147
- code: _kubb_core.Diagnostics.code.unknown,
148
- severity: "error",
149
- message: "Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id."
150
- });
151
- const base = options.baseId ? {
152
- branch: options.baseId,
153
- id: options.baseId
154
- } : ci.base;
155
- return {
156
- ...ci,
157
- base: base?.id === ci.id ? void 0 : base
158
- };
159
- }
160
- function absoluteUrl(studioUrl, path) {
161
- return new URL(path, `${studioUrl}/`).toString();
162
- }
163
- function toResult({ studioUrl, snapshot, ci }) {
164
- return {
165
- id: snapshot.id,
166
- name: snapshot.name,
167
- version: snapshot.version,
168
- integrity: snapshot.integrity,
169
- url: absoluteUrl(studioUrl, snapshot.url),
170
- snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
171
- expiresAt: snapshot.expiresAt,
172
- agentUrl: absoluteUrl(studioUrl, `/agents/${snapshot.agent.slug ?? snapshot.agent.id}`),
173
- changes: snapshot.changes,
174
- branchChanges: snapshot.branchChanges && ci.base ? {
175
- ...snapshot.branchChanges,
176
- branch: ci.base.branch
177
- } : void 0
178
- };
179
- }
180
- /** How many files differ, `against` what. */
181
- function describeChanges(changes, against) {
182
- const { added, changed, removed } = changes;
183
- return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
184
- }
185
- /** One summary line: how many files changed, and since which run. */
186
- function formatChanges(changes) {
187
- if (!changes.base) return "First snapshot";
188
- return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
189
- }
190
- /** One summary line: how the snapshot differs from the base branch's latest one. */
191
- function formatBranchChanges(changes) {
192
- if (changes.base) return describeChanges(changes, `against ${changes.branch}`);
193
- return changes.baseFound ? `No snapshot of ${changes.branch} for this package yet` : `No snapshot of ${changes.branch} to compare with`;
194
- }
195
- function printSummary(result) {
196
- require_output.logBlock([
197
- `${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
198
- `${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
199
- `${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
200
- ...result.branchChanges ? [`${(0, node_util.styleText)("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
201
- ...result.changes ? [`${(0, node_util.styleText)("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
202
- `${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
203
- ]);
204
- }
205
- /**
206
- * Generates the project, packs it, and publishes it to Kubb Studio in one request, under the CI
207
- * agent the run's identity names.
208
- */
209
- async function snapshot(options) {
210
- const token = resolveToken(options);
211
- const { config } = await require_run.loadConfigs(options);
212
- const ci = resolveCiIdentity(options);
213
- const { name, version: packageVersion } = await resolvePackageMetadata(options);
214
- const logLevel = _kubb_core.logLevel[options.logLevel ?? "info"];
215
- const write = options.json ? (line) => console.error(line) : (line) => console.log(line);
216
- const hooks = new _kubb_core.Hookable();
217
- require_config.setupReporters(hooks, {
218
- logLevel,
219
- reporters: [_kubb_core.cliReporter],
220
- logger: require_output.createPlainLogger(write)
221
- });
222
- const step = (message) => {
223
- if (logLevel > _kubb_core.logLevel.silent) write(message);
224
- };
225
- step("Generating the snapshot");
226
- try {
227
- const published = await (0, _kubb_studio.createSnapshot)({
228
- studioUrl: options.studioUrl,
229
- apiKey: token,
230
- config,
231
- hooks,
232
- id: ci.id,
233
- name: ci.name,
234
- packageName: name,
235
- version: packageVersion,
236
- commit: ci.commit,
237
- baseId: ci.base?.id
238
- });
239
- const result = toResult({
240
- studioUrl: options.studioUrl,
241
- snapshot: published,
242
- ci
243
- });
244
- step("Snapshot published");
245
- if (options.json) console.log(JSON.stringify(result));
246
- if (!options.json) printSummary(result);
247
- } catch (error) {
248
- step("Snapshot failed");
249
- throw error;
250
- }
251
- }
252
- const runner = ({ values }) => require_run.runStudio(values, (options) => snapshot({
253
- ...options,
254
- token: values.token,
255
- id: values.id,
256
- baseId: values.baseId,
257
- name: values.name,
258
- packageVersion: values.packageVersion,
259
- json: values.json
260
- }), { json: values.json });
261
- //#endregion
262
- exports.runner = runner;
263
-
264
- //# sourceMappingURL=snapshot-DP9Pcnsg.cjs.map