@kubb/cli 5.3.8 → 5.3.9
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-CvHQevSK.cjs → Telemetry-B3kc9gFh.cjs} +3 -2
- package/dist/Telemetry-B3kc9gFh.cjs.map +1 -0
- package/dist/{Telemetry-CJcQkQOT.js → Telemetry-Dw5s6abr.js} +3 -2
- package/dist/Telemetry-Dw5s6abr.js.map +1 -0
- package/dist/connect-DFd7vS7_.js +11 -0
- package/dist/connect-DFd7vS7_.js.map +1 -0
- package/dist/connect-bCESn4L8.cjs +11 -0
- package/dist/connect-bCESn4L8.cjs.map +1 -0
- package/dist/{generate-DGRNFF3n.cjs → generate-Cl5hFNdC.cjs} +5 -18
- package/dist/generate-Cl5hFNdC.cjs.map +1 -0
- package/dist/{generate-Zldpj9MI.js → generate-Del-D4hj.js} +5 -18
- package/dist/generate-Del-D4hj.js.map +1 -0
- package/dist/index.cjs +9 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -18
- package/dist/index.js.map +1 -1
- package/dist/{init-C2aRtQsn.cjs → init-C5trdwre.cjs} +3 -3
- package/dist/{init-C2aRtQsn.cjs.map → init-C5trdwre.cjs.map} +1 -1
- package/dist/{init-CqKLyf-D.js → init-CBAmaPkc.js} +3 -3
- package/dist/{init-CqKLyf-D.js.map → init-CBAmaPkc.js.map} +1 -1
- package/dist/login-5QXmUaQN.cjs +11 -0
- package/dist/login-5QXmUaQN.cjs.map +1 -0
- package/dist/login-D-1xSRxT.js +11 -0
- package/dist/login-D-1xSRxT.js.map +1 -0
- package/dist/logout-B2vHFyac.cjs +14 -0
- package/dist/logout-B2vHFyac.cjs.map +1 -0
- package/dist/logout-XB0v_SY-.js +14 -0
- package/dist/logout-XB0v_SY-.js.map +1 -0
- package/dist/output-CdnsdD1b.js +342 -0
- package/dist/output-CdnsdD1b.js.map +1 -0
- package/dist/output-DBBTlqPw.cjs +438 -0
- package/dist/output-DBBTlqPw.cjs.map +1 -0
- package/dist/{package-BzG32I44.cjs → package-BwIh-jWZ.cjs} +2 -2
- package/dist/package-BwIh-jWZ.cjs.map +1 -0
- package/dist/package-CDw1YdJ8.js +6 -0
- package/dist/package-CDw1YdJ8.js.map +1 -0
- package/dist/{run-gQD6xSuC.js → run-Bd-IwEch.js} +48 -301
- package/dist/run-Bd-IwEch.js.map +1 -0
- package/dist/{run-ByKuuI4i.js → run-C5HkzCUt.js} +27 -23
- package/dist/run-C5HkzCUt.js.map +1 -0
- package/dist/{run-BaaFaBBx.cjs → run-CIonyF_t.cjs} +99 -299
- package/dist/run-CIonyF_t.cjs.map +1 -0
- package/dist/{run-BrnQLk3o.js → run-CLhU86LM.js} +3 -3
- package/dist/{run-BrnQLk3o.js.map → run-CLhU86LM.js.map} +1 -1
- package/dist/{run-kdxqOL8u.js → run-CeTu1eSk.js} +2 -2
- package/dist/{run-kdxqOL8u.js.map → run-CeTu1eSk.js.map} +1 -1
- package/dist/{run-De_AsR8i.cjs → run-CxglY4u6.cjs} +27 -23
- package/dist/run-CxglY4u6.cjs.map +1 -0
- package/dist/{run-CqLiqWP1.cjs → run-DPuKGV20.cjs} +3 -3
- package/dist/{run-CqLiqWP1.cjs.map → run-DPuKGV20.cjs.map} +1 -1
- package/dist/{run-BP7-azAp.js → run-Df4x0iX_.js} +3 -3
- package/dist/{run-BP7-azAp.js.map → run-Df4x0iX_.js.map} +1 -1
- package/dist/{run-BZiPrq4E.cjs → run-SybIXc6w.cjs} +3 -3
- package/dist/{run-BZiPrq4E.cjs.map → run-SybIXc6w.cjs.map} +1 -1
- package/dist/{run-VK50TiB7.cjs → run-ZPt0Sw9r.cjs} +2 -2
- package/dist/{run-VK50TiB7.cjs.map → run-ZPt0Sw9r.cjs.map} +1 -1
- package/dist/shared-C5doIqKD.js +64 -0
- package/dist/shared-C5doIqKD.js.map +1 -0
- package/dist/shared-CaRlFkWL.cjs +87 -0
- package/dist/shared-CaRlFkWL.cjs.map +1 -0
- package/dist/snapshot-DWNiluEm.cjs +261 -0
- package/dist/snapshot-DWNiluEm.cjs.map +1 -0
- package/dist/snapshot-Dhwz_MpL.js +260 -0
- package/dist/snapshot-Dhwz_MpL.js.map +1 -0
- package/dist/status-Cc3wqN4l.js +11 -0
- package/dist/status-Cc3wqN4l.js.map +1 -0
- package/dist/status-CxMC5vAa.cjs +11 -0
- package/dist/status-CxMC5vAa.cjs.map +1 -0
- package/dist/studio-CQ24bwGz.cjs +155 -0
- package/dist/studio-CQ24bwGz.cjs.map +1 -0
- package/dist/studio-jqKsQP5_.js +155 -0
- package/dist/studio-jqKsQP5_.js.map +1 -0
- package/dist/{utils-s6yetN6W.js → utils-B1_SWa35.js} +356 -525
- package/dist/utils-B1_SWa35.js.map +1 -0
- package/dist/{utils-CMU1rLfY.cjs → utils-BP0xq5AK.cjs} +345 -508
- package/dist/utils-BP0xq5AK.cjs.map +1 -0
- package/package.json +9 -9
- package/dist/Telemetry-CJcQkQOT.js.map +0 -1
- package/dist/Telemetry-CvHQevSK.cjs.map +0 -1
- package/dist/generate-DGRNFF3n.cjs.map +0 -1
- package/dist/generate-Zldpj9MI.js.map +0 -1
- package/dist/output-DH2Uoy4x.js +0 -118
- package/dist/output-DH2Uoy4x.js.map +0 -1
- package/dist/output-kmklyYIv.cjs +0 -172
- package/dist/output-kmklyYIv.cjs.map +0 -1
- package/dist/package-BzG32I44.cjs.map +0 -1
- package/dist/package-CRlfmw6k.js +0 -6
- package/dist/package-CRlfmw6k.js.map +0 -1
- package/dist/run-BaaFaBBx.cjs.map +0 -1
- package/dist/run-ByKuuI4i.js.map +0 -1
- package/dist/run-De_AsR8i.cjs.map +0 -1
- package/dist/run-gQD6xSuC.js.map +0 -1
- package/dist/studio-B33RIU3-.cjs +0 -111
- package/dist/studio-B33RIU3-.cjs.map +0 -1
- package/dist/studio-Cq_th0uM.js +0 -112
- package/dist/studio-Cq_th0uM.js.map +0 -1
- package/dist/utils-CMU1rLfY.cjs.map +0 -1
- package/dist/utils-s6yetN6W.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-C5doIqKD.js","names":[],"sources":["../src/commands/shared.ts"],"sourcesContent":["export const configArg = {\n config: {\n type: 'string',\n description: 'Path to the Kubb config',\n short: 'c',\n },\n} as const\n\nexport const logLevelArg = {\n logLevel: {\n type: 'enum',\n choices: ['silent', 'info', 'verbose'] as const,\n description: 'Info, silent or verbose',\n short: 'l',\n default: 'info',\n toKebab: true,\n },\n} as const\n\nexport const studioConnectionArgs = {\n url: {\n type: 'string',\n description: 'Base URL of the Kubb Studio instance',\n },\n token: {\n type: 'string',\n description: 'Organization CI API key for `snapshot`. Defaults to KUBB_TOKEN',\n },\n} as const\n\nexport const studioPermissionArgs = {\n allowRead: {\n type: 'boolean',\n description: 'Read the source of files a generation produced. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowWrite: {\n type: 'boolean',\n description: 'Write generated files to disk. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowConfigEdit: {\n type: 'boolean',\n description: 'Let Studio change plugin options in kubb.config.ts. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowInput: {\n type: 'boolean',\n description: 'Generate from an OpenAPI spec sent by Studio instead of the one on disk. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowExec: {\n type: 'boolean',\n description: 'Run the formatter, the linter, and output.postGenerate after a generation',\n default: false,\n toKebab: true,\n },\n} as const\n"],"mappings":";AAAA,MAAa,YAAY,EACvB,QAAQ;CACN,MAAM;CACN,aAAa;CACb,OAAO;AACT,EACF;AAEA,MAAa,cAAc,EACzB,UAAU;CACR,MAAM;CACN,SAAS;EAAC;EAAU;EAAQ;CAAS;CACrC,aAAa;CACb,OAAO;CACP,SAAS;CACT,SAAS;AACX,EACF;AAEA,MAAa,uBAAuB;CAClC,KAAK;EACH,MAAM;EACN,aAAa;CACf;CACA,OAAO;EACL,MAAM;EACN,aAAa;CACf;AACF;AAEA,MAAa,uBAAuB;CAClC,WAAW;EACT,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,YAAY;EACV,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,iBAAiB;EACf,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,YAAY;EACV,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,WAAW;EACT,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;AACF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//#region src/commands/shared.ts
|
|
2
|
+
const configArg = { config: {
|
|
3
|
+
type: "string",
|
|
4
|
+
description: "Path to the Kubb config",
|
|
5
|
+
short: "c"
|
|
6
|
+
} };
|
|
7
|
+
const logLevelArg = { logLevel: {
|
|
8
|
+
type: "enum",
|
|
9
|
+
choices: [
|
|
10
|
+
"silent",
|
|
11
|
+
"info",
|
|
12
|
+
"verbose"
|
|
13
|
+
],
|
|
14
|
+
description: "Info, silent or verbose",
|
|
15
|
+
short: "l",
|
|
16
|
+
default: "info",
|
|
17
|
+
toKebab: true
|
|
18
|
+
} };
|
|
19
|
+
const studioConnectionArgs = {
|
|
20
|
+
url: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Base URL of the Kubb Studio instance"
|
|
23
|
+
},
|
|
24
|
+
token: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Organization CI API key for `snapshot`. Defaults to KUBB_TOKEN"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const studioPermissionArgs = {
|
|
30
|
+
allowRead: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: "Read the source of files a generation produced. Asked for once per project when omitted",
|
|
33
|
+
default: false,
|
|
34
|
+
toKebab: true
|
|
35
|
+
},
|
|
36
|
+
allowWrite: {
|
|
37
|
+
type: "boolean",
|
|
38
|
+
description: "Write generated files to disk. Asked for once per project when omitted",
|
|
39
|
+
default: false,
|
|
40
|
+
toKebab: true
|
|
41
|
+
},
|
|
42
|
+
allowConfigEdit: {
|
|
43
|
+
type: "boolean",
|
|
44
|
+
description: "Let Studio change plugin options in kubb.config.ts. Asked for once per project when omitted",
|
|
45
|
+
default: false,
|
|
46
|
+
toKebab: true
|
|
47
|
+
},
|
|
48
|
+
allowInput: {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
description: "Generate from an OpenAPI spec sent by Studio instead of the one on disk. Asked for once per project when omitted",
|
|
51
|
+
default: false,
|
|
52
|
+
toKebab: true
|
|
53
|
+
},
|
|
54
|
+
allowExec: {
|
|
55
|
+
type: "boolean",
|
|
56
|
+
description: "Run the formatter, the linter, and output.postGenerate after a generation",
|
|
57
|
+
default: false,
|
|
58
|
+
toKebab: true
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
Object.defineProperty(exports, "configArg", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
get: function() {
|
|
65
|
+
return configArg;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
Object.defineProperty(exports, "logLevelArg", {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function() {
|
|
71
|
+
return logLevelArg;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
Object.defineProperty(exports, "studioConnectionArgs", {
|
|
75
|
+
enumerable: true,
|
|
76
|
+
get: function() {
|
|
77
|
+
return studioConnectionArgs;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
Object.defineProperty(exports, "studioPermissionArgs", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: function() {
|
|
83
|
+
return studioPermissionArgs;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=shared-CaRlFkWL.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-CaRlFkWL.cjs","names":[],"sources":["../src/commands/shared.ts"],"sourcesContent":["export const configArg = {\n config: {\n type: 'string',\n description: 'Path to the Kubb config',\n short: 'c',\n },\n} as const\n\nexport const logLevelArg = {\n logLevel: {\n type: 'enum',\n choices: ['silent', 'info', 'verbose'] as const,\n description: 'Info, silent or verbose',\n short: 'l',\n default: 'info',\n toKebab: true,\n },\n} as const\n\nexport const studioConnectionArgs = {\n url: {\n type: 'string',\n description: 'Base URL of the Kubb Studio instance',\n },\n token: {\n type: 'string',\n description: 'Organization CI API key for `snapshot`. Defaults to KUBB_TOKEN',\n },\n} as const\n\nexport const studioPermissionArgs = {\n allowRead: {\n type: 'boolean',\n description: 'Read the source of files a generation produced. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowWrite: {\n type: 'boolean',\n description: 'Write generated files to disk. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowConfigEdit: {\n type: 'boolean',\n description: 'Let Studio change plugin options in kubb.config.ts. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowInput: {\n type: 'boolean',\n description: 'Generate from an OpenAPI spec sent by Studio instead of the one on disk. Asked for once per project when omitted',\n default: false,\n toKebab: true,\n },\n allowExec: {\n type: 'boolean',\n description: 'Run the formatter, the linter, and output.postGenerate after a generation',\n default: false,\n toKebab: true,\n },\n} as const\n"],"mappings":";AAAA,MAAa,YAAY,EACvB,QAAQ;CACN,MAAM;CACN,aAAa;CACb,OAAO;AACT,EACF;AAEA,MAAa,cAAc,EACzB,UAAU;CACR,MAAM;CACN,SAAS;EAAC;EAAU;EAAQ;CAAS;CACrC,aAAa;CACb,OAAO;CACP,SAAS;CACT,SAAS;AACX,EACF;AAEA,MAAa,uBAAuB;CAClC,KAAK;EACH,MAAM;EACN,aAAa;CACf;CACA,OAAO;EACL,MAAM;EACN,aAAa;CACf;AACF;AAEA,MAAa,uBAAuB;CAClC,WAAW;EACT,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,YAAY;EACV,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,iBAAiB;EACf,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,YAAY;EACV,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;CACA,WAAW;EACT,MAAM;EACN,aAAa;EACb,SAAS;EACT,SAAS;CACX;AACF"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
+
const require_run = require("./run-CIonyF_t.cjs");
|
|
3
|
+
const require_output = require("./output-DBBTlqPw.cjs");
|
|
4
|
+
let node_util = require("node:util");
|
|
5
|
+
let node_process = require("node:process");
|
|
6
|
+
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
let node_fs = require("node:fs");
|
|
9
|
+
let _kubb_core = require("@kubb/core");
|
|
10
|
+
let _kubb_studio = require("@kubb/studio");
|
|
11
|
+
//#region src/runners/studio/ci.ts
|
|
12
|
+
function readGithubPullRequestNumber(eventPath) {
|
|
13
|
+
if (!eventPath) return;
|
|
14
|
+
try {
|
|
15
|
+
const event = JSON.parse((0, node_fs.readFileSync)(eventPath, "utf8"));
|
|
16
|
+
return event.pull_request?.number ? String(event.pull_request.number) : void 0;
|
|
17
|
+
} catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
23
|
+
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
24
|
+
* always registered agents under, so an existing repository keeps reusing its agent.
|
|
25
|
+
*/
|
|
26
|
+
function detectCi(env = node_process.default.env) {
|
|
27
|
+
if (env.GITHUB_ACTIONS) {
|
|
28
|
+
const pullRequestNumber = readGithubPullRequestNumber(env.GITHUB_EVENT_PATH);
|
|
29
|
+
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
30
|
+
const scope = pullRequestNumber ?? env.GITHUB_RUN_ID ?? "";
|
|
31
|
+
return {
|
|
32
|
+
id: `gh:${repositoryId}:${scope}`,
|
|
33
|
+
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (env.GITLAB_CI) {
|
|
37
|
+
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
38
|
+
return {
|
|
39
|
+
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
40
|
+
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
44
|
+
const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? "";
|
|
45
|
+
return {
|
|
46
|
+
id: `bb:${env.BITBUCKET_REPO_UUID ?? ""}:${scope}`,
|
|
47
|
+
name: `${env.BITBUCKET_REPO_FULL_NAME ?? "bitbucket"}#${scope}`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (env.CIRCLECI) {
|
|
51
|
+
const owner = env.CIRCLE_PROJECT_USERNAME ?? "";
|
|
52
|
+
const project = env.CIRCLE_PROJECT_REPONAME ?? "circleci";
|
|
53
|
+
const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? "";
|
|
54
|
+
return {
|
|
55
|
+
id: `circle:${owner}:${project}:${scope}`,
|
|
56
|
+
name: `${owner ? `${owner}/` : ""}${project}#${scope}`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/runners/studio/snapshot.ts
|
|
63
|
+
/**
|
|
64
|
+
* How long to wait for Studio's `studio:ready` acknowledgement, above the client's own 10s
|
|
65
|
+
* handshake-ack timeout.
|
|
66
|
+
*/
|
|
67
|
+
const READY_TIMEOUT_MS = 15e3;
|
|
68
|
+
/**
|
|
69
|
+
* Longest `--timeout` accepted. Job records expire from Studio's storage after an hour.
|
|
70
|
+
*/
|
|
71
|
+
const MAX_TIMEOUT_SECONDS = 3600;
|
|
72
|
+
const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
|
|
73
|
+
"localhost",
|
|
74
|
+
"127.0.0.1",
|
|
75
|
+
"::1"
|
|
76
|
+
]);
|
|
77
|
+
async function findPackageJson(startDirectory) {
|
|
78
|
+
let directory = startDirectory;
|
|
79
|
+
for (;;) {
|
|
80
|
+
const file = (0, node_path.join)(directory, "package.json");
|
|
81
|
+
if (await require_run.exists(file)) {
|
|
82
|
+
const packageJson = JSON.parse(await require_run.read(file));
|
|
83
|
+
if (packageJson.name && packageJson.version) return {
|
|
84
|
+
name: packageJson.name,
|
|
85
|
+
version: packageJson.version
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const parent = (0, node_path.dirname)(directory);
|
|
89
|
+
if (parent === directory) break;
|
|
90
|
+
directory = parent;
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`No package.json with a name and a version found above ${startDirectory}`);
|
|
93
|
+
}
|
|
94
|
+
/** Reads package.json only for whichever of name/version --name and --version did not supply. */
|
|
95
|
+
async function resolvePackageMetadata(options) {
|
|
96
|
+
if (options.name && options.packageVersion) return {
|
|
97
|
+
name: options.name,
|
|
98
|
+
version: options.packageVersion
|
|
99
|
+
};
|
|
100
|
+
const packageMetadata = await findPackageJson(node_process.default.cwd());
|
|
101
|
+
return {
|
|
102
|
+
name: options.name ?? packageMetadata.name,
|
|
103
|
+
version: options.packageVersion ?? packageMetadata.version
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function resolveToken(options) {
|
|
107
|
+
const token = options.token ?? node_process.default.env.KUBB_TOKEN;
|
|
108
|
+
if (!token) throw new Error("An organization CI API key is required. Pass --token or set KUBB_TOKEN.");
|
|
109
|
+
return token;
|
|
110
|
+
}
|
|
111
|
+
function resolveCiIdentity(options) {
|
|
112
|
+
const detected = detectCi();
|
|
113
|
+
if (options.id) return {
|
|
114
|
+
id: options.id,
|
|
115
|
+
name: detected?.name ?? options.id
|
|
116
|
+
};
|
|
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
|
+
}
|
|
120
|
+
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
121
|
+
function resolveTimeoutMs(options) {
|
|
122
|
+
const seconds = options.timeout ?? 600;
|
|
123
|
+
if (!Number.isFinite(seconds) || seconds <= 0) throw new Error("--timeout must be a positive number of seconds");
|
|
124
|
+
return Math.min(seconds, MAX_TIMEOUT_SECONDS) * 1e3;
|
|
125
|
+
}
|
|
126
|
+
/** The CI key is a credential, so refuse to send it anywhere but HTTPS or a loopback dev host. */
|
|
127
|
+
function assertSecureStudioUrl(studioUrl) {
|
|
128
|
+
const url = new URL(studioUrl);
|
|
129
|
+
if (url.protocol !== "https:" && !LOOPBACK_HOSTS.has(url.hostname)) throw new Error(`Refusing to send the CI API key to ${studioUrl}. Use an https:// Studio URL, or a loopback host for local development.`);
|
|
130
|
+
}
|
|
131
|
+
function absoluteUrl(studioUrl, path) {
|
|
132
|
+
return new URL(path, `${studioUrl}/`).toString();
|
|
133
|
+
}
|
|
134
|
+
function toResult(studioUrl, snapshot, agentSlug) {
|
|
135
|
+
return {
|
|
136
|
+
id: snapshot.id,
|
|
137
|
+
name: snapshot.name,
|
|
138
|
+
version: snapshot.version,
|
|
139
|
+
integrity: snapshot.integrity,
|
|
140
|
+
url: absoluteUrl(studioUrl, snapshot.url),
|
|
141
|
+
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
142
|
+
expiresAt: snapshot.expiresAt,
|
|
143
|
+
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function printSummary(result) {
|
|
147
|
+
require_output.logBlock([
|
|
148
|
+
`${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
149
|
+
`${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
|
|
150
|
+
`${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
151
|
+
`${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
152
|
+
]);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Generates a Kubb Studio snapshot from a script: registers or reuses a CI agent, connects it,
|
|
156
|
+
* queues a snapshot job, and polls until the tarball is ready. A snapshot job runs generation and
|
|
157
|
+
* packs the tarball in one step, so this needs no separate generation run.
|
|
158
|
+
*/
|
|
159
|
+
async function snapshot(options) {
|
|
160
|
+
const timeoutMs = resolveTimeoutMs(options);
|
|
161
|
+
const token = resolveToken(options);
|
|
162
|
+
assertSecureStudioUrl(options.studioUrl);
|
|
163
|
+
const { configPath } = await require_run.loadConfigs(options);
|
|
164
|
+
const ci = resolveCiIdentity(options);
|
|
165
|
+
const { name, version: packageVersion } = await resolvePackageMetadata(options);
|
|
166
|
+
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);
|
|
174
|
+
};
|
|
175
|
+
if (options.json) log("Creating Kubb Studio agent");
|
|
176
|
+
if (!options.json) spinner?.start("Creating Kubb Studio agent");
|
|
177
|
+
const agent = await (0, _kubb_studio.createAgent)({
|
|
178
|
+
studioUrl: options.studioUrl,
|
|
179
|
+
token,
|
|
180
|
+
name: ci.name,
|
|
181
|
+
machineToken: (0, _kubb_studio.machineTokenFrom)(ci.id)
|
|
182
|
+
});
|
|
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
|
+
}
|
|
203
|
+
});
|
|
204
|
+
await client.connect();
|
|
205
|
+
try {
|
|
206
|
+
let readyTimeoutHandle;
|
|
207
|
+
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
|
+
})]);
|
|
211
|
+
} finally {
|
|
212
|
+
clearTimeout(readyTimeoutHandle);
|
|
213
|
+
}
|
|
214
|
+
log("Creating snapshot job");
|
|
215
|
+
const job = await (0, _kubb_studio.createJob)({
|
|
216
|
+
studioUrl: options.studioUrl,
|
|
217
|
+
token,
|
|
218
|
+
type: "snapshot",
|
|
219
|
+
agentId: agent.id,
|
|
220
|
+
name,
|
|
221
|
+
version: packageVersion
|
|
222
|
+
});
|
|
223
|
+
log(`Snapshot job queued: ${job.id}`);
|
|
224
|
+
const finished = await (0, _kubb_studio.waitForJob)({
|
|
225
|
+
studioUrl: options.studioUrl,
|
|
226
|
+
token,
|
|
227
|
+
id: job.id,
|
|
228
|
+
timeoutMs
|
|
229
|
+
});
|
|
230
|
+
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
231
|
+
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");
|
|
235
|
+
if (options.json) console.log(JSON.stringify(result));
|
|
236
|
+
if (!options.json) printSummary(result);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
if (options.json) log("Snapshot failed");
|
|
239
|
+
if (!options.json) spinner?.stop("Snapshot failed");
|
|
240
|
+
throw error;
|
|
241
|
+
} finally {
|
|
242
|
+
if (options.json) log("Disconnecting from Kubb Studio");
|
|
243
|
+
client.disconnect();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const runner = async ({ values }) => {
|
|
247
|
+
const options = {
|
|
248
|
+
...require_run.createStudioOptions(values),
|
|
249
|
+
token: values.token,
|
|
250
|
+
id: values.id,
|
|
251
|
+
name: values.name,
|
|
252
|
+
packageVersion: values.packageVersion,
|
|
253
|
+
timeout: values.timeout,
|
|
254
|
+
json: values.json
|
|
255
|
+
};
|
|
256
|
+
await require_run.run(options, () => snapshot(options), { json: options.json });
|
|
257
|
+
};
|
|
258
|
+
//#endregion
|
|
259
|
+
exports.runner = runner;
|
|
260
|
+
|
|
261
|
+
//# sourceMappingURL=snapshot-DWNiluEm.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-DWNiluEm.cjs","names":["readFileSync","process","join","exists","read","dirname","process","styleText","loadConfigs","createSpinner","createAgent","machineTokenFrom","createClient","logLevelMap","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}\n\nfunction readGithubPullRequestNumber(eventPath: string | undefined): string | undefined {\n if (!eventPath) {\n return undefined\n }\n\n try {\n const event = JSON.parse(readFileSync(eventPath, 'utf8')) as { pull_request?: { number?: number } }\n return event.pull_request?.number ? String(event.pull_request.number) : undefined\n } catch {\n return undefined\n }\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 pullRequestNumber = readGithubPullRequestNumber(env.GITHUB_EVENT_PATH)\n const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? ''\n const scope = pullRequestNumber ?? env.GITHUB_RUN_ID ?? ''\n\n return { id: `gh:${repositoryId}:${scope}`, name: `${env.GITHUB_REPOSITORY ?? 'github'}#${scope}` }\n }\n\n if (env.GITLAB_CI) {\n const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? ''\n\n return { id: `gl:${env.CI_PROJECT_ID ?? ''}:${scope}`, name: `${env.CI_PROJECT_PATH ?? 'gitlab'}#${scope}` }\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}` }\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}` }\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 { logLevel as logLevelMap } from '@kubb/core'\nimport { createAgent, createClient, createJob, machineTokenFrom, waitForJob, type StudioSnapshot } from '@kubb/studio'\nimport { createSpinner, logBlock } from '../../loggers/output.ts'\nimport { 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): { id: string; name: string } {\n const detected = detectCi()\n\n if (options.id) {\n return { id: options.id, name: detected?.name ?? options.id }\n }\n\n if (!detected) {\n throw new Error('Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.')\n }\n\n return detected\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}\n\nfunction toResult(studioUrl: string, snapshot: StudioSnapshot, agentSlug: string): 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 }\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 `${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\n // Set before the first `getMachineToken()` call (inside `client.connect()`), 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 spinner = options.json ? null : createSpinner()\n const log = (message: string) => {\n if (options.json) {\n console.error(message)\n return\n }\n\n spinner?.message(message)\n }\n\n if (options.json) {\n log('Creating Kubb Studio agent')\n }\n if (!options.json) {\n spinner?.start('Creating Kubb Studio agent')\n }\n\n const agent = await createAgent({ studioUrl: options.studioUrl, token, name: ci.name, machineToken: machineTokenFrom(ci.id) })\n\n const { promise: ready, reject: markFailed, resolve: markReady } = Promise.withResolvers<void>()\n\n const client = createClient({\n studioUrl: options.studioUrl,\n token: agent.token,\n configPath,\n root: process.cwd(),\n version: options.version,\n client: { kind: 'cli' },\n logLevel: logLevelMap[options.logLevel ?? 'info'],\n loadConfig: async () => (await loadConfigs(options)).config,\n installLogger: (hooks) => {\n hooks.hook('studio:connecting', ({ url }) => log(`Connecting to Kubb Studio at ${url}`))\n hooks.hook('studio:connected', ({ url }) => log(`Connected to Kubb Studio at ${url}`))\n hooks.hook('studio:ready', () => {\n log('Kubb Studio connection ready')\n markReady()\n })\n hooks.hook('studio:warn', ({ message }) => log(`Kubb Studio warning: ${message}`))\n hooks.hook('studio:error', ({ error }) => markFailed(error))\n },\n })\n\n await client.connect()\n\n try {\n let readyTimeoutHandle: ReturnType<typeof setTimeout> | undefined\n\n try {\n await Promise.race([\n ready,\n new Promise<void>((_, reject) => {\n readyTimeoutHandle = 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(readyTimeoutHandle)\n }\n\n log('Creating snapshot job')\n\n const job = await createJob({ studioUrl: options.studioUrl, token, type: 'snapshot', agentId: agent.id, name, version: packageVersion })\n log(`Snapshot job queued: ${job.id}`)\n const finished = await waitForJob({ studioUrl: options.studioUrl, token, id: job.id, timeoutMs })\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)\n\n if (options.json) {\n log('Snapshot published')\n }\n if (!options.json) {\n spinner?.stop('Snapshot published')\n }\n\n if (options.json) {\n console.log(JSON.stringify(result))\n }\n if (!options.json) {\n printSummary(result)\n }\n } catch (error) {\n if (options.json) {\n log('Snapshot failed')\n }\n if (!options.json) {\n spinner?.stop('Snapshot failed')\n }\n throw error\n } finally {\n if (options.json) {\n log('Disconnecting from Kubb Studio')\n }\n client.disconnect()\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 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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"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
+
import { a as run, c as exists, l as read, n as createStudioOptions, r as loadConfigs } from "./run-Bd-IwEch.js";
|
|
3
|
+
import { r as logBlock, t as createSpinner } from "./output-CdnsdD1b.js";
|
|
4
|
+
import { styleText } from "node:util";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { logLevel } from "@kubb/core";
|
|
9
|
+
import { createAgent, createClient, createJob, machineTokenFrom, waitForJob } from "@kubb/studio";
|
|
10
|
+
//#region src/runners/studio/ci.ts
|
|
11
|
+
function readGithubPullRequestNumber(eventPath) {
|
|
12
|
+
if (!eventPath) return;
|
|
13
|
+
try {
|
|
14
|
+
const event = JSON.parse(readFileSync(eventPath, "utf8"));
|
|
15
|
+
return event.pull_request?.number ? String(event.pull_request.number) : void 0;
|
|
16
|
+
} catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
22
|
+
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
23
|
+
* always registered agents under, so an existing repository keeps reusing its agent.
|
|
24
|
+
*/
|
|
25
|
+
function detectCi(env = process.env) {
|
|
26
|
+
if (env.GITHUB_ACTIONS) {
|
|
27
|
+
const pullRequestNumber = readGithubPullRequestNumber(env.GITHUB_EVENT_PATH);
|
|
28
|
+
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
29
|
+
const scope = pullRequestNumber ?? env.GITHUB_RUN_ID ?? "";
|
|
30
|
+
return {
|
|
31
|
+
id: `gh:${repositoryId}:${scope}`,
|
|
32
|
+
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (env.GITLAB_CI) {
|
|
36
|
+
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
37
|
+
return {
|
|
38
|
+
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
39
|
+
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
43
|
+
const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? "";
|
|
44
|
+
return {
|
|
45
|
+
id: `bb:${env.BITBUCKET_REPO_UUID ?? ""}:${scope}`,
|
|
46
|
+
name: `${env.BITBUCKET_REPO_FULL_NAME ?? "bitbucket"}#${scope}`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (env.CIRCLECI) {
|
|
50
|
+
const owner = env.CIRCLE_PROJECT_USERNAME ?? "";
|
|
51
|
+
const project = env.CIRCLE_PROJECT_REPONAME ?? "circleci";
|
|
52
|
+
const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? "";
|
|
53
|
+
return {
|
|
54
|
+
id: `circle:${owner}:${project}:${scope}`,
|
|
55
|
+
name: `${owner ? `${owner}/` : ""}${project}#${scope}`
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/runners/studio/snapshot.ts
|
|
62
|
+
/**
|
|
63
|
+
* How long to wait for Studio's `studio:ready` acknowledgement, above the client's own 10s
|
|
64
|
+
* handshake-ack timeout.
|
|
65
|
+
*/
|
|
66
|
+
const READY_TIMEOUT_MS = 15e3;
|
|
67
|
+
/**
|
|
68
|
+
* Longest `--timeout` accepted. Job records expire from Studio's storage after an hour.
|
|
69
|
+
*/
|
|
70
|
+
const MAX_TIMEOUT_SECONDS = 3600;
|
|
71
|
+
const LOOPBACK_HOSTS = /* @__PURE__ */ new Set([
|
|
72
|
+
"localhost",
|
|
73
|
+
"127.0.0.1",
|
|
74
|
+
"::1"
|
|
75
|
+
]);
|
|
76
|
+
async function findPackageJson(startDirectory) {
|
|
77
|
+
let directory = startDirectory;
|
|
78
|
+
for (;;) {
|
|
79
|
+
const file = join(directory, "package.json");
|
|
80
|
+
if (await exists(file)) {
|
|
81
|
+
const packageJson = JSON.parse(await read(file));
|
|
82
|
+
if (packageJson.name && packageJson.version) return {
|
|
83
|
+
name: packageJson.name,
|
|
84
|
+
version: packageJson.version
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const parent = dirname(directory);
|
|
88
|
+
if (parent === directory) break;
|
|
89
|
+
directory = parent;
|
|
90
|
+
}
|
|
91
|
+
throw new Error(`No package.json with a name and a version found above ${startDirectory}`);
|
|
92
|
+
}
|
|
93
|
+
/** Reads package.json only for whichever of name/version --name and --version did not supply. */
|
|
94
|
+
async function resolvePackageMetadata(options) {
|
|
95
|
+
if (options.name && options.packageVersion) return {
|
|
96
|
+
name: options.name,
|
|
97
|
+
version: options.packageVersion
|
|
98
|
+
};
|
|
99
|
+
const packageMetadata = await findPackageJson(process.cwd());
|
|
100
|
+
return {
|
|
101
|
+
name: options.name ?? packageMetadata.name,
|
|
102
|
+
version: options.packageVersion ?? packageMetadata.version
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function resolveToken(options) {
|
|
106
|
+
const token = options.token ?? process.env.KUBB_TOKEN;
|
|
107
|
+
if (!token) throw new Error("An organization CI API key is required. Pass --token or set KUBB_TOKEN.");
|
|
108
|
+
return token;
|
|
109
|
+
}
|
|
110
|
+
function resolveCiIdentity(options) {
|
|
111
|
+
const detected = detectCi();
|
|
112
|
+
if (options.id) return {
|
|
113
|
+
id: options.id,
|
|
114
|
+
name: detected?.name ?? options.id
|
|
115
|
+
};
|
|
116
|
+
if (!detected) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
117
|
+
return detected;
|
|
118
|
+
}
|
|
119
|
+
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
120
|
+
function resolveTimeoutMs(options) {
|
|
121
|
+
const seconds = options.timeout ?? 600;
|
|
122
|
+
if (!Number.isFinite(seconds) || seconds <= 0) throw new Error("--timeout must be a positive number of seconds");
|
|
123
|
+
return Math.min(seconds, MAX_TIMEOUT_SECONDS) * 1e3;
|
|
124
|
+
}
|
|
125
|
+
/** The CI key is a credential, so refuse to send it anywhere but HTTPS or a loopback dev host. */
|
|
126
|
+
function assertSecureStudioUrl(studioUrl) {
|
|
127
|
+
const url = new URL(studioUrl);
|
|
128
|
+
if (url.protocol !== "https:" && !LOOPBACK_HOSTS.has(url.hostname)) throw new Error(`Refusing to send the CI API key to ${studioUrl}. Use an https:// Studio URL, or a loopback host for local development.`);
|
|
129
|
+
}
|
|
130
|
+
function absoluteUrl(studioUrl, path) {
|
|
131
|
+
return new URL(path, `${studioUrl}/`).toString();
|
|
132
|
+
}
|
|
133
|
+
function toResult(studioUrl, snapshot, agentSlug) {
|
|
134
|
+
return {
|
|
135
|
+
id: snapshot.id,
|
|
136
|
+
name: snapshot.name,
|
|
137
|
+
version: snapshot.version,
|
|
138
|
+
integrity: snapshot.integrity,
|
|
139
|
+
url: absoluteUrl(studioUrl, snapshot.url),
|
|
140
|
+
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
141
|
+
expiresAt: snapshot.expiresAt,
|
|
142
|
+
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function printSummary(result) {
|
|
146
|
+
logBlock([
|
|
147
|
+
`${styleText("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
148
|
+
`${styleText("dim", "Tarball".padEnd(10))} ${styleText("cyan", result.url)}`,
|
|
149
|
+
`${styleText("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
150
|
+
`${styleText("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Generates a Kubb Studio snapshot from a script: registers or reuses a CI agent, connects it,
|
|
155
|
+
* queues a snapshot job, and polls until the tarball is ready. A snapshot job runs generation and
|
|
156
|
+
* packs the tarball in one step, so this needs no separate generation run.
|
|
157
|
+
*/
|
|
158
|
+
async function snapshot(options) {
|
|
159
|
+
const timeoutMs = resolveTimeoutMs(options);
|
|
160
|
+
const token = resolveToken(options);
|
|
161
|
+
assertSecureStudioUrl(options.studioUrl);
|
|
162
|
+
const { configPath } = await loadConfigs(options);
|
|
163
|
+
const ci = resolveCiIdentity(options);
|
|
164
|
+
const { name, version: packageVersion } = await resolvePackageMetadata(options);
|
|
165
|
+
process.env.KUBB_AGENT_SECRET = ci.id;
|
|
166
|
+
const spinner = options.json ? null : createSpinner();
|
|
167
|
+
const log = (message) => {
|
|
168
|
+
if (options.json) {
|
|
169
|
+
console.error(message);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
spinner?.message(message);
|
|
173
|
+
};
|
|
174
|
+
if (options.json) log("Creating Kubb Studio agent");
|
|
175
|
+
if (!options.json) spinner?.start("Creating Kubb Studio agent");
|
|
176
|
+
const agent = await createAgent({
|
|
177
|
+
studioUrl: options.studioUrl,
|
|
178
|
+
token,
|
|
179
|
+
name: ci.name,
|
|
180
|
+
machineToken: machineTokenFrom(ci.id)
|
|
181
|
+
});
|
|
182
|
+
const { promise: ready, reject: markFailed, resolve: markReady } = Promise.withResolvers();
|
|
183
|
+
const client = createClient({
|
|
184
|
+
studioUrl: options.studioUrl,
|
|
185
|
+
token: agent.token,
|
|
186
|
+
configPath,
|
|
187
|
+
root: process.cwd(),
|
|
188
|
+
version: options.version,
|
|
189
|
+
client: { kind: "cli" },
|
|
190
|
+
logLevel: logLevel[options.logLevel ?? "info"],
|
|
191
|
+
loadConfig: async () => (await loadConfigs(options)).config,
|
|
192
|
+
installLogger: (hooks) => {
|
|
193
|
+
hooks.hook("studio:connecting", ({ url }) => log(`Connecting to Kubb Studio at ${url}`));
|
|
194
|
+
hooks.hook("studio:connected", ({ url }) => log(`Connected to Kubb Studio at ${url}`));
|
|
195
|
+
hooks.hook("studio:ready", () => {
|
|
196
|
+
log("Kubb Studio connection ready");
|
|
197
|
+
markReady();
|
|
198
|
+
});
|
|
199
|
+
hooks.hook("studio:warn", ({ message }) => log(`Kubb Studio warning: ${message}`));
|
|
200
|
+
hooks.hook("studio:error", ({ error }) => markFailed(error));
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
await client.connect();
|
|
204
|
+
try {
|
|
205
|
+
let readyTimeoutHandle;
|
|
206
|
+
try {
|
|
207
|
+
await Promise.race([ready, new Promise((_, reject) => {
|
|
208
|
+
readyTimeoutHandle = setTimeout(() => reject(/* @__PURE__ */ new Error("Timed out waiting for Kubb Studio to confirm the agent was ready")), READY_TIMEOUT_MS);
|
|
209
|
+
})]);
|
|
210
|
+
} finally {
|
|
211
|
+
clearTimeout(readyTimeoutHandle);
|
|
212
|
+
}
|
|
213
|
+
log("Creating snapshot job");
|
|
214
|
+
const job = await createJob({
|
|
215
|
+
studioUrl: options.studioUrl,
|
|
216
|
+
token,
|
|
217
|
+
type: "snapshot",
|
|
218
|
+
agentId: agent.id,
|
|
219
|
+
name,
|
|
220
|
+
version: packageVersion
|
|
221
|
+
});
|
|
222
|
+
log(`Snapshot job queued: ${job.id}`);
|
|
223
|
+
const finished = await waitForJob({
|
|
224
|
+
studioUrl: options.studioUrl,
|
|
225
|
+
token,
|
|
226
|
+
id: job.id,
|
|
227
|
+
timeoutMs
|
|
228
|
+
});
|
|
229
|
+
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
230
|
+
if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
|
|
231
|
+
const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
|
|
232
|
+
if (options.json) log("Snapshot published");
|
|
233
|
+
if (!options.json) spinner?.stop("Snapshot published");
|
|
234
|
+
if (options.json) console.log(JSON.stringify(result));
|
|
235
|
+
if (!options.json) printSummary(result);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (options.json) log("Snapshot failed");
|
|
238
|
+
if (!options.json) spinner?.stop("Snapshot failed");
|
|
239
|
+
throw error;
|
|
240
|
+
} finally {
|
|
241
|
+
if (options.json) log("Disconnecting from Kubb Studio");
|
|
242
|
+
client.disconnect();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const runner = async ({ values }) => {
|
|
246
|
+
const options = {
|
|
247
|
+
...createStudioOptions(values),
|
|
248
|
+
token: values.token,
|
|
249
|
+
id: values.id,
|
|
250
|
+
name: values.name,
|
|
251
|
+
packageVersion: values.packageVersion,
|
|
252
|
+
timeout: values.timeout,
|
|
253
|
+
json: values.json
|
|
254
|
+
};
|
|
255
|
+
await run(options, () => snapshot(options), { json: options.json });
|
|
256
|
+
};
|
|
257
|
+
//#endregion
|
|
258
|
+
export { runner };
|
|
259
|
+
|
|
260
|
+
//# sourceMappingURL=snapshot-Dhwz_MpL.js.map
|