@supacloud/admin 0.15.2 → 0.15.4

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/index.js CHANGED
@@ -4757,6 +4757,11 @@ var require_utils = __commonJS((exports, module) => {
4757
4757
  };
4758
4758
  });
4759
4759
 
4760
+ // node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
4761
+ var require_sshcrypto = __commonJS((exports, module) => {
4762
+ module.exports = __require("./sshcrypto-vd2k5hq9.node");
4763
+ });
4764
+
4760
4765
  // node_modules/ssh2/lib/protocol/crypto/poly1305.js
4761
4766
  var require_poly1305 = __commonJS((exports, module) => {
4762
4767
  var __dirname = "/home/runner/work/supacloud/supacloud/packages/admin/node_modules/ssh2/lib/protocol/crypto", __filename = "/home/runner/work/supacloud/supacloud/packages/admin/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
@@ -5243,7 +5248,7 @@ var require_crypto = __commonJS((exports, module) => {
5243
5248
  var ChaChaPolyDecipher;
5244
5249
  var GenericDecipher;
5245
5250
  try {
5246
- binding = (()=>{throw new Error("Cannot require module "+"./crypto/build/Release/sshcrypto.node");})();
5251
+ binding = require_sshcrypto();
5247
5252
  ({
5248
5253
  AESGCMCipher,
5249
5254
  ChaChaPolyCipher,
@@ -26376,6 +26381,14 @@ var RELEASE_CHECKSUMS_NAME = "SHA256SUMS";
26376
26381
  var RELEASE_REPOSITORY = "vibeunion/supacloud";
26377
26382
  var RELEASE_SOURCE_REF = "refs/heads/main";
26378
26383
  var RELEASE_SIGNER_WORKFLOW = `${RELEASE_REPOSITORY}/.github/workflows/release-please.yml`;
26384
+ var LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY = {
26385
+ repository: "zuohuadong/supacloud",
26386
+ workflow: "zuohuadong/supacloud/.github/workflows/release-please.yml",
26387
+ component: "edge-runtime",
26388
+ version: "0.18.2",
26389
+ tag: "edge-runtime-v0.18.2",
26390
+ sourceCommit: "c6a3a87cf4e41e0f3dafadb018dd0c7d5b99b7d9"
26391
+ };
26379
26392
  var MEBIBYTE = 1024 * 1024;
26380
26393
  var RELEASE_BUNDLE_SIZE_LIMITS = {
26381
26394
  manifest: MEBIBYTE,
@@ -26482,6 +26495,16 @@ function parseArtifacts(candidate, component) {
26482
26495
  throw new Error(`Release manifest artifact ${oversized.name} exceeds its size limit`);
26483
26496
  return artifacts;
26484
26497
  }
26498
+ function parseIdentity(manifest, source, release) {
26499
+ const current = manifest.repository === RELEASE_REPOSITORY && manifest.workflow === RELEASE_SIGNER_WORKFLOW;
26500
+ const legacyEdgeRuntime = manifest.repository === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.repository && manifest.workflow === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.workflow && release.component === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.component && release.version === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.version && release.tag === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.tag && source.commit === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.sourceCommit;
26501
+ if (!current && !legacyEdgeRuntime)
26502
+ throw new Error("Release manifest identity is invalid");
26503
+ return {
26504
+ repository: manifest.repository,
26505
+ workflow: manifest.workflow
26506
+ };
26507
+ }
26485
26508
  function parseReleaseManifest(text, expected) {
26486
26509
  let candidate;
26487
26510
  try {
@@ -26491,15 +26514,16 @@ function parseReleaseManifest(text, expected) {
26491
26514
  }
26492
26515
  const manifest = manifestObject(candidate, "Release manifest");
26493
26516
  assertExactKeys(manifest, ["schemaVersion", "repository", "source", "workflow", "release", "artifacts"], "Release manifest");
26494
- if (manifest.schemaVersion !== 1 || manifest.repository !== RELEASE_REPOSITORY || manifest.workflow !== RELEASE_SIGNER_WORKFLOW) {
26517
+ if (manifest.schemaVersion !== 1)
26495
26518
  throw new Error("Release manifest identity is invalid");
26496
- }
26519
+ const source = parseSource(manifest.source);
26520
+ const release = parseRelease(manifest.release, expected);
26521
+ const identity = parseIdentity(manifest, source, release);
26497
26522
  return {
26498
26523
  schemaVersion: 1,
26499
- repository: RELEASE_REPOSITORY,
26500
- source: parseSource(manifest.source),
26501
- workflow: RELEASE_SIGNER_WORKFLOW,
26502
- release: parseRelease(manifest.release, expected),
26524
+ ...identity,
26525
+ source,
26526
+ release,
26503
26527
  artifacts: parseArtifacts(manifest.artifacts, expected.component)
26504
26528
  };
26505
26529
  }
@@ -26625,6 +26649,7 @@ async function withSigstoreVerificationDirectory(operation) {
26625
26649
  // src/shared/releases/local-upgrade-bundle.ts
26626
26650
  var RELEASES_API = `https://api.github.com/repos/${RELEASE_REPOSITORY}/releases`;
26627
26651
  var ATTESTATIONS_API = `https://api.github.com/repos/${RELEASE_REPOSITORY}/attestations`;
26652
+ var GITHUB_CLI_REPOSITORY = "cli/cli";
26628
26653
  var GH_VERSION = "2.96.0";
26629
26654
  var GH_ARCHIVE_SHA256 = {
26630
26655
  amd64: "83d5c2ccad5498f58bf6368acb1ab32588cf43ab3a4b1c301bf36328b1c8bd60",
@@ -26835,6 +26860,36 @@ async function downloadDirect(url, destination, maxBytes) {
26835
26860
  }
26836
26861
  throw new AggregateError(retryFailures, `Unable to download ${parsed.hostname}${parsed.pathname}`);
26837
26862
  }
26863
+ async function downloadGithubReleaseAsset(request) {
26864
+ const download = await runGithubCliDownload([
26865
+ "release",
26866
+ "download",
26867
+ request.tag,
26868
+ "--repo",
26869
+ `github.com/${request.repository}`,
26870
+ "--pattern",
26871
+ request.assetName,
26872
+ "--output",
26873
+ "-"
26874
+ ], request.destination, request.maxBytes, DOWNLOAD_TIMEOUT_MS);
26875
+ if (download.exitCode !== 0) {
26876
+ rmSync2(request.destination, { force: true });
26877
+ throw new Error(`GitHub release asset download failed: ${download.stderr.trim().slice(-1000) || download.exitCode}`);
26878
+ }
26879
+ assertDownloadedReleaseAsset(request);
26880
+ }
26881
+ function assertDownloadedReleaseAsset(request) {
26882
+ const stats = lstatSync(request.destination);
26883
+ if (!stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1) {
26884
+ rmSync2(request.destination, { force: true });
26885
+ throw new Error("GitHub release asset must be a direct regular file");
26886
+ }
26887
+ if (stats.size > request.maxBytes) {
26888
+ rmSync2(request.destination, { force: true });
26889
+ throw new Error(`GitHub release asset exceeded ${request.maxBytes} bytes`);
26890
+ }
26891
+ chmodSync2(request.destination, 384);
26892
+ }
26838
26893
  function parseJsonFile(filePath, label) {
26839
26894
  const contents = readFileSync3(filePath, "utf8");
26840
26895
  try {
@@ -26906,7 +26961,7 @@ function serializeAttestationBundles(candidate) {
26906
26961
  function directEnvironment() {
26907
26962
  const environment = { ...process.env };
26908
26963
  for (const key of Object.keys(environment)) {
26909
- if (/(?:^|_)proxy$/i.test(key) || /^(?:SUPACLOUD_GITHUB_PROXIES|NODE_USE_ENV_PROXY)$/.test(key)) {
26964
+ if (/(?:^|_)proxy$/i.test(key) || /^(?:GH_HOST|GH_REPO|SUPACLOUD_GITHUB_PROXIES|NODE_USE_ENV_PROXY)$/.test(key)) {
26910
26965
  delete environment[key];
26911
26966
  }
26912
26967
  }
@@ -26931,15 +26986,15 @@ function githubCliExecutable(environment) {
26931
26986
  }
26932
26987
  throw new Error("GitHub CLI executable was not found in PATH");
26933
26988
  }
26934
- async function runGithubCli(arguments_, timeoutMs) {
26935
- return await new Promise((resolve2, reject) => {
26936
- const environment = directEnvironment();
26937
- const child = spawn(githubCliExecutable(environment), arguments_, {
26938
- env: environment,
26939
- stdio: ["ignore", "pipe", "pipe"]
26940
- });
26941
- let stdout = "";
26942
- let stderr = "";
26989
+ function spawnGithubCli(arguments_) {
26990
+ const environment = directEnvironment();
26991
+ return spawn(githubCliExecutable(environment), arguments_, {
26992
+ env: environment,
26993
+ stdio: ["ignore", "pipe", "pipe"]
26994
+ });
26995
+ }
26996
+ function githubCliExitCode(child, timeoutMs) {
26997
+ return new Promise((resolve2, reject) => {
26943
26998
  let timedOut = false;
26944
26999
  let settled = false;
26945
27000
  let forceKillTimer;
@@ -26958,18 +27013,46 @@ async function runGithubCli(arguments_, timeoutMs) {
26958
27013
  if (error)
26959
27014
  reject(error);
26960
27015
  else
26961
- resolve2({ exitCode: timedOut ? 124 : exitCode, stdout, stderr });
27016
+ resolve2(timedOut ? 124 : exitCode);
26962
27017
  };
26963
- child.stdout.on("data", (chunk) => {
26964
- stdout = `${stdout}${chunk.toString()}`.slice(-8000);
26965
- });
26966
- child.stderr.on("data", (chunk) => {
26967
- stderr = `${stderr}${chunk.toString()}`.slice(-8000);
26968
- });
26969
27018
  child.once("error", (error) => settleExecution(error, 127));
26970
27019
  child.once("close", (code) => settleExecution(undefined, code ?? 1));
26971
27020
  });
26972
27021
  }
27022
+ async function runGithubCli(arguments_, timeoutMs) {
27023
+ const child = spawnGithubCli(arguments_);
27024
+ let stdout = "";
27025
+ let stderr = "";
27026
+ child.stdout.on("data", (chunk) => {
27027
+ stdout = `${stdout}${chunk.toString()}`.slice(-8000);
27028
+ });
27029
+ child.stderr.on("data", (chunk) => {
27030
+ stderr = `${stderr}${chunk.toString()}`.slice(-8000);
27031
+ });
27032
+ const exitCode = await githubCliExitCode(child, timeoutMs);
27033
+ return { exitCode, stdout, stderr };
27034
+ }
27035
+ async function runGithubCliDownload(arguments_, destination, maxBytes, timeoutMs) {
27036
+ const child = spawnGithubCli(arguments_);
27037
+ let stderr = "";
27038
+ child.stderr.on("data", (chunk) => {
27039
+ stderr = `${stderr}${chunk.toString()}`.slice(-8000);
27040
+ });
27041
+ const write = pipeline(child.stdout, boundedWriter(maxBytes), createWriteStream(destination, { flags: "wx", mode: 384 })).catch((error) => {
27042
+ child.kill("SIGKILL");
27043
+ throw error;
27044
+ });
27045
+ const [writeState, exitState] = await Promise.allSettled([write, githubCliExitCode(child, timeoutMs)]);
27046
+ if (writeState.status === "rejected") {
27047
+ rmSync2(destination, { force: true });
27048
+ throw writeState.reason;
27049
+ }
27050
+ if (exitState.status === "rejected") {
27051
+ rmSync2(destination, { force: true });
27052
+ throw exitState.reason;
27053
+ }
27054
+ return { exitCode: exitState.value, stdout: "", stderr };
27055
+ }
26973
27056
  function supportsStrictGithubVerification(execution) {
26974
27057
  const tokens = `${execution.stdout}
26975
27058
  ${execution.stderr}`.split(/\s+/);
@@ -26989,11 +27072,11 @@ function githubAttestationVerificationArguments(request) {
26989
27072
  "--bundle",
26990
27073
  request.bundlePath,
26991
27074
  "--repo",
26992
- RELEASE_REPOSITORY,
27075
+ request.manifest.repository,
26993
27076
  "--signer-workflow",
26994
- RELEASE_SIGNER_WORKFLOW,
27077
+ request.manifest.workflow,
26995
27078
  "--source-ref",
26996
- RELEASE_SOURCE_REF,
27079
+ request.manifest.source.ref,
26997
27080
  "--source-digest",
26998
27081
  request.manifest.source.commit,
26999
27082
  "--deny-self-hosted-runners",
@@ -27036,10 +27119,30 @@ async function downloadReleaseMetadata(component, version, directory) {
27036
27119
  rmSync2(metadataPath, { force: true });
27037
27120
  }
27038
27121
  }
27039
- async function downloadManifestAttestation(manifestPath, destination) {
27122
+ function manifestAttestationDownloadUrl(release, manifest, manifestDigest) {
27123
+ if (manifest.repository === RELEASE_REPOSITORY) {
27124
+ return `${ATTESTATIONS_API}/sha256:${manifestDigest}`;
27125
+ }
27126
+ if (manifest.repository === LEGACY_EDGE_RUNTIME_RELEASE_IDENTITY.repository) {
27127
+ return releaseAssetUrl(release, RELEASE_ATTESTATION_NAME);
27128
+ }
27129
+ throw new Error("Release manifest repository is not supported");
27130
+ }
27131
+ async function downloadManifestAttestation(request) {
27132
+ const { release, manifest, manifestPath, destination } = request;
27133
+ if (manifest.repository !== RELEASE_REPOSITORY) {
27134
+ await downloadGithubReleaseAsset({
27135
+ repository: RELEASE_REPOSITORY,
27136
+ tag: release.tag_name,
27137
+ assetName: RELEASE_ATTESTATION_NAME,
27138
+ destination,
27139
+ maxBytes: RELEASE_BUNDLE_SIZE_LIMITS.attestation
27140
+ });
27141
+ return;
27142
+ }
27040
27143
  const responsePath = `${destination}.response`;
27041
27144
  try {
27042
- await downloadDirect(`${ATTESTATIONS_API}/sha256:${sha256File(manifestPath)}`, responsePath, RELEASE_BUNDLE_SIZE_LIMITS.attestation);
27145
+ await downloadDirect(manifestAttestationDownloadUrl(release, manifest, sha256File(manifestPath)), responsePath, RELEASE_BUNDLE_SIZE_LIMITS.attestation);
27043
27146
  const bundles = serializeAttestationBundles(parseJsonFile(responsePath, "GitHub attestation response"));
27044
27147
  writeFileSync2(destination, bundles, { mode: 384, flag: "wx" });
27045
27148
  chmodSync2(destination, 384);
@@ -27051,9 +27154,16 @@ async function downloadComponent(request) {
27051
27154
  const release = await downloadReleaseMetadata(request.component, request.version, request.destination);
27052
27155
  const manifestPath = directChildPath(request.destination, RELEASE_MANIFEST_NAME);
27053
27156
  const attestationPath = directChildPath(request.destination, RELEASE_ATTESTATION_NAME);
27054
- await downloadDirect(releaseAssetUrl(release, RELEASE_MANIFEST_NAME), manifestPath, RELEASE_BUNDLE_SIZE_LIMITS.manifest);
27157
+ releaseAssetUrl(release, RELEASE_MANIFEST_NAME);
27158
+ await downloadGithubReleaseAsset({
27159
+ repository: RELEASE_REPOSITORY,
27160
+ tag: release.tag_name,
27161
+ assetName: RELEASE_MANIFEST_NAME,
27162
+ destination: manifestPath,
27163
+ maxBytes: RELEASE_BUNDLE_SIZE_LIMITS.manifest
27164
+ });
27055
27165
  const manifest = parseReleaseManifest(readFileSync3(manifestPath, "utf8"), request);
27056
- await downloadManifestAttestation(manifestPath, attestationPath);
27166
+ await downloadManifestAttestation({ release, manifest, manifestPath, destination: attestationPath });
27057
27167
  await verifyManifestAttestation({
27058
27168
  artifactPath: manifestPath,
27059
27169
  bundlePath: attestationPath,
@@ -27061,12 +27171,26 @@ async function downloadComponent(request) {
27061
27171
  trustedRootPath: request.trustedRootPath
27062
27172
  });
27063
27173
  const checksumsPath = directChildPath(request.destination, RELEASE_CHECKSUMS_NAME);
27064
- await downloadDirect(releaseAssetUrl(release, RELEASE_CHECKSUMS_NAME), checksumsPath, RELEASE_BUNDLE_SIZE_LIMITS.checksums);
27174
+ releaseAssetUrl(release, RELEASE_CHECKSUMS_NAME);
27175
+ await downloadGithubReleaseAsset({
27176
+ repository: RELEASE_REPOSITORY,
27177
+ tag: release.tag_name,
27178
+ assetName: RELEASE_CHECKSUMS_NAME,
27179
+ destination: checksumsPath,
27180
+ maxBytes: RELEASE_BUNDLE_SIZE_LIMITS.checksums
27181
+ });
27065
27182
  assertSignedArtifact(checksumsPath, manifest);
27066
27183
  const checksums = parseReleaseChecksums(readFileSync3(checksumsPath, "utf8"), manifest);
27067
27184
  for (const assetName of request.assetNames) {
27068
27185
  const assetPath = directChildPath(request.destination, assetName);
27069
- await downloadDirect(releaseAssetUrl(release, assetName), assetPath, releaseAssetSizeLimit(request.component, assetName));
27186
+ releaseAssetUrl(release, assetName);
27187
+ await downloadGithubReleaseAsset({
27188
+ repository: RELEASE_REPOSITORY,
27189
+ tag: release.tag_name,
27190
+ assetName,
27191
+ destination: assetPath,
27192
+ maxBytes: releaseAssetSizeLimit(request.component, assetName)
27193
+ });
27070
27194
  verifyDownloadedFile(assetPath, manifest, checksums);
27071
27195
  }
27072
27196
  return [RELEASE_MANIFEST_NAME, RELEASE_ATTESTATION_NAME, RELEASE_CHECKSUMS_NAME, ...request.assetNames].map((name) => localUpgradeFile(directChildPath(request.destination, name), `bundle/${request.component}/${name}`));
@@ -27074,8 +27198,13 @@ async function downloadComponent(request) {
27074
27198
  async function downloadPinnedGithubCli(directory, architecture) {
27075
27199
  const identity = githubCliArchiveIdentity(architecture);
27076
27200
  const archivePath = directChildPath(directory, identity.archiveName);
27077
- const url = `https://github.com/cli/cli/releases/download/v${identity.version}/${identity.archiveName}`;
27078
- await downloadDirect(url, archivePath, MAX_GH_ARCHIVE_BYTES);
27201
+ await downloadGithubReleaseAsset({
27202
+ repository: GITHUB_CLI_REPOSITORY,
27203
+ tag: `v${identity.version}`,
27204
+ assetName: identity.archiveName,
27205
+ destination: archivePath,
27206
+ maxBytes: MAX_GH_ARCHIVE_BYTES
27207
+ });
27079
27208
  if (sha256File(archivePath) !== identity.sha256) {
27080
27209
  throw new Error("Pinned GitHub CLI archive SHA256 mismatch");
27081
27210
  }
@@ -32116,7 +32245,7 @@ Actions: list_releases, get_release, upload_release, activate_release`, {
32116
32245
  // package.json
32117
32246
  var package_default = {
32118
32247
  name: "@supacloud/admin",
32119
- version: "0.15.2",
32248
+ version: "0.15.4",
32120
32249
  description: "Platform administration CLI for SupaCloud operators",
32121
32250
  type: "module",
32122
32251
  main: "./dist/index.js",
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/admin",
3
- "version": "0.15.2",
3
+ "version": "0.15.4",
4
4
  "description": "Platform administration CLI for SupaCloud operators",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",