@kubb/cli 5.3.15 → 5.3.17

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 (70) hide show
  1. package/dist/{connect-CgkbDN1-.js → connect-DQWYjheY.js} +2 -2
  2. package/dist/{connect-CgkbDN1-.js.map → connect-DQWYjheY.js.map} +1 -1
  3. package/dist/{connect-B4NIfpxC.cjs → connect-c9W1razJ.cjs} +2 -2
  4. package/dist/{connect-B4NIfpxC.cjs.map → connect-c9W1razJ.cjs.map} +1 -1
  5. package/dist/{generate-D3l-s7Vh.js → generate-BSnIzFH0.js} +2 -2
  6. package/dist/{generate-D3l-s7Vh.js.map → generate-BSnIzFH0.js.map} +1 -1
  7. package/dist/{generate-CGVdHu45.cjs → generate-BoamktRp.cjs} +2 -2
  8. package/dist/{generate-CGVdHu45.cjs.map → generate-BoamktRp.cjs.map} +1 -1
  9. package/dist/index.cjs +7 -7
  10. package/dist/index.js +7 -7
  11. package/dist/{init-B40Y8E7d.cjs → init--iLsTi1X.cjs} +2 -2
  12. package/dist/{init-B40Y8E7d.cjs.map → init--iLsTi1X.cjs.map} +1 -1
  13. package/dist/{init-BtNySVze.js → init-C6AZG9IZ.js} +2 -2
  14. package/dist/{init-BtNySVze.js.map → init-C6AZG9IZ.js.map} +1 -1
  15. package/dist/{login-VlfI9Xcv.js → login-Bkm0Bcwh.js} +2 -2
  16. package/dist/{login-VlfI9Xcv.js.map → login-Bkm0Bcwh.js.map} +1 -1
  17. package/dist/{login-CcYnvzn9.cjs → login-DICKtsMS.cjs} +2 -2
  18. package/dist/{login-CcYnvzn9.cjs.map → login-DICKtsMS.cjs.map} +1 -1
  19. package/dist/{logout-BNlPXi-7.js → logout-CCAt5yNI.js} +2 -2
  20. package/dist/{logout-BNlPXi-7.js.map → logout-CCAt5yNI.js.map} +1 -1
  21. package/dist/{logout-Bzlys_F2.cjs → logout-Cq_SjOQf.cjs} +2 -2
  22. package/dist/{logout-Bzlys_F2.cjs.map → logout-Cq_SjOQf.cjs.map} +1 -1
  23. package/dist/{package-Bd8xo-XX.cjs → package-Bpz2OqOp.cjs} +2 -2
  24. package/dist/package-Bpz2OqOp.cjs.map +1 -0
  25. package/dist/package-CO6hZYJK.js +6 -0
  26. package/dist/package-CO6hZYJK.js.map +1 -0
  27. package/dist/{run-CmB0Bnby.cjs → run-CHG7Y4OF.cjs} +2 -2
  28. package/dist/{run-CmB0Bnby.cjs.map → run-CHG7Y4OF.cjs.map} +1 -1
  29. package/dist/{run-DyXw4hZU.js → run-CQmDghzm.js} +3 -3
  30. package/dist/{run-DyXw4hZU.js.map → run-CQmDghzm.js.map} +1 -1
  31. package/dist/{run-Dcv_CGTV.cjs → run-Cx_Biqws.cjs} +2 -2
  32. package/dist/{run-Dcv_CGTV.cjs.map → run-Cx_Biqws.cjs.map} +1 -1
  33. package/dist/{run-CqNGsZW4.js → run-D5DrRIpE.js} +2 -2
  34. package/dist/{run-CqNGsZW4.js.map → run-D5DrRIpE.js.map} +1 -1
  35. package/dist/{run-BHMnPdul.js → run-DgJoQeWU.js} +18 -19
  36. package/dist/run-DgJoQeWU.js.map +1 -0
  37. package/dist/{run-2VumfVcx.js → run-Dq11mN4W.js} +2 -2
  38. package/dist/{run-2VumfVcx.js.map → run-Dq11mN4W.js.map} +1 -1
  39. package/dist/{run-DqZ334j3.cjs → run-QtVt-csj.cjs} +3 -3
  40. package/dist/{run-DqZ334j3.cjs.map → run-QtVt-csj.cjs.map} +1 -1
  41. package/dist/{run-DYmx4BUd.cjs → run-fLBpH170.cjs} +17 -18
  42. package/dist/run-fLBpH170.cjs.map +1 -0
  43. package/dist/{snapshot-C2dbvseU.cjs → snapshot-BTM3dE9L.cjs} +126 -64
  44. package/dist/snapshot-BTM3dE9L.cjs.map +1 -0
  45. package/dist/{snapshot-CWZAiRmb.js → snapshot-Bxlj-1OJ.js} +129 -67
  46. package/dist/snapshot-Bxlj-1OJ.js.map +1 -0
  47. package/dist/{status-D9O6D20d.cjs → status-BxUqzCGT.cjs} +2 -2
  48. package/dist/{status-D9O6D20d.cjs.map → status-BxUqzCGT.cjs.map} +1 -1
  49. package/dist/{status-CKhgk59o.js → status-QnFiAJK0.js} +2 -2
  50. package/dist/{status-CKhgk59o.js.map → status-QnFiAJK0.js.map} +1 -1
  51. package/dist/{studio-D_bRD3nc.cjs → studio-BeOQYXoh.cjs} +12 -7
  52. package/dist/studio-BeOQYXoh.cjs.map +1 -0
  53. package/dist/{studio-DFZKPTAs.js → studio-C2FsZ4zt.js} +12 -7
  54. package/dist/studio-C2FsZ4zt.js.map +1 -0
  55. package/dist/{utils-CyfAlK9G.cjs → utils-DqUNntyL.cjs} +34 -17
  56. package/dist/utils-DqUNntyL.cjs.map +1 -0
  57. package/dist/{utils-LvEYQf9I.js → utils-TpILNAy7.js} +29 -18
  58. package/dist/utils-TpILNAy7.js.map +1 -0
  59. package/package.json +7 -7
  60. package/dist/package-79jTR7nF.js +0 -6
  61. package/dist/package-79jTR7nF.js.map +0 -1
  62. package/dist/package-Bd8xo-XX.cjs.map +0 -1
  63. package/dist/run-BHMnPdul.js.map +0 -1
  64. package/dist/run-DYmx4BUd.cjs.map +0 -1
  65. package/dist/snapshot-C2dbvseU.cjs.map +0 -1
  66. package/dist/snapshot-CWZAiRmb.js.map +0 -1
  67. package/dist/studio-DFZKPTAs.js.map +0 -1
  68. package/dist/studio-D_bRD3nc.cjs.map +0 -1
  69. package/dist/utils-CyfAlK9G.cjs.map +0 -1
  70. package/dist/utils-LvEYQf9I.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
2
- const require_run = require("./run-DYmx4BUd.cjs");
2
+ const require_run = require("./run-fLBpH170.cjs");
3
+ const require_utils = require("./utils-DqUNntyL.cjs");
3
4
  const require_output = require("./output-D-9bGS7y.cjs");
4
5
  let node_util = require("node:util");
5
6
  let node_process = require("node:process");
@@ -9,15 +10,19 @@ let node_fs = require("node:fs");
9
10
  let _kubb_core = require("@kubb/core");
10
11
  let _kubb_studio = require("@kubb/studio");
11
12
  //#region src/runners/studio/ci.ts
12
- function readGithubPullRequestNumber(eventPath) {
13
+ function readGithubPullRequest(eventPath) {
13
14
  if (!eventPath) return;
14
15
  try {
15
16
  const event = JSON.parse((0, node_fs.readFileSync)(eventPath, "utf8"));
16
- return event.pull_request?.number ? String(event.pull_request.number) : void 0;
17
+ return event.pull_request?.number ? event.pull_request : void 0;
17
18
  } catch {
18
19
  return;
19
20
  }
20
21
  }
22
+ /** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */
23
+ function gitlabRefSlug(ref) {
24
+ return ref.toLowerCase().replace(/[^a-z0-9]/gu, "-").slice(0, 63).replace(/^-+|-+$/g, "");
25
+ }
21
26
  /**
22
27
  * Detects the CI provider from its environment variables and derives a stable identity from it.
23
28
  * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
@@ -25,26 +30,40 @@ function readGithubPullRequestNumber(eventPath) {
25
30
  */
26
31
  function detectCi(env = node_process.default.env) {
27
32
  if (env.GITHUB_ACTIONS) {
28
- const pullRequestNumber = readGithubPullRequestNumber(env.GITHUB_EVENT_PATH);
33
+ const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
29
34
  const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
30
- const scope = pullRequestNumber ?? env.GITHUB_RUN_ID ?? "";
35
+ const branch = env.GITHUB_REF?.startsWith("refs/heads/") ? env.GITHUB_REF.slice(11) : void 0;
36
+ const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? "";
37
+ const baseBranch = pullRequest?.base?.ref;
31
38
  return {
32
39
  id: `gh:${repositoryId}:${scope}`,
33
- name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`
40
+ name: `${env.GITHUB_REPOSITORY ?? "github"}#${pullRequest?.number ?? branch ?? scope}`,
41
+ commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,
42
+ base: baseBranch ? {
43
+ branch: baseBranch,
44
+ id: `gh:${repositoryId}:refs/heads/${baseBranch}`
45
+ } : void 0
34
46
  };
35
47
  }
36
48
  if (env.GITLAB_CI) {
37
49
  const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
50
+ const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
38
51
  return {
39
52
  id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
40
- name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`
53
+ name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
54
+ commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,
55
+ base: baseBranch ? {
56
+ branch: baseBranch,
57
+ id: `gl:${env.CI_PROJECT_ID ?? ""}:${gitlabRefSlug(baseBranch)}`
58
+ } : void 0
41
59
  };
42
60
  }
43
61
  if (env.BITBUCKET_BUILD_NUMBER) {
44
62
  const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? "";
45
63
  return {
46
64
  id: `bb:${env.BITBUCKET_REPO_UUID ?? ""}:${scope}`,
47
- name: `${env.BITBUCKET_REPO_FULL_NAME ?? "bitbucket"}#${scope}`
65
+ name: `${env.BITBUCKET_REPO_FULL_NAME ?? "bitbucket"}#${scope}`,
66
+ commit: env.BITBUCKET_COMMIT
48
67
  };
49
68
  }
50
69
  if (env.CIRCLECI) {
@@ -53,7 +72,8 @@ function detectCi(env = node_process.default.env) {
53
72
  const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? "";
54
73
  return {
55
74
  id: `circle:${owner}:${project}:${scope}`,
56
- name: `${owner ? `${owner}/` : ""}${project}#${scope}`
75
+ name: `${owner ? `${owner}/` : ""}${project}#${scope}`,
76
+ commit: env.CIRCLE_SHA1
57
77
  };
58
78
  }
59
79
  return null;
@@ -110,12 +130,20 @@ function resolveToken(options) {
110
130
  }
111
131
  function resolveCiIdentity(options) {
112
132
  const detected = detectCi();
113
- if (options.id) return {
133
+ const ci = options.id ? {
114
134
  id: options.id,
115
- name: detected?.name ?? options.id
135
+ name: detected?.name ?? options.id,
136
+ commit: detected?.commit
137
+ } : detected;
138
+ if (!ci) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
139
+ const base = options.baseId ? {
140
+ branch: options.baseId,
141
+ id: options.baseId
142
+ } : ci.base;
143
+ return {
144
+ ...ci,
145
+ base: base?.id === ci.id ? void 0 : base
116
146
  };
117
- if (!detected) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
118
- return detected;
119
147
  }
120
148
  /** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
121
149
  function resolveTimeoutMs(options) {
@@ -131,7 +159,7 @@ function assertSecureStudioUrl(studioUrl) {
131
159
  function absoluteUrl(studioUrl, path) {
132
160
  return new URL(path, `${studioUrl}/`).toString();
133
161
  }
134
- function toResult(studioUrl, snapshot, agentSlug) {
162
+ function toResult(studioUrl, snapshot, agentSlug, ci) {
135
163
  return {
136
164
  id: snapshot.id,
137
165
  name: snapshot.name,
@@ -140,14 +168,35 @@ function toResult(studioUrl, snapshot, agentSlug) {
140
168
  url: absoluteUrl(studioUrl, snapshot.url),
141
169
  snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
142
170
  expiresAt: snapshot.expiresAt,
143
- agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`)
171
+ agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),
172
+ changes: snapshot.changes,
173
+ branchChanges: snapshot.branchChanges && ci.base ? {
174
+ ...snapshot.branchChanges,
175
+ branch: ci.base.branch
176
+ } : void 0
144
177
  };
145
178
  }
179
+ /** How many files differ, `against` what. */
180
+ function describeChanges(changes, against) {
181
+ const { added, changed, removed } = changes;
182
+ return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
183
+ }
184
+ /** One summary line: how many files changed, and since which run. */
185
+ function formatChanges(changes) {
186
+ if (!changes.base) return "First snapshot";
187
+ return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
188
+ }
189
+ /** One summary line: how the snapshot differs from the base branch's latest one. */
190
+ function formatBranchChanges(changes) {
191
+ return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`;
192
+ }
146
193
  function printSummary(result) {
147
194
  require_output.logBlock([
148
195
  `${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
149
196
  `${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
150
197
  `${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
198
+ ...result.branchChanges ? [`${(0, node_util.styleText)("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
199
+ ...result.changes ? [`${(0, node_util.styleText)("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
151
200
  `${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
152
201
  ]);
153
202
  }
@@ -163,84 +212,96 @@ async function snapshot(options) {
163
212
  const { configPath } = await require_run.loadConfigs(options);
164
213
  const ci = resolveCiIdentity(options);
165
214
  const { name, version: packageVersion } = await resolvePackageMetadata(options);
215
+ const logLevel = _kubb_core.logLevel[options.logLevel ?? "info"];
166
216
  node_process.default.env.KUBB_AGENT_SECRET = ci.id;
167
- const spinner = options.json ? null : require_output.createSpinner();
168
- const log = (message) => {
169
- if (options.json) {
170
- console.error(message);
171
- return;
172
- }
173
- spinner?.message(message);
217
+ const write = options.json ? (line) => console.error(line) : (line) => console.log(line);
218
+ const logger = require_utils.createPlainLogger(write);
219
+ const step = (message) => {
220
+ if (logLevel > _kubb_core.logLevel.silent) write(message);
174
221
  };
175
- if (options.json) log("Creating Kubb Studio agent");
176
- if (!options.json) spinner?.start("Creating Kubb Studio agent");
222
+ step("Creating Kubb Studio agent");
177
223
  const agent = await (0, _kubb_studio.createAgent)({
178
224
  studioUrl: options.studioUrl,
179
225
  token,
180
226
  name: ci.name,
181
227
  machineToken: (0, _kubb_studio.machineTokenFrom)(ci.id)
182
228
  });
183
- const { promise: ready, reject: markFailed, resolve: markReady } = Promise.withResolvers();
184
- const client = (0, _kubb_studio.createClient)({
185
- studioUrl: options.studioUrl,
186
- token: agent.token,
187
- configPath,
188
- root: node_process.default.cwd(),
189
- version: options.version,
190
- client: { kind: "cli" },
191
- logLevel: _kubb_core.logLevel[options.logLevel ?? "info"],
192
- loadConfig: async () => (await require_run.loadConfigs(options)).config,
193
- installLogger: (hooks) => {
194
- hooks.hook("studio:connecting", ({ url }) => log(`Connecting to Kubb Studio at ${url}`));
195
- hooks.hook("studio:connected", ({ url }) => log(`Connected to Kubb Studio at ${url}`));
196
- hooks.hook("studio:ready", () => {
197
- log("Kubb Studio connection ready");
198
- markReady();
199
- });
200
- hooks.hook("studio:warn", ({ message }) => log(`Kubb Studio warning: ${message}`));
201
- hooks.hook("studio:error", ({ error }) => markFailed(error));
202
- }
229
+ const { promise: ready, resolve: markReady } = Promise.withResolvers();
230
+ const shutdown = new AbortController();
231
+ const connection = (0, _kubb_studio.runConnection)({
232
+ credentials: { token: agent.token },
233
+ signal: shutdown.signal,
234
+ clientOptions: () => ({
235
+ studioUrl: options.studioUrl,
236
+ configPath,
237
+ root: node_process.default.cwd(),
238
+ version: options.version,
239
+ permissions: options.permission,
240
+ loadConfig: async () => (await require_run.loadConfigs(options)).config,
241
+ installLogger: async (hooks) => {
242
+ await require_utils.setupReporters(hooks, {
243
+ logLevel,
244
+ reporters: [_kubb_core.cliReporter],
245
+ logger
246
+ });
247
+ hooks.hook("studio:ready", () => markReady());
248
+ }
249
+ }),
250
+ onTokenRejected: ({ error }) => Promise.reject(error)
203
251
  });
204
- await client.connect();
252
+ const connectionLost = new AbortController();
253
+ const connectionEnded = /* @__PURE__ */ new Error("The Kubb Studio connection ended before the snapshot finished");
254
+ connection.then(() => connectionLost.abort(connectionEnded), (error) => connectionLost.abort(error));
255
+ const lost = connection.then(() => Promise.reject(connectionEnded), (error) => Promise.reject(error));
256
+ lost.catch(() => {});
205
257
  try {
206
- let readyTimeoutHandle;
258
+ let readyTimeout;
207
259
  try {
208
- await Promise.race([ready, new Promise((_, reject) => {
209
- readyTimeoutHandle = setTimeout(() => reject(/* @__PURE__ */ new Error("Timed out waiting for Kubb Studio to confirm the agent was ready")), READY_TIMEOUT_MS);
210
- })]);
260
+ await Promise.race([
261
+ ready,
262
+ lost,
263
+ new Promise((_, reject) => {
264
+ readyTimeout = setTimeout(() => reject(/* @__PURE__ */ new Error("Timed out waiting for Kubb Studio to confirm the agent was ready")), READY_TIMEOUT_MS);
265
+ })
266
+ ]);
211
267
  } finally {
212
- clearTimeout(readyTimeoutHandle);
268
+ clearTimeout(readyTimeout);
213
269
  }
214
- log("Creating snapshot job");
270
+ step("Creating snapshot job");
271
+ const snapshotDeadline = Date.now() + timeoutMs;
272
+ const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1);
215
273
  const job = await (0, _kubb_studio.createJob)({
216
274
  studioUrl: options.studioUrl,
217
275
  token,
218
276
  type: "snapshot",
219
277
  agentId: agent.id,
220
278
  name,
221
- version: packageVersion
279
+ version: packageVersion,
280
+ commit: ci.commit,
281
+ baseId: ci.base?.id,
282
+ timeoutMs: snapshotTimeoutMs(),
283
+ signal: connectionLost.signal
222
284
  });
223
- log(`Snapshot job queued: ${job.id}`);
224
- const finished = await (0, _kubb_studio.waitForJob)({
285
+ step(`Snapshot job queued: ${job.id}`);
286
+ const finished = await Promise.race([(0, _kubb_studio.waitForJob)({
225
287
  studioUrl: options.studioUrl,
226
288
  token,
227
289
  id: job.id,
228
- timeoutMs
229
- });
290
+ timeoutMs: snapshotTimeoutMs(),
291
+ signal: connectionLost.signal
292
+ }), lost]);
230
293
  if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
231
294
  if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
232
- const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
233
- if (options.json) log("Snapshot published");
234
- if (!options.json) spinner?.stop("Snapshot published");
295
+ const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci);
296
+ step("Snapshot published");
235
297
  if (options.json) console.log(JSON.stringify(result));
236
298
  if (!options.json) printSummary(result);
237
299
  } catch (error) {
238
- if (options.json) log("Snapshot failed");
239
- if (!options.json) spinner?.stop("Snapshot failed");
300
+ step("Snapshot failed");
240
301
  throw error;
241
302
  } finally {
242
- if (options.json) log("Disconnecting from Kubb Studio");
243
- client.disconnect();
303
+ step("Disconnecting from Kubb Studio");
304
+ shutdown.abort();
244
305
  }
245
306
  }
246
307
  const runner = async ({ values }) => {
@@ -248,6 +309,7 @@ const runner = async ({ values }) => {
248
309
  ...require_run.createStudioOptions(values),
249
310
  token: values.token,
250
311
  id: values.id,
312
+ baseId: values.baseId,
251
313
  name: values.name,
252
314
  packageVersion: values.packageVersion,
253
315
  timeout: values.timeout,
@@ -258,4 +320,4 @@ const runner = async ({ values }) => {
258
320
  //#endregion
259
321
  exports.runner = runner;
260
322
 
261
- //# sourceMappingURL=snapshot-C2dbvseU.cjs.map
323
+ //# sourceMappingURL=snapshot-BTM3dE9L.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-BTM3dE9L.cjs","names":["readFileSync","process","join","exists","read","dirname","process","styleText","loadConfigs","logLevelMap","createPlainLogger","createAgent","machineTokenFrom","runConnection","setupReporters","cliReporter","createJob","waitForJob","createStudioOptions","run"],"sources":["../src/runners/studio/ci.ts","../src/runners/studio/snapshot.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport process from 'node:process'\n\n/**\n * Stable identity for the CI agent a snapshot run registers or reuses.\n */\nexport type CiContext = {\n /**\n * Fed into the machine token, so the same merge or pull request reuses one agent.\n */\n id: string\n /**\n * Agent display name shown in Studio.\n */\n name: string\n /** The commit this run builds, so the next snapshot can diff against it. */\n commit?: string\n /** The branch a pull request merges into, and the `id` runs on that branch register under. */\n base?: { branch: string; id: string }\n}\n\ntype GithubPullRequest = { number: number; head?: { sha?: string }; base?: { ref?: string } }\n\nfunction readGithubPullRequest(eventPath: string | undefined): GithubPullRequest | undefined {\n if (!eventPath) {\n return undefined\n }\n\n try {\n const event = JSON.parse(readFileSync(eventPath, 'utf8')) as { pull_request?: GithubPullRequest }\n return event.pull_request?.number ? event.pull_request : undefined\n } catch {\n return undefined\n }\n}\n\n/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */\nexport function gitlabRefSlug(ref: string): string {\n return ref\n .toLowerCase()\n .replace(/[^a-z0-9]/gu, '-')\n .slice(0, 63)\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Detects the CI provider from its environment variables and derives a stable identity from it.\n * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has\n * always registered agents under, so an existing repository keeps reusing its agent.\n */\nexport function detectCi(env: Record<string, string | undefined> = process.env): CiContext | null {\n if (env.GITHUB_ACTIONS) {\n const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH)\n const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? ''\n const branch = env.GITHUB_REF?.startsWith('refs/heads/') ? env.GITHUB_REF.slice('refs/heads/'.length) : undefined\n // A branch run is scoped by its ref, which a pull request number never collides with.\n const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? ''\n const baseBranch = pullRequest?.base?.ref\n\n return {\n id: `gh:${repositoryId}:${scope}`,\n name: `${env.GITHUB_REPOSITORY ?? 'github'}#${pullRequest?.number ?? branch ?? scope}`,\n // The head commit, not the merge commit a pull request run checks out.\n commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gh:${repositoryId}:refs/heads/${baseBranch}` } : undefined,\n }\n }\n\n if (env.GITLAB_CI) {\n const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? ''\n const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME\n\n return {\n id: `gl:${env.CI_PROJECT_ID ?? ''}:${scope}`,\n name: `${env.CI_PROJECT_PATH ?? 'gitlab'}#${scope}`,\n commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gl:${env.CI_PROJECT_ID ?? ''}:${gitlabRefSlug(baseBranch)}` } : undefined,\n }\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? ''\n\n return { id: `bb:${env.BITBUCKET_REPO_UUID ?? ''}:${scope}`, name: `${env.BITBUCKET_REPO_FULL_NAME ?? 'bitbucket'}#${scope}`, commit: env.BITBUCKET_COMMIT }\n }\n\n if (env.CIRCLECI) {\n // Owner-qualified: two projects with the same name under different CircleCI orgs must not\n // collide on one agent, since registering it purges the other project's live sessions.\n const owner = env.CIRCLE_PROJECT_USERNAME ?? ''\n const project = env.CIRCLE_PROJECT_REPONAME ?? 'circleci'\n const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? ''\n\n return { id: `circle:${owner}:${project}:${scope}`, name: `${owner ? `${owner}/` : ''}${project}#${scope}`, commit: env.CIRCLE_SHA1 }\n }\n\n return null\n}\n","import { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { exists, read } from '@internals/utils'\nimport { cliReporter, logLevel as logLevelMap } from '@kubb/core'\nimport { createAgent, createJob, machineTokenFrom, runConnection, waitForJob, type StudioSnapshot, type StudioSnapshotChanges } from '@kubb/studio'\nimport { logBlock } from '../../loggers/output.ts'\nimport { createPlainLogger } from '../../loggers/plainLogger.ts'\nimport setupReporters from '../../loggers/utils.ts'\nimport { type CiContext, detectCi } from './ci.ts'\nimport { createStudioOptions, loadConfigs, run, type SnapshotOptions } from './run.ts'\nimport type { definition } from '../../commands/studio/snapshot.ts'\nimport type { CommandRunner } from 'gunshi'\n\n/**\n * How long to wait for Studio's `studio:ready` acknowledgement, above the client's own 10s\n * handshake-ack timeout.\n */\nconst READY_TIMEOUT_MS = 15_000\n\n/**\n * Longest `--timeout` accepted. Job records expire from Studio's storage after an hour.\n */\nconst MAX_TIMEOUT_SECONDS = 3600\n\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1'])\n\nasync function findPackageJson(startDirectory: string): Promise<{ name: string; version: string }> {\n let directory = startDirectory\n\n for (;;) {\n const file = join(directory, 'package.json')\n\n if (await exists(file)) {\n const packageJson = JSON.parse(await read(file)) as Partial<{ name: string; version: string }>\n\n if (packageJson.name && packageJson.version) {\n return { name: packageJson.name, version: packageJson.version }\n }\n }\n\n const parent = dirname(directory)\n\n if (parent === directory) {\n break\n }\n\n directory = parent\n }\n\n throw new Error(`No package.json with a name and a version found above ${startDirectory}`)\n}\n\n/** Reads package.json only for whichever of name/version --name and --version did not supply. */\nasync function resolvePackageMetadata(options: SnapshotOptions): Promise<{ name: string; version: string }> {\n if (options.name && options.packageVersion) {\n return { name: options.name, version: options.packageVersion }\n }\n\n const packageMetadata = await findPackageJson(process.cwd())\n\n return { name: options.name ?? packageMetadata.name, version: options.packageVersion ?? packageMetadata.version }\n}\n\nfunction resolveToken(options: SnapshotOptions): string {\n const token = options.token ?? process.env.KUBB_TOKEN\n\n if (!token) {\n throw new Error('An organization CI API key is required. Pass --token or set KUBB_TOKEN.')\n }\n\n return token\n}\n\nfunction resolveCiIdentity(options: SnapshotOptions): CiContext {\n const detected = detectCi()\n // A custom --id drops the detected base, since runs on that branch may use a custom id too.\n const ci = options.id ? { id: options.id, name: detected?.name ?? options.id, commit: detected?.commit } : detected\n\n if (!ci) {\n throw new Error('Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.')\n }\n\n // An explicit --base-id may not name a branch, so it labels the comparison itself.\n const base = options.baseId ? { branch: options.baseId, id: options.baseId } : ci.base\n\n return { ...ci, base: base?.id === ci.id ? undefined : base }\n}\n\n/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */\nfunction resolveTimeoutMs(options: SnapshotOptions): number {\n const seconds = options.timeout ?? 600\n\n if (!Number.isFinite(seconds) || seconds <= 0) {\n throw new Error('--timeout must be a positive number of seconds')\n }\n\n return Math.min(seconds, MAX_TIMEOUT_SECONDS) * 1000\n}\n\n/** The CI key is a credential, so refuse to send it anywhere but HTTPS or a loopback dev host. */\nfunction assertSecureStudioUrl(studioUrl: string): void {\n const url = new URL(studioUrl)\n\n if (url.protocol !== 'https:' && !LOOPBACK_HOSTS.has(url.hostname)) {\n throw new Error(`Refusing to send the CI API key to ${studioUrl}. Use an https:// Studio URL, or a loopback host for local development.`)\n }\n}\n\nfunction absoluteUrl(studioUrl: string, path: string): string {\n return new URL(path, `${studioUrl}/`).toString()\n}\n\ntype SnapshotResult = {\n id: string\n name: string | null\n version: string | null\n integrity: string | null\n url: string\n snapshotIdUrl: string\n expiresAt: string\n agentUrl: string\n /** What changed since the previous snapshot of this package on this agent. */\n changes?: StudioSnapshotChanges\n /** What differs from the latest snapshot of the base branch, named by `branch`. */\n branchChanges?: StudioSnapshotChanges & { branch: string }\n}\n\nfunction toResult(studioUrl: string, snapshot: StudioSnapshot, agentSlug: string, ci: CiContext): SnapshotResult {\n return {\n id: snapshot.id,\n name: snapshot.name,\n version: snapshot.version,\n integrity: snapshot.integrity,\n url: absoluteUrl(studioUrl, snapshot.url),\n snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),\n expiresAt: snapshot.expiresAt,\n agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),\n changes: snapshot.changes,\n branchChanges: snapshot.branchChanges && ci.base ? { ...snapshot.branchChanges, branch: ci.base.branch } : undefined,\n }\n}\n\n/** How many files differ, `against` what. */\nfunction describeChanges(changes: StudioSnapshotChanges, against: string): string {\n const { added, changed, removed } = changes\n\n return added.length + changed.length + removed.length\n ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}`\n : `No changes ${against}`\n}\n\n/** One summary line: how many files changed, and since which run. */\nexport function formatChanges(changes: StudioSnapshotChanges): string {\n if (!changes.base) {\n return 'First snapshot'\n }\n\n return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`)\n}\n\n/** One summary line: how the snapshot differs from the base branch's latest one. */\nexport function formatBranchChanges(changes: StudioSnapshotChanges & { branch: string }): string {\n return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`\n}\n\nfunction printSummary(result: SnapshotResult): void {\n logBlock([\n `${styleText('dim', 'Package'.padEnd(10))} ${result.name ?? '(unnamed)'}@${result.version ?? '0.0.0'}`,\n `${styleText('dim', 'Tarball'.padEnd(10))} ${styleText('cyan', result.url)}`,\n `${styleText('dim', 'Agent'.padEnd(10))} ${result.agentUrl}`,\n ...(result.branchChanges ? [`${styleText('dim', 'Branch'.padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : []),\n ...(result.changes ? [`${styleText('dim', 'Changes'.padEnd(10))} ${formatChanges(result.changes)}`] : []),\n `${styleText('dim', 'Expires'.padEnd(10))} ${result.expiresAt}`,\n ])\n}\n\n/**\n * Generates a Kubb Studio snapshot from a script: registers or reuses a CI agent, connects it,\n * queues a snapshot job, and polls until the tarball is ready. A snapshot job runs generation and\n * packs the tarball in one step, so this needs no separate generation run.\n */\nexport async function snapshot(options: SnapshotOptions): Promise<void> {\n const timeoutMs = resolveTimeoutMs(options)\n const token = resolveToken(options)\n assertSecureStudioUrl(options.studioUrl)\n const { configPath } = await loadConfigs(options)\n const ci = resolveCiIdentity(options)\n const { name, version: packageVersion } = await resolvePackageMetadata(options)\n const logLevel = logLevelMap[options.logLevel ?? 'info']\n\n // Set before the first `getMachineToken()` call (inside the connection), so the WebSocket\n // session registers under the same machine token `createAgent` just registered with Studio.\n process.env.KUBB_AGENT_SECRET = ci.id\n\n const write = options.json ? (line: string) => console.error(line) : (line: string) => console.log(line)\n const logger = createPlainLogger(write)\n const step = (message: string) => {\n if (logLevel > logLevelMap.silent) {\n write(message)\n }\n }\n\n step('Creating Kubb Studio agent')\n\n const agent = await createAgent({ studioUrl: options.studioUrl, token, name: ci.name, machineToken: machineTokenFrom(ci.id) })\n\n const { promise: ready, resolve: markReady } = Promise.withResolvers<void>()\n const shutdown = new AbortController()\n\n const connection = runConnection({\n credentials: { token: agent.token },\n signal: shutdown.signal,\n clientOptions: () => ({\n studioUrl: options.studioUrl,\n configPath,\n root: process.cwd(),\n version: options.version,\n // Flags only: a script is never prompted and never reuses a saved answer.\n permissions: options.permission,\n loadConfig: async () => (await loadConfigs(options)).config,\n installLogger: async (hooks) => {\n await setupReporters(hooks, { logLevel, reporters: [cliReporter], logger })\n hooks.hook('studio:ready', () => markReady())\n },\n }),\n // A CI agent's token comes from the organization key, so there is no pairing to fall back to.\n onTokenRejected: ({ error }) => Promise.reject(error),\n })\n const connectionLost = new AbortController()\n const connectionEnded = new Error('The Kubb Studio connection ended before the snapshot finished')\n void connection.then(\n () => connectionLost.abort(connectionEnded),\n (error) => connectionLost.abort(error),\n )\n const lost = connection.then(\n () => Promise.reject(connectionEnded),\n (error) => Promise.reject(error),\n )\n void lost.catch(() => {})\n\n try {\n let readyTimeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n ready,\n lost,\n new Promise<never>((_, reject) => {\n readyTimeout = setTimeout(() => reject(new Error('Timed out waiting for Kubb Studio to confirm the agent was ready')), READY_TIMEOUT_MS)\n }),\n ])\n } finally {\n clearTimeout(readyTimeout)\n }\n\n step('Creating snapshot job')\n\n const snapshotDeadline = Date.now() + timeoutMs\n const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1)\n\n const job = await createJob({\n studioUrl: options.studioUrl,\n token,\n type: 'snapshot',\n agentId: agent.id,\n name,\n version: packageVersion,\n commit: ci.commit,\n baseId: ci.base?.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n })\n step(`Snapshot job queued: ${job.id}`)\n const finished = await Promise.race([\n waitForJob({\n studioUrl: options.studioUrl,\n token,\n id: job.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n }),\n lost,\n ])\n\n if (finished.status === 'failed') {\n throw new Error(finished.error ?? 'Snapshot job failed')\n }\n\n if (!finished.snapshot) {\n throw new Error('Snapshot job succeeded without a snapshot')\n }\n\n const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci)\n\n step('Snapshot published')\n\n if (options.json) {\n console.log(JSON.stringify(result))\n }\n if (!options.json) {\n printSummary(result)\n }\n } catch (error) {\n step('Snapshot failed')\n throw error\n } finally {\n step('Disconnecting from Kubb Studio')\n // Not awaited: a half-open socket must not hold the run open.\n shutdown.abort()\n }\n}\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options: SnapshotOptions = {\n ...createStudioOptions(values),\n token: values.token,\n id: values.id,\n baseId: values.baseId,\n name: values.name,\n packageVersion: values.packageVersion,\n timeout: values.timeout,\n json: values.json,\n }\n await run(options, () => snapshot(options), { json: options.json })\n}\n"],"mappings":"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"}