🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@aptos-labs/aptos-cli

Package Overview
Dependencies
Maintainers
2
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aptos-labs/aptos-cli - npm Package Compare versions

Comparing version
2.0.0
to
3.0.0
+44
-17
dist/tasks/install.js

@@ -1,3 +0,4 @@

import { execSync } from "node:child_process";
import { chmodSync, existsSync, mkdirSync } from "node:fs";
import { execFileSync, execSync } from "node:child_process";
import { createHash } from "node:crypto";
import { chmodSync, createReadStream, existsSync, mkdirSync, renameSync, } from "node:fs";
import { tmpdir } from "node:os";

@@ -8,8 +9,31 @@ import { join } from "node:path";

import { getBinDir, getLocalBinPath, invalidateBinPathCache, } from "../utils/getLocalBinPath.js";
import { getOS, getTargetPlatform } from "../utils/getUserOs.js";
import { getCliVersion, hasUserSpecifiedVersion, } from "../utils/ghOperations.js";
import { getPlatformInfo, getTargetPlatform } from "../utils/getUserOs.js";
import { getAssetDigest, getCliVersion, hasUserSpecifiedVersion, } from "../utils/ghOperations.js";
import { installViaChoco, installViaWinget, isChocoAvailable, isInstalledViaChoco, isInstalledViaWinget, isWingetAvailable, } from "../utils/windowsPackageManagers.js";
const sha256File = (filePath) => {
return new Promise((resolve, reject) => {
const hash = createHash("sha256");
const stream = createReadStream(filePath);
stream.on("data", (chunk) => hash.update(chunk));
stream.on("end", () => resolve(hash.digest("hex")));
stream.on("error", reject);
});
};
const verifyChecksum = async (filePath, expectedDigest) => {
if (!expectedDigest) {
console.log("Checksum not available from GitHub API, skipping verification");
return;
}
const actual = await sha256File(filePath);
if (actual !== expectedDigest) {
throw new Error(`Checksum verification failed!\n` +
` Expected: ${expectedDigest}\n` +
` Actual: ${actual}\n` +
`The downloaded file may be corrupted or tampered with.`);
}
console.log("Checksum verified");
};
export const installCli = async (directDownload = false) => {
invalidateBinPathCache();
const os = getOS();
const { os } = getPlatformInfo();
const useDirectDownload = directDownload || hasUserSpecifiedVersion();

@@ -20,3 +44,3 @@ if (useDirectDownload && hasUserSpecifiedVersion()) {

if (!useDirectDownload) {
if (os === "MacOS" && isBrewAvailable()) {
if (os === "macos" && isBrewAvailable()) {
if (isInstalledViaBrew()) {

@@ -29,3 +53,3 @@ console.log("Aptos CLI is already installed via Homebrew");

}
if (os === "Windows") {
if (os === "windows") {
if (isWingetAvailable()) {

@@ -61,9 +85,12 @@ if (isInstalledViaWinget()) {

console.log(`Downloading Aptos CLI version ${version} for ${targetPlatform}...`);
const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${PNAME}-${version}-${targetPlatform}.zip`;
const assetName = `${PNAME}-${version}-${targetPlatform}.zip`;
const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${assetName}`;
const expectedDigest = await getAssetDigest(version, assetName);
const tempDir = tmpdir();
const zipPath = join(tempDir, "aptos-cli.zip");
try {
if (os === "Windows") {
const zipPath = join(tempDir, "aptos-cli.zip");
if (os === "windows") {
execSync(`powershell -Command "Invoke-WebRequest -Uri '${url}' -OutFile '${zipPath}'"`, { stdio: "inherit" });
await verifyChecksum(zipPath, expectedDigest);
execSync(`powershell -Command "` +
`Invoke-WebRequest -Uri '${url}' -OutFile '${zipPath}'; ` +
`Expand-Archive -Path '${zipPath}' -DestinationPath '${binDir}' -Force; ` +

@@ -73,12 +100,12 @@ `Remove-Item -Path '${zipPath}' -Force"`, { stdio: "inherit" });

else {
const zipPath = join(tempDir, "aptos-cli.zip");
execSync(`curl -L -o "${zipPath}" "${url}"`, { stdio: "inherit" });
execSync(`unzip -o -q "${zipPath}" -d "${tempDir}"`, {
execFileSync("curl", ["-L", "-o", zipPath, url], { stdio: "inherit" });
await verifyChecksum(zipPath, expectedDigest);
execFileSync("unzip", ["-o", "-q", zipPath, "-d", tempDir], {
stdio: "inherit",
});
const extractedBinary = join(tempDir, "aptos");
execSync(`mv "${extractedBinary}" "${binaryPath}"`, { stdio: "inherit" });
renameSync(extractedBinary, binaryPath);
chmodSync(binaryPath, 0o755);
try {
execSync(`rm -f "${zipPath}"`, { stdio: "ignore" });
execFileSync("rm", ["-f", zipPath], { stdio: "ignore" });
}

@@ -89,3 +116,3 @@ catch {

console.log(`Aptos CLI installed successfully to ${binaryPath}`);
if (os !== "Windows") {
if (os !== "windows") {
console.log(`\nMake sure ${binDir} is in your PATH. You can add it by running:`);

@@ -92,0 +119,0 @@ console.log(` export PATH="${binDir}:$PATH"`);

@@ -1,1 +0,1 @@

{"version":3,"file":"install.js","sourceRoot":"","sources":["../../bin/tasks/install.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from \"node:child_process\";\nimport { chmodSync, existsSync, mkdirSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n installViaBrew,\n isBrewAvailable,\n isInstalledViaBrew,\n} from \"../utils/brewOperations.js\";\nimport { GH_CLI_DOWNLOAD_URL, PNAME } from \"../utils/consts.js\";\nimport {\n getBinDir,\n getLocalBinPath,\n invalidateBinPathCache,\n} from \"../utils/getLocalBinPath.js\";\nimport { getOS, getTargetPlatform } from \"../utils/getUserOs.js\";\nimport {\n getCliVersion,\n hasUserSpecifiedVersion,\n} from \"../utils/ghOperations.js\";\nimport {\n installViaChoco,\n installViaWinget,\n isChocoAvailable,\n isInstalledViaChoco,\n isInstalledViaWinget,\n isWingetAvailable,\n} from \"../utils/windowsPackageManagers.js\";\n\n/**\n * Install the Aptos CLI.\n *\n * Installation priority:\n *\n * macOS:\n * 1. Homebrew (if available)\n * 2. Direct download from GitHub releases\n *\n * Windows:\n * 1. winget (if available)\n * 2. Chocolatey (if available)\n * 3. Direct download from GitHub releases\n *\n * Linux:\n * - Direct download from GitHub releases\n *\n * Note: When APTOS_CLI_VERSION is set, package managers are skipped and the\n * specified version is downloaded directly from GitHub releases.\n *\n * @param directDownload - If true, skip package managers and download directly\n */\nexport const installCli = async (\n directDownload: boolean = false,\n): Promise<void> => {\n invalidateBinPathCache();\n const os = getOS();\n\n // If a specific version is requested, force direct download\n // Package managers don't support installing specific versions\n const useDirectDownload = directDownload || hasUserSpecifiedVersion();\n\n if (useDirectDownload && hasUserSpecifiedVersion()) {\n console.log(\n `Using specified version from APTOS_CLI_VERSION: ${process.env.APTOS_CLI_VERSION}`,\n );\n }\n\n // Skip package managers if directDownload is set or specific version requested\n if (!useDirectDownload) {\n // On macOS, prefer Homebrew if available\n if (os === \"MacOS\" && isBrewAvailable()) {\n if (isInstalledViaBrew()) {\n console.log(\"Aptos CLI is already installed via Homebrew\");\n return;\n }\n installViaBrew();\n return;\n }\n\n // On Windows, prefer winget, then Chocolatey\n if (os === \"Windows\") {\n if (isWingetAvailable()) {\n if (isInstalledViaWinget()) {\n console.log(\"Aptos CLI is already installed via winget\");\n return;\n }\n installViaWinget();\n return;\n }\n\n if (isChocoAvailable()) {\n if (isInstalledViaChoco()) {\n console.log(\"Aptos CLI is already installed via Chocolatey\");\n return;\n }\n installViaChoco();\n return;\n }\n }\n }\n\n // Direct download installation\n const binaryPath = getLocalBinPath();\n if (existsSync(binaryPath)) {\n console.log(\"Aptos CLI is already installed\");\n return;\n }\n\n // Ensure the bin directory exists\n const binDir = getBinDir();\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n // Get target platform first for version validation\n const targetPlatform = getTargetPlatform();\n\n // Get the version to install (user-specified or latest)\n const version = await getCliVersion(targetPlatform);\n\n console.log(\n `Downloading Aptos CLI version ${version} for ${targetPlatform}...`,\n );\n\n // Build download URL matching official release artifact naming\n const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${PNAME}-${version}-${targetPlatform}.zip`;\n\n const tempDir = tmpdir();\n\n try {\n if (os === \"Windows\") {\n // Windows installation using PowerShell\n const zipPath = join(tempDir, \"aptos-cli.zip\");\n execSync(\n `powershell -Command \"` +\n `Invoke-WebRequest -Uri '${url}' -OutFile '${zipPath}'; ` +\n `Expand-Archive -Path '${zipPath}' -DestinationPath '${binDir}' -Force; ` +\n `Remove-Item -Path '${zipPath}' -Force\"`,\n { stdio: \"inherit\" },\n );\n } else {\n // macOS (without Homebrew) and Linux installation using curl/unzip\n const zipPath = join(tempDir, \"aptos-cli.zip\");\n\n // Download\n execSync(`curl -L -o \"${zipPath}\" \"${url}\"`, { stdio: \"inherit\" });\n\n // Extract\n execSync(`unzip -o -q \"${zipPath}\" -d \"${tempDir}\"`, {\n stdio: \"inherit\",\n });\n\n // Move binary to bin directory\n const extractedBinary = join(tempDir, \"aptos\");\n execSync(`mv \"${extractedBinary}\" \"${binaryPath}\"`, { stdio: \"inherit\" });\n\n // Set executable permissions\n chmodSync(binaryPath, 0o755);\n\n // Clean up\n try {\n execSync(`rm -f \"${zipPath}\"`, { stdio: \"ignore\" });\n } catch {\n // Ignore cleanup errors\n }\n }\n\n console.log(`Aptos CLI installed successfully to ${binaryPath}`);\n\n // Remind user about PATH if needed\n if (os !== \"Windows\") {\n console.log(\n `\\nMake sure ${binDir} is in your PATH. You can add it by running:`,\n );\n console.log(` export PATH=\"${binDir}:$PATH\"`);\n }\n } catch (error) {\n throw new Error(\n `Failed to install Aptos CLI: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n"]}
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../bin/tasks/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,cAAc,EACd,eAAe,EACf,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,SAAS,EACT,eAAe,EACf,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,aAAa,EACb,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,oCAAoC,CAAC;AAK5C,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAmB,EAAE;IACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAMF,MAAM,cAAc,GAAG,KAAK,EAC1B,QAAgB,EAChB,cAA6B,EACd,EAAE;IACjB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CACT,+DAA+D,CAChE,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,iCAAiC;YAC/B,eAAe,cAAc,IAAI;YACjC,eAAe,MAAM,IAAI;YACzB,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC,CAAC;AAwBF,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,iBAA0B,KAAK,EAChB,EAAE;IACjB,sBAAsB,EAAE,CAAC;IACzB,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,EAAE,CAAC;IAIjC,MAAM,iBAAiB,GAAG,cAAc,IAAI,uBAAuB,EAAE,CAAC;IAEtE,IAAI,iBAAiB,IAAI,uBAAuB,EAAE,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,mDAAmD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CACnF,CAAC;IACJ,CAAC;IAGD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEvB,IAAI,EAAE,KAAK,OAAO,IAAI,eAAe,EAAE,EAAE,CAAC;YACxC,IAAI,kBAAkB,EAAE,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YACD,cAAc,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAGD,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,IAAI,iBAAiB,EAAE,EAAE,CAAC;gBACxB,IAAI,oBAAoB,EAAE,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;oBACzD,OAAO;gBACT,CAAC;gBACD,gBAAgB,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,IAAI,mBAAmB,EAAE,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;oBAC7D,OAAO;gBACT,CAAC;gBACD,eAAe,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAGD,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IACrC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAGD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAGD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAG3C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAC;IAEpD,OAAO,CAAC,GAAG,CACT,iCAAiC,OAAO,QAAQ,cAAc,KAAK,CACpE,CAAC;IAGF,MAAM,SAAS,GAAG,GAAG,KAAK,IAAI,OAAO,IAAI,cAAc,MAAM,CAAC;IAC9D,MAAM,GAAG,GAAG,GAAG,mBAAmB,IAAI,KAAK,KAAK,OAAO,IAAI,SAAS,EAAE,CAAC;IAGvE,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAEhE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YAErB,QAAQ,CACN,gDAAgD,GAAG,eAAe,OAAO,IAAI,EAC7E,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;YAGF,MAAM,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAG9C,QAAQ,CACN,uBAAuB;gBACrB,yBAAyB,OAAO,uBAAuB,MAAM,YAAY;gBACzE,sBAAsB,OAAO,WAAW,EAC1C,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;QACJ,CAAC;aAAM,CAAC;YAEN,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAGvE,MAAM,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAG9C,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE;gBAC1D,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAGH,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/C,UAAU,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;YAGxC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAG7B,IAAI,CAAC;gBACH,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;YAET,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,uCAAuC,UAAU,EAAE,CAAC,CAAC;QAGjE,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CACT,eAAe,MAAM,8CAA8C,CACpE,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,SAAS,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACzF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { execFileSync, execSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n chmodSync,\n createReadStream,\n existsSync,\n mkdirSync,\n renameSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n installViaBrew,\n isBrewAvailable,\n isInstalledViaBrew,\n} from \"../utils/brewOperations.js\";\nimport { GH_CLI_DOWNLOAD_URL, PNAME } from \"../utils/consts.js\";\nimport {\n getBinDir,\n getLocalBinPath,\n invalidateBinPathCache,\n} from \"../utils/getLocalBinPath.js\";\nimport { getPlatformInfo, getTargetPlatform } from \"../utils/getUserOs.js\";\nimport {\n getAssetDigest,\n getCliVersion,\n hasUserSpecifiedVersion,\n} from \"../utils/ghOperations.js\";\nimport {\n installViaChoco,\n installViaWinget,\n isChocoAvailable,\n isInstalledViaChoco,\n isInstalledViaWinget,\n isWingetAvailable,\n} from \"../utils/windowsPackageManagers.js\";\n\n/**\n * Compute the SHA256 hex digest of a file.\n */\nconst sha256File = (filePath: string): Promise<string> => {\n return new Promise((resolve, reject) => {\n const hash = createHash(\"sha256\");\n const stream = createReadStream(filePath);\n stream.on(\"data\", (chunk) => hash.update(chunk));\n stream.on(\"end\", () => resolve(hash.digest(\"hex\")));\n stream.on(\"error\", reject);\n });\n};\n\n/**\n * Verify a downloaded file against its expected SHA256 digest.\n * Warns on mismatch or if digest is unavailable; throws on mismatch.\n */\nconst verifyChecksum = async (\n filePath: string,\n expectedDigest: string | null,\n): Promise<void> => {\n if (!expectedDigest) {\n console.log(\n \"Checksum not available from GitHub API, skipping verification\",\n );\n return;\n }\n\n const actual = await sha256File(filePath);\n if (actual !== expectedDigest) {\n throw new Error(\n `Checksum verification failed!\\n` +\n ` Expected: ${expectedDigest}\\n` +\n ` Actual: ${actual}\\n` +\n `The downloaded file may be corrupted or tampered with.`,\n );\n }\n console.log(\"Checksum verified\");\n};\n\n/**\n * Install the Aptos CLI.\n *\n * Installation priority:\n *\n * macOS:\n * 1. Homebrew (if available)\n * 2. Direct download from GitHub releases\n *\n * Windows:\n * 1. winget (if available)\n * 2. Chocolatey (if available)\n * 3. Direct download from GitHub releases\n *\n * Linux:\n * - Direct download from GitHub releases\n *\n * Note: When APTOS_CLI_VERSION is set, package managers are skipped and the\n * specified version is downloaded directly from GitHub releases.\n *\n * @param directDownload - If true, skip package managers and download directly\n */\nexport const installCli = async (\n directDownload: boolean = false,\n): Promise<void> => {\n invalidateBinPathCache();\n const { os } = getPlatformInfo();\n\n // If a specific version is requested, force direct download\n // Package managers don't support installing specific versions\n const useDirectDownload = directDownload || hasUserSpecifiedVersion();\n\n if (useDirectDownload && hasUserSpecifiedVersion()) {\n console.log(\n `Using specified version from APTOS_CLI_VERSION: ${process.env.APTOS_CLI_VERSION}`,\n );\n }\n\n // Skip package managers if directDownload is set or specific version requested\n if (!useDirectDownload) {\n // On macOS, prefer Homebrew if available\n if (os === \"macos\" && isBrewAvailable()) {\n if (isInstalledViaBrew()) {\n console.log(\"Aptos CLI is already installed via Homebrew\");\n return;\n }\n installViaBrew();\n return;\n }\n\n // On Windows, prefer winget, then Chocolatey\n if (os === \"windows\") {\n if (isWingetAvailable()) {\n if (isInstalledViaWinget()) {\n console.log(\"Aptos CLI is already installed via winget\");\n return;\n }\n installViaWinget();\n return;\n }\n\n if (isChocoAvailable()) {\n if (isInstalledViaChoco()) {\n console.log(\"Aptos CLI is already installed via Chocolatey\");\n return;\n }\n installViaChoco();\n return;\n }\n }\n }\n\n // Direct download installation\n const binaryPath = getLocalBinPath();\n if (existsSync(binaryPath)) {\n console.log(\"Aptos CLI is already installed\");\n return;\n }\n\n // Ensure the bin directory exists\n const binDir = getBinDir();\n if (!existsSync(binDir)) {\n mkdirSync(binDir, { recursive: true });\n }\n\n // Get target platform first for version validation\n const targetPlatform = getTargetPlatform();\n\n // Get the version to install (user-specified or latest)\n const version = await getCliVersion(targetPlatform);\n\n console.log(\n `Downloading Aptos CLI version ${version} for ${targetPlatform}...`,\n );\n\n // Build download URL matching official release artifact naming\n const assetName = `${PNAME}-${version}-${targetPlatform}.zip`;\n const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${assetName}`;\n\n // Fetch expected checksum from GitHub API (non-blocking)\n const expectedDigest = await getAssetDigest(version, assetName);\n\n const tempDir = tmpdir();\n const zipPath = join(tempDir, \"aptos-cli.zip\");\n\n try {\n if (os === \"windows\") {\n // Download\n execSync(\n `powershell -Command \"Invoke-WebRequest -Uri '${url}' -OutFile '${zipPath}'\"`,\n { stdio: \"inherit\" },\n );\n\n // Verify checksum before extraction\n await verifyChecksum(zipPath, expectedDigest);\n\n // Extract and clean up\n execSync(\n `powershell -Command \"` +\n `Expand-Archive -Path '${zipPath}' -DestinationPath '${binDir}' -Force; ` +\n `Remove-Item -Path '${zipPath}' -Force\"`,\n { stdio: \"inherit\" },\n );\n } else {\n // Download (argument array avoids shell injection)\n execFileSync(\"curl\", [\"-L\", \"-o\", zipPath, url], { stdio: \"inherit\" });\n\n // Verify checksum before extraction\n await verifyChecksum(zipPath, expectedDigest);\n\n // Extract\n execFileSync(\"unzip\", [\"-o\", \"-q\", zipPath, \"-d\", tempDir], {\n stdio: \"inherit\",\n });\n\n // Move binary to bin directory\n const extractedBinary = join(tempDir, \"aptos\");\n renameSync(extractedBinary, binaryPath);\n\n // Set executable permissions\n chmodSync(binaryPath, 0o755);\n\n // Clean up\n try {\n execFileSync(\"rm\", [\"-f\", zipPath], { stdio: \"ignore\" });\n } catch {\n // Ignore cleanup errors\n }\n }\n\n console.log(`Aptos CLI installed successfully to ${binaryPath}`);\n\n // Remind user about PATH if needed\n if (os !== \"windows\") {\n console.log(\n `\\nMake sure ${binDir} is in your PATH. You can add it by running:`,\n );\n console.log(` export PATH=\"${binDir}:$PATH\"`);\n }\n } catch (error) {\n throw new Error(\n `Failed to install Aptos CLI: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n"]}

@@ -41,3 +41,4 @@ import { existsSync, unlinkSync } from "node:fs";

})).trim();
currentVersion = versionOutput.split(" ")[1] || "";
const match = versionOutput.match(/(\d+\.\d+\.\d+)/);
currentVersion = match?.[1] ?? "";
}

@@ -44,0 +45,0 @@ catch {

@@ -1,1 +0,1 @@

{"version":3,"file":"update.js","sourceRoot":"","sources":["../../bin/tasks/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,eAAe,EACf,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAgB1C,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,iBAA0B,KAAK,EAChB,EAAE;IACjB,sBAAsB,EAAE,CAAC;IACzB,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;IAErC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CACT,+DAA+D,CAChE,CAAC;QACF,OAAO;IACT,CAAC;IAGD,MAAM,iBAAiB,GAAG,cAAc,IAAI,uBAAuB,EAAE,CAAC;IAEtE,IAAI,iBAAiB,IAAI,uBAAuB,EAAE,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,mDAAmD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CACnF,CAAC;IACJ,CAAC;IAGD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEvB,IAAI,kBAAkB,EAAE,EAAE,CAAC;YACzB,aAAa,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAGD,IAAI,oBAAoB,EAAE,EAAE,CAAC;YAC3B,eAAe,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAGD,IAAI,mBAAmB,EAAE,EAAE,CAAC;YAC1B,cAAc,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;IACH,CAAC;IAGD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAG3C,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,CAAC;IAG1D,IAAI,cAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,CAC1B,aAAa,CAAC,IAAI,UAAU,aAAa,EAAE;YACzC,QAAQ,EAAE,MAAM;SACjB,CAAC,CACH,CAAC,IAAI,EAAE,CAAC;QAET,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,cAAc,GAAG,EAAE,CAAC;IACtB,CAAC;IAGD,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;QACrC,IAAI,uBAAuB,EAAE,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CACT,4CAA4C,cAAc,GAAG,CAC9D,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,8BAA8B,cAAc,GAAG,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,iBAAiB,GAAG,uBAAuB,EAAE;QACjD,CAAC,CAAC,8BAA8B,cAAc,IAAI,SAAS,OAAO,aAAa,KAAK;QACpF,CAAC,CAAC,6BAA6B,cAAc,IAAI,SAAS,OAAO,aAAa,KAAK,CAAC;IAEtF,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAG/B,IAAI,CAAC;QACH,UAAU,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,2CAA2C,UAAU,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,UAAU,CAAC,iBAAiB,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { existsSync, unlinkSync } from \"node:fs\";\nimport { isInstalledViaBrew, updateViaBrew } from \"../utils/brewOperations.js\";\nimport { execSyncShell } from \"../utils/execSyncShell.js\";\nimport {\n getLocalBinPath,\n invalidateBinPathCache,\n} from \"../utils/getLocalBinPath.js\";\nimport { getTargetPlatform } from \"../utils/getUserOs.js\";\nimport {\n getCliVersion,\n hasUserSpecifiedVersion,\n} from \"../utils/ghOperations.js\";\nimport {\n isInstalledViaChoco,\n isInstalledViaWinget,\n updateViaChoco,\n updateViaWinget,\n} from \"../utils/windowsPackageManagers.js\";\nimport { installCli } from \"./install.js\";\n\n/**\n * Update the Aptos CLI to the latest version (or a specific version if APTOS_CLI_VERSION is set).\n *\n * Update methods by installation type:\n * - Homebrew: `brew upgrade aptos`\n * - winget: `winget upgrade`\n * - Chocolatey: `choco upgrade`\n * - Direct download: Compare versions and reinstall if newer/different\n *\n * Note: When APTOS_CLI_VERSION is set, package managers are skipped and the\n * specified version is downloaded directly from GitHub releases.\n *\n * @param directDownload - If true, skip package manager updates and force direct download\n */\nexport const updateCli = async (\n directDownload: boolean = false,\n): Promise<void> => {\n invalidateBinPathCache();\n const binaryPath = getLocalBinPath();\n\n if (!existsSync(binaryPath)) {\n console.log(\n \"Aptos CLI not installed, run `npx aptos --install` to install\",\n );\n return;\n }\n\n // If a specific version is requested, force direct download\n const useDirectDownload = directDownload || hasUserSpecifiedVersion();\n\n if (useDirectDownload && hasUserSpecifiedVersion()) {\n console.log(\n `Using specified version from APTOS_CLI_VERSION: ${process.env.APTOS_CLI_VERSION}`,\n );\n }\n\n // Check for package manager installations (unless directDownload is set or specific version requested)\n if (!useDirectDownload) {\n // If installed via Homebrew, use brew upgrade\n if (isInstalledViaBrew()) {\n updateViaBrew();\n return;\n }\n\n // If installed via winget, use winget upgrade\n if (isInstalledViaWinget()) {\n updateViaWinget();\n return;\n }\n\n // If installed via Chocolatey, use choco upgrade\n if (isInstalledViaChoco()) {\n updateViaChoco();\n return;\n }\n }\n\n // Get target platform for version validation\n const targetPlatform = getTargetPlatform();\n\n // Get the target version (user-specified or latest)\n const targetVersion = await getCliVersion(targetPlatform);\n\n // Get the current version of the CLI\n let currentVersion: string;\n try {\n const versionOutput = String(\n execSyncShell(`\"${binaryPath}\" --version`, {\n encoding: \"utf8\",\n }),\n ).trim();\n // Version output format: \"aptos X.Y.Z\"\n currentVersion = versionOutput.split(\" \")[1] || \"\";\n } catch {\n console.error(\"Warning: Could not determine current CLI version\");\n currentVersion = \"\";\n }\n\n // Check if the installed version matches the target version\n if (currentVersion === targetVersion) {\n if (hasUserSpecifiedVersion()) {\n console.log(\n `CLI is already at the specified version (${currentVersion})`,\n );\n } else {\n console.log(`CLI is up to date (version ${currentVersion})`);\n }\n return;\n }\n\n const updateDescription = hasUserSpecifiedVersion()\n ? `Switching CLI from version ${currentVersion || \"unknown\"} to ${targetVersion}...`\n : `Updating CLI from version ${currentVersion || \"unknown\"} to ${targetVersion}...`;\n\n console.log(updateDescription);\n\n // Remove the old binary before installing the new one\n try {\n unlinkSync(binaryPath);\n } catch {\n console.error(`Warning: Could not remove old binary at ${binaryPath}`);\n }\n\n await installCli(useDirectDownload);\n};\n"]}
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../bin/tasks/update.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, unlinkSync } from \"node:fs\";\nimport { isInstalledViaBrew, updateViaBrew } from \"../utils/brewOperations.js\";\nimport { execSyncShell } from \"../utils/execSyncShell.js\";\nimport {\n getLocalBinPath,\n invalidateBinPathCache,\n} from \"../utils/getLocalBinPath.js\";\nimport { getTargetPlatform } from \"../utils/getUserOs.js\";\nimport {\n getCliVersion,\n hasUserSpecifiedVersion,\n} from \"../utils/ghOperations.js\";\nimport {\n isInstalledViaChoco,\n isInstalledViaWinget,\n updateViaChoco,\n updateViaWinget,\n} from \"../utils/windowsPackageManagers.js\";\nimport { installCli } from \"./install.js\";\n\n/**\n * Update the Aptos CLI to the latest version (or a specific version if APTOS_CLI_VERSION is set).\n *\n * Update methods by installation type:\n * - Homebrew: `brew upgrade aptos`\n * - winget: `winget upgrade`\n * - Chocolatey: `choco upgrade`\n * - Direct download: Compare versions and reinstall if newer/different\n *\n * Note: When APTOS_CLI_VERSION is set, package managers are skipped and the\n * specified version is downloaded directly from GitHub releases.\n *\n * @param directDownload - If true, skip package manager updates and force direct download\n */\nexport const updateCli = async (\n directDownload: boolean = false,\n): Promise<void> => {\n invalidateBinPathCache();\n const binaryPath = getLocalBinPath();\n\n if (!existsSync(binaryPath)) {\n console.log(\n \"Aptos CLI not installed, run `npx aptos --install` to install\",\n );\n return;\n }\n\n // If a specific version is requested, force direct download\n const useDirectDownload = directDownload || hasUserSpecifiedVersion();\n\n if (useDirectDownload && hasUserSpecifiedVersion()) {\n console.log(\n `Using specified version from APTOS_CLI_VERSION: ${process.env.APTOS_CLI_VERSION}`,\n );\n }\n\n // Check for package manager installations (unless directDownload is set or specific version requested)\n if (!useDirectDownload) {\n // If installed via Homebrew, use brew upgrade\n if (isInstalledViaBrew()) {\n updateViaBrew();\n return;\n }\n\n // If installed via winget, use winget upgrade\n if (isInstalledViaWinget()) {\n updateViaWinget();\n return;\n }\n\n // If installed via Chocolatey, use choco upgrade\n if (isInstalledViaChoco()) {\n updateViaChoco();\n return;\n }\n }\n\n // Get target platform for version validation\n const targetPlatform = getTargetPlatform();\n\n // Get the target version (user-specified or latest)\n const targetVersion = await getCliVersion(targetPlatform);\n\n // Get the current version of the CLI\n let currentVersion: string;\n try {\n const versionOutput = String(\n execSyncShell(`\"${binaryPath}\" --version`, {\n encoding: \"utf8\",\n }),\n ).trim();\n // Extract semver from output (e.g. \"aptos 4.5.0\" or \"aptos-cli 4.5.0\")\n const match = versionOutput.match(/(\\d+\\.\\d+\\.\\d+)/);\n currentVersion = match?.[1] ?? \"\";\n } catch {\n console.error(\"Warning: Could not determine current CLI version\");\n currentVersion = \"\";\n }\n\n // Check if the installed version matches the target version\n if (currentVersion === targetVersion) {\n if (hasUserSpecifiedVersion()) {\n console.log(\n `CLI is already at the specified version (${currentVersion})`,\n );\n } else {\n console.log(`CLI is up to date (version ${currentVersion})`);\n }\n return;\n }\n\n const updateDescription = hasUserSpecifiedVersion()\n ? `Switching CLI from version ${currentVersion || \"unknown\"} to ${targetVersion}...`\n : `Updating CLI from version ${currentVersion || \"unknown\"} to ${targetVersion}...`;\n\n console.log(updateDescription);\n\n // Remove the old binary before installing the new one\n try {\n unlinkSync(binaryPath);\n } catch {\n console.error(`Warning: Could not remove old binary at ${binaryPath}`);\n }\n\n await installCli(useDirectDownload);\n};\n"]}
import { execSync } from "node:child_process";
export const execSyncShell = (command, options) => {
const execOptions = {
...options,
shell: true,
};
return execSync(command, execOptions);
const shell = process.platform === "win32" ? "cmd.exe" : "/bin/sh";
return execSync(command, { ...options, shell });
};
//# sourceMappingURL=execSyncShell.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"execSyncShell.js","sourceRoot":"","sources":["../../bin/utils/execSyncShell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQpE,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAe,EACf,OAA8B,EACb,EAAE;IAGnB,MAAM,WAAW,GAAG;QAClB,GAAG,OAAO;QACV,KAAK,EAAE,IAAI;KACkB,CAAC;IAChC,OAAO,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import { type ExecSyncOptions, execSync } from \"node:child_process\";\n\ntype ExecSyncShellOptions = Omit<ExecSyncOptions, \"shell\">;\n\n/**\n * Wrapper around execSync that uses the shell.\n * This always executes with shell: true for cross-platform compatibility.\n */\nexport const execSyncShell = (\n command: string,\n options?: ExecSyncShellOptions,\n): Buffer | string => {\n // Type assertion needed due to @types/node ExecSyncOptions overload complexity\n // where shell is typed as string | boolean but overloads expect specific types\n const execOptions = {\n ...options,\n shell: true,\n } as unknown as ExecSyncOptions;\n return execSync(command, execOptions);\n};\n"]}
{"version":3,"file":"execSyncShell.js","sourceRoot":"","sources":["../../bin/utils/execSyncShell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQpE,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,OAAe,EACf,OAA8B,EACb,EAAE;IAGnB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC","sourcesContent":["import { type ExecSyncOptions, execSync } from \"node:child_process\";\n\ntype ExecSyncShellOptions = Omit<ExecSyncOptions, \"shell\">;\n\n/**\n * Wrapper around execSync that uses the shell.\n * This always executes with shell: true for cross-platform compatibility.\n */\nexport const execSyncShell = (\n command: string,\n options?: ExecSyncShellOptions,\n): Buffer | string => {\n // @types/node overloads type `shell` as only `string`, but Node.js\n // accepts `boolean` at runtime. Use the platform default shell path.\n const shell = process.platform === \"win32\" ? \"cmd.exe\" : \"/bin/sh\";\n return execSync(command, { ...options, shell });\n};\n"]}

@@ -5,6 +5,6 @@ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";

import { getCliPathBrew, isInstalledViaBrew } from "./brewOperations.js";
import { getOS } from "./getUserOs.js";
import { getPlatformInfo } from "./getUserOs.js";
import { getCliPathChoco, getCliPathWinget, isInstalledViaChoco, isInstalledViaWinget, } from "./windowsPackageManagers.js";
const getCachePath = () => {
if (getOS() === "Windows") {
if (getPlatformInfo().os === "windows") {
return join(homedir(), ".aptoscli", ".bin-path-cache");

@@ -42,4 +42,4 @@ }

export const getBinDir = () => {
const os = getOS();
if (os === "Windows") {
const { os } = getPlatformInfo();
if (os === "windows") {
return join(homedir(), ".aptoscli", "bin");

@@ -54,4 +54,4 @@ }

}
const os = getOS();
if (os === "MacOS") {
const { os } = getPlatformInfo();
if (os === "macos") {
if (isInstalledViaBrew()) {

@@ -67,3 +67,3 @@ try {

}
if (os === "Windows") {
if (os === "windows") {
if (isInstalledViaWinget()) {

@@ -85,3 +85,3 @@ const wingetPath = getCliPathWinget();

const binDir = getBinDir();
const binaryName = os === "Windows" ? "aptos.exe" : "aptos";
const binaryName = os === "windows" ? "aptos.exe" : "aptos";
const defaultPath = join(binDir, binaryName);

@@ -88,0 +88,0 @@ writeCachedBinPath(defaultPath);

@@ -1,1 +0,1 @@

{"version":3,"file":"getLocalBinPath.js","sourceRoot":"","sources":["../../bin/utils/getLocalBinPath.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { getCliPathBrew, isInstalledViaBrew } from \"./brewOperations.js\";\nimport { getOS } from \"./getUserOs.js\";\nimport {\n getCliPathChoco,\n getCliPathWinget,\n isInstalledViaChoco,\n isInstalledViaWinget,\n} from \"./windowsPackageManagers.js\";\n\n/**\n * Path to the cached binary location file.\n * Avoids expensive shell spawns (brew --prefix, winget list) on every run.\n */\nconst getCachePath = (): string => {\n if (getOS() === \"Windows\") {\n return join(homedir(), \".aptoscli\", \".bin-path-cache\");\n }\n return join(homedir(), \".local\", \"share\", \"aptos-cli\", \".bin-path-cache\");\n};\n\nconst readCachedBinPath = (): string | undefined => {\n try {\n const cached = readFileSync(getCachePath(), \"utf8\").trim();\n if (cached && existsSync(cached)) {\n return cached;\n }\n } catch {\n // No cache or unreadable\n }\n return undefined;\n};\n\nconst writeCachedBinPath = (binPath: string): void => {\n try {\n const cachePath = getCachePath();\n mkdirSync(dirname(cachePath), { recursive: true });\n writeFileSync(cachePath, binPath, \"utf8\");\n } catch {\n // Non-fatal — caching is best-effort\n }\n};\n\n/**\n * Invalidate the cached binary path.\n * Call this when install or update changes the binary location.\n */\nexport const invalidateBinPathCache = (): void => {\n try {\n unlinkSync(getCachePath());\n } catch {\n // No cache to invalidate\n }\n};\n\n/**\n * Get the binary directory path where the CLI should be installed.\n * Matches the official Aptos CLI install scripts:\n * - macOS/Linux: ~/.local/bin\n * - Windows: $USERPROFILE\\.aptoscli\\bin\n */\nexport const getBinDir = (): string => {\n const os = getOS();\n\n if (os === \"Windows\") {\n // Match official Windows script: $env:USERPROFILE\\.aptoscli\\bin\n return join(homedir(), \".aptoscli\", \"bin\");\n }\n\n // Match official Unix script: $HOME/.local/bin\n return join(homedir(), \".local\", \"bin\");\n};\n\n/**\n * Get the full path to the Aptos CLI binary.\n *\n * Uses a file-based cache to avoid expensive shell spawns (brew --prefix,\n * winget list) on every invocation. The cache is invalidated by install\n * and update tasks.\n *\n * Checks for package manager installations first:\n * - macOS: Homebrew\n * - Windows: winget, then Chocolatey\n *\n * Otherwise uses the standard paths:\n * - macOS/Linux: ~/.local/bin/aptos\n * - Windows: $USERPROFILE\\.aptoscli\\bin\\aptos.exe\n */\nexport const getLocalBinPath = (): string => {\n // Fast path: return cached binary location if still valid\n const cached = readCachedBinPath();\n if (cached) {\n return cached;\n }\n\n const os = getOS();\n\n // On macOS, prefer Homebrew installation if it exists\n if (os === \"MacOS\") {\n if (isInstalledViaBrew()) {\n try {\n const brewPath = getCliPathBrew();\n writeCachedBinPath(brewPath);\n return brewPath;\n } catch {\n // Fall through to default path\n }\n }\n }\n\n // On Windows, check for winget or Chocolatey installations\n if (os === \"Windows\") {\n if (isInstalledViaWinget()) {\n const wingetPath = getCliPathWinget();\n if (wingetPath) {\n writeCachedBinPath(wingetPath);\n return wingetPath;\n }\n }\n\n if (isInstalledViaChoco()) {\n const chocoPath = getCliPathChoco();\n if (chocoPath) {\n writeCachedBinPath(chocoPath);\n return chocoPath;\n }\n }\n }\n\n const binDir = getBinDir();\n const binaryName = os === \"Windows\" ? \"aptos.exe\" : \"aptos\";\n const defaultPath = join(binDir, binaryName);\n writeCachedBinPath(defaultPath);\n return defaultPath;\n};\n"]}
{"version":3,"file":"getLocalBinPath.js","sourceRoot":"","sources":["../../bin/utils/getLocalBinPath.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { getCliPathBrew, isInstalledViaBrew } from \"./brewOperations.js\";\nimport { getPlatformInfo } from \"./getUserOs.js\";\nimport {\n getCliPathChoco,\n getCliPathWinget,\n isInstalledViaChoco,\n isInstalledViaWinget,\n} from \"./windowsPackageManagers.js\";\n\n/**\n * Path to the cached binary location file.\n * Avoids expensive shell spawns (brew --prefix, winget list) on every run.\n */\nconst getCachePath = (): string => {\n if (getPlatformInfo().os === \"windows\") {\n return join(homedir(), \".aptoscli\", \".bin-path-cache\");\n }\n return join(homedir(), \".local\", \"share\", \"aptos-cli\", \".bin-path-cache\");\n};\n\nconst readCachedBinPath = (): string | undefined => {\n try {\n const cached = readFileSync(getCachePath(), \"utf8\").trim();\n if (cached && existsSync(cached)) {\n return cached;\n }\n } catch {\n // No cache or unreadable\n }\n return undefined;\n};\n\nconst writeCachedBinPath = (binPath: string): void => {\n try {\n const cachePath = getCachePath();\n mkdirSync(dirname(cachePath), { recursive: true });\n writeFileSync(cachePath, binPath, \"utf8\");\n } catch {\n // Non-fatal — caching is best-effort\n }\n};\n\n/**\n * Invalidate the cached binary path.\n * Call this when install or update changes the binary location.\n */\nexport const invalidateBinPathCache = (): void => {\n try {\n unlinkSync(getCachePath());\n } catch {\n // No cache to invalidate\n }\n};\n\n/**\n * Get the binary directory path where the CLI should be installed.\n * Matches the official Aptos CLI install scripts:\n * - macOS/Linux: ~/.local/bin\n * - Windows: $USERPROFILE\\.aptoscli\\bin\n */\nexport const getBinDir = (): string => {\n const { os } = getPlatformInfo();\n\n if (os === \"windows\") {\n // Match official Windows script: $env:USERPROFILE\\.aptoscli\\bin\n return join(homedir(), \".aptoscli\", \"bin\");\n }\n\n // Match official Unix script: $HOME/.local/bin\n return join(homedir(), \".local\", \"bin\");\n};\n\n/**\n * Get the full path to the Aptos CLI binary.\n *\n * Uses a file-based cache to avoid expensive shell spawns (brew --prefix,\n * winget list) on every invocation. The cache is invalidated by install\n * and update tasks.\n *\n * Checks for package manager installations first:\n * - macOS: Homebrew\n * - Windows: winget, then Chocolatey\n *\n * Otherwise uses the standard paths:\n * - macOS/Linux: ~/.local/bin/aptos\n * - Windows: $USERPROFILE\\.aptoscli\\bin\\aptos.exe\n */\nexport const getLocalBinPath = (): string => {\n // Fast path: return cached binary location if still valid\n const cached = readCachedBinPath();\n if (cached) {\n return cached;\n }\n\n const { os } = getPlatformInfo();\n\n // On macOS, prefer Homebrew installation if it exists\n if (os === \"macos\") {\n if (isInstalledViaBrew()) {\n try {\n const brewPath = getCliPathBrew();\n writeCachedBinPath(brewPath);\n return brewPath;\n } catch {\n // Fall through to default path\n }\n }\n }\n\n // On Windows, check for winget or Chocolatey installations\n if (os === \"windows\") {\n if (isInstalledViaWinget()) {\n const wingetPath = getCliPathWinget();\n if (wingetPath) {\n writeCachedBinPath(wingetPath);\n return wingetPath;\n }\n }\n\n if (isInstalledViaChoco()) {\n const chocoPath = getCliPathChoco();\n if (chocoPath) {\n writeCachedBinPath(chocoPath);\n return chocoPath;\n }\n }\n }\n\n const binDir = getBinDir();\n const binaryName = os === \"windows\" ? \"aptos.exe\" : \"aptos\";\n const defaultPath = join(binDir, binaryName);\n writeCachedBinPath(defaultPath);\n return defaultPath;\n};\n"]}

@@ -82,5 +82,2 @@ import { existsSync, readFileSync } from "node:fs";

case "windows":
if (architecture === "aarch64") {
throw new Error("Windows ARM64 is not currently supported. Please use x86_64 emulation or build from source.");
}
return "Windows-x86_64";

@@ -91,13 +88,2 @@ default:

};
export const getOS = () => {
const { os } = getPlatformInfo();
switch (os) {
case "macos":
return "MacOS";
case "linux":
return "Linux";
case "windows":
return "Windows";
}
};
//# sourceMappingURL=getUserOs.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"getUserOs.js","sourceRoot":"","sources":["../../bin/utils/getUserOs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA4BzC,MAAM,CAAC,MAAM,eAAe,GAAG,GAAiB,EAAE;IAChD,MAAM,UAAU,GAAG,QAAQ,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;IAEtB,IAAI,EAAe,CAAC;IACpB,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,EAAE,GAAG,OAAO,CAAC;YACb,MAAM;QACR,KAAK,OAAO;YACV,EAAE,GAAG,OAAO,CAAC;YACb,MAAM;QACR,KAAK,OAAO;YACV,EAAE,GAAG,SAAS,CAAC;YACf,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,YAA2B,CAAC;IAChC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK,CAAC;QACX,KAAK,QAAQ;YACX,YAAY,GAAG,QAAQ,CAAC;YACxB,MAAM;QACR,KAAK,OAAO,CAAC;QACb,KAAK,SAAS;YACZ,YAAY,GAAG,SAAS,CAAC;YACzB,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AACpC,CAAC,CAAC;AAMF,MAAM,kBAAkB,GAAG,GAA6C,EAAE;IACxE,MAAM,aAAa,GAAG,iBAAiB,CAAC;IACxC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,IAAI,SAAS,GAAG,EAAE,CAAC;QAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAE/D,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACjB,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;iBAAM,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBAChC,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAmB,EAAE;IACpD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,eAAe,EAAE,CAAC;IAErD,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,OAAO;YAEV,OAAO,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC;QAErE,KAAK,OAAO,CAAC,CAAC,CAAC;YAEb,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,eAAe,CAAC;YACzB,CAAC;YAGD,MAAM,UAAU,GAAG,kBAAkB,EAAE,CAAC;YACxC,IAAI,UAAU,EAAE,EAAE,KAAK,QAAQ,EAAE,CAAC;gBAChC,IAAI,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7C,OAAO,qBAAqB,CAAC;gBAC/B,CAAC;gBACD,IAAI,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7C,OAAO,qBAAqB,CAAC;gBAC/B,CAAC;YACH,CAAC;YAGD,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,KAAK,SAAS;YAEZ,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;YACJ,CAAC;YACD,OAAO,gBAAgB,CAAC;QAE1B;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,KAAK,GAAG,GAAkC,EAAE;IACvD,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,EAAE,CAAC;IACjC,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { arch, platform } from \"node:os\";\n\nexport type SupportedOS = \"macos\" | \"linux\" | \"windows\";\nexport type SupportedArch = \"x86_64\" | \"aarch64\";\n\nexport interface PlatformInfo {\n os: SupportedOS;\n arch: SupportedArch;\n}\n\n/**\n * Target strings that match the official Aptos CLI release artifacts.\n * These are derived from the official install scripts at:\n * - https://aptos.dev/scripts/install_cli.sh\n * - https://aptos.dev/scripts/install_cli.ps1\n */\nexport type TargetPlatform =\n | \"macos-x86_64\"\n | \"macos-arm64\"\n | \"Ubuntu-22.04-x86_64\"\n | \"Ubuntu-24.04-x86_64\"\n | \"Linux-x86_64\"\n | \"Linux-aarch64\"\n | \"Windows-x86_64\";\n\n/**\n * Get basic OS and architecture information.\n */\nexport const getPlatformInfo = (): PlatformInfo => {\n const osPlatform = platform();\n const osArch = arch();\n\n let os: SupportedOS;\n switch (osPlatform) {\n case \"darwin\":\n os = \"macos\";\n break;\n case \"linux\":\n os = \"linux\";\n break;\n case \"win32\":\n os = \"windows\";\n break;\n default:\n throw new Error(`Unsupported operating system: ${osPlatform}`);\n }\n\n let architecture: SupportedArch;\n switch (osArch) {\n case \"x64\":\n case \"x86_64\":\n architecture = \"x86_64\";\n break;\n case \"arm64\":\n case \"aarch64\":\n architecture = \"aarch64\";\n break;\n default:\n throw new Error(`Unsupported architecture: ${osArch}`);\n }\n\n return { os, arch: architecture };\n};\n\n/**\n * Parse /etc/os-release file to get distribution info.\n * Returns null if file doesn't exist or can't be parsed.\n */\nconst getLinuxDistroInfo = (): { id: string; versionId: string } | null => {\n const osReleasePath = \"/etc/os-release\";\n if (!existsSync(osReleasePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(osReleasePath, \"utf8\");\n const lines = content.split(\"\\n\");\n\n let id = \"\";\n let versionId = \"\";\n\n for (const line of lines) {\n const [key, ...valueParts] = line.split(\"=\");\n const value = valueParts.join(\"=\").replace(/^[\"']|[\"']$/g, \"\");\n\n if (key === \"ID\") {\n id = value.toLowerCase();\n } else if (key === \"VERSION_ID\") {\n versionId = value;\n }\n }\n\n return { id, versionId };\n } catch {\n return null;\n }\n};\n\n/**\n * Determine the target platform string for downloading the CLI binary.\n * This matches the naming convention used in official Aptos CLI releases.\n */\nexport const getTargetPlatform = (): TargetPlatform => {\n const { os, arch: architecture } = getPlatformInfo();\n\n switch (os) {\n case \"macos\":\n // macOS supports both x86_64 and arm64\n return architecture === \"aarch64\" ? \"macos-arm64\" : \"macos-x86_64\";\n\n case \"linux\": {\n // Check for ARM64 first\n if (architecture === \"aarch64\") {\n return \"Linux-aarch64\";\n }\n\n // For x86_64, check if we're on Ubuntu and what version\n const distroInfo = getLinuxDistroInfo();\n if (distroInfo?.id === \"ubuntu\") {\n if (distroInfo.versionId.startsWith(\"24.04\")) {\n return \"Ubuntu-24.04-x86_64\";\n }\n if (distroInfo.versionId.startsWith(\"22.04\")) {\n return \"Ubuntu-22.04-x86_64\";\n }\n }\n\n // Default to generic Linux for non-Ubuntu or older Ubuntu versions\n return \"Linux-x86_64\";\n }\n\n case \"windows\":\n // Windows only supports x86_64 currently\n if (architecture === \"aarch64\") {\n throw new Error(\n \"Windows ARM64 is not currently supported. Please use x86_64 emulation or build from source.\",\n );\n }\n return \"Windows-x86_64\";\n\n default:\n throw new Error(`Unsupported OS: ${os}`);\n }\n};\n\n/**\n * Get simple OS identifier for branching logic.\n * @deprecated Use getPlatformInfo() or getTargetPlatform() instead for more precise platform detection.\n */\nexport const getOS = (): \"MacOS\" | \"Linux\" | \"Windows\" => {\n const { os } = getPlatformInfo();\n switch (os) {\n case \"macos\":\n return \"MacOS\";\n case \"linux\":\n return \"Linux\";\n case \"windows\":\n return \"Windows\";\n }\n};\n"]}
{"version":3,"file":"getUserOs.js","sourceRoot":"","sources":["../../bin/utils/getUserOs.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { arch, platform } from \"node:os\";\n\nexport type SupportedOS = \"macos\" | \"linux\" | \"windows\";\nexport type SupportedArch = \"x86_64\" | \"aarch64\";\n\nexport interface PlatformInfo {\n os: SupportedOS;\n arch: SupportedArch;\n}\n\n/**\n * Target strings that match the official Aptos CLI release artifacts.\n * These are derived from the official install scripts at:\n * - https://aptos.dev/scripts/install_cli.sh\n * - https://aptos.dev/scripts/install_cli.ps1\n */\nexport type TargetPlatform =\n | \"macos-x86_64\"\n | \"macos-arm64\"\n | \"Ubuntu-22.04-x86_64\"\n | \"Ubuntu-24.04-x86_64\"\n | \"Linux-x86_64\"\n | \"Linux-aarch64\"\n | \"Windows-x86_64\";\n\n/**\n * Get basic OS and architecture information.\n */\nexport const getPlatformInfo = (): PlatformInfo => {\n const osPlatform = platform();\n const osArch = arch();\n\n let os: SupportedOS;\n switch (osPlatform) {\n case \"darwin\":\n os = \"macos\";\n break;\n case \"linux\":\n os = \"linux\";\n break;\n case \"win32\":\n os = \"windows\";\n break;\n default:\n throw new Error(`Unsupported operating system: ${osPlatform}`);\n }\n\n let architecture: SupportedArch;\n switch (osArch) {\n case \"x64\":\n case \"x86_64\":\n architecture = \"x86_64\";\n break;\n case \"arm64\":\n case \"aarch64\":\n architecture = \"aarch64\";\n break;\n default:\n throw new Error(`Unsupported architecture: ${osArch}`);\n }\n\n return { os, arch: architecture };\n};\n\n/**\n * Parse /etc/os-release file to get distribution info.\n * Returns null if file doesn't exist or can't be parsed.\n */\nconst getLinuxDistroInfo = (): { id: string; versionId: string } | null => {\n const osReleasePath = \"/etc/os-release\";\n if (!existsSync(osReleasePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(osReleasePath, \"utf8\");\n const lines = content.split(\"\\n\");\n\n let id = \"\";\n let versionId = \"\";\n\n for (const line of lines) {\n const [key, ...valueParts] = line.split(\"=\");\n const value = valueParts.join(\"=\").replace(/^[\"']|[\"']$/g, \"\");\n\n if (key === \"ID\") {\n id = value.toLowerCase();\n } else if (key === \"VERSION_ID\") {\n versionId = value;\n }\n }\n\n return { id, versionId };\n } catch {\n return null;\n }\n};\n\n/**\n * Determine the target platform string for downloading the CLI binary.\n * This matches the naming convention used in official Aptos CLI releases.\n */\nexport const getTargetPlatform = (): TargetPlatform => {\n const { os, arch: architecture } = getPlatformInfo();\n\n switch (os) {\n case \"macos\":\n // macOS supports both x86_64 and arm64\n return architecture === \"aarch64\" ? \"macos-arm64\" : \"macos-x86_64\";\n\n case \"linux\": {\n // Check for ARM64 first\n if (architecture === \"aarch64\") {\n return \"Linux-aarch64\";\n }\n\n // For x86_64, check if we're on Ubuntu and what version\n const distroInfo = getLinuxDistroInfo();\n if (distroInfo?.id === \"ubuntu\") {\n if (distroInfo.versionId.startsWith(\"24.04\")) {\n return \"Ubuntu-24.04-x86_64\";\n }\n if (distroInfo.versionId.startsWith(\"22.04\")) {\n return \"Ubuntu-22.04-x86_64\";\n }\n }\n\n // Default to generic Linux for non-Ubuntu or older Ubuntu versions\n return \"Linux-x86_64\";\n }\n\n case \"windows\":\n // Windows ARM64 uses x86_64 binary via built-in emulation\n return \"Windows-x86_64\";\n\n default:\n throw new Error(`Unsupported OS: ${os}`);\n }\n};\n"]}

@@ -87,2 +87,25 @@ import { GH_CLI_DOWNLOAD_URL, PNAME } from "./consts.js";

};
export const getAssetDigest = async (version, assetName) => {
const tag = `${PNAME}-v${version}`;
const url = `https://api.github.com/repos/aptos-labs/aptos-core/releases/tags/${tag}`;
try {
const response = await fetch(url, { headers: getGitHubHeaders() });
if (!response.ok) {
return null;
}
const release = await response.json();
const asset = release.assets?.find((a) => a.name === assetName);
if (!asset?.digest) {
return null;
}
const digest = asset.digest;
if (digest.startsWith("sha256:")) {
return digest.slice(7);
}
return null;
}
catch {
return null;
}
};
//# sourceMappingURL=ghOperations.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"ghOperations.js","sourceRoot":"","sources":["../../bin/utils/ghOperations.ts"],"names":[],"mappings":"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","sourcesContent":["import { GH_CLI_DOWNLOAD_URL, PNAME } from \"./consts.js\";\n\ninterface GitHubRelease {\n tag_name: string;\n [key: string]: unknown;\n}\n\n/**\n * Build headers for GitHub API requests.\n * Uses GITHUB_TOKEN environment variable if available for authenticated requests.\n */\nconst getGitHubHeaders = (): Record<string, string> => {\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github.v3+json\",\n \"User-Agent\": \"aptos-cli-npm\",\n };\n\n // Use GITHUB_TOKEN if available for higher rate limits\n const token = process.env.GITHUB_TOKEN;\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n return headers;\n};\n\n/**\n * Get the user-specified CLI version from environment variable.\n * Returns undefined if not set.\n */\nexport const getUserSpecifiedVersion = (): string | undefined => {\n const version = process.env.APTOS_CLI_VERSION;\n if (!version) {\n return undefined;\n }\n // Strip 'v' prefix if present (e.g., \"v1.2.3\" -> \"1.2.3\")\n const stripped = version.replace(/^v/, \"\");\n if (!/^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?$/.test(stripped)) {\n throw new Error(\n `Invalid APTOS_CLI_VERSION: \"${version}\". Must match MAJOR.MINOR.PATCH (e.g. \"4.5.0\" or \"v4.5.0\").`,\n );\n }\n return stripped;\n};\n\n/**\n * Check if a user has specified a CLI version via environment variable.\n */\nexport const hasUserSpecifiedVersion = (): boolean => {\n return !!process.env.APTOS_CLI_VERSION;\n};\n\n/**\n * Validate that a specific version exists by checking if the release assets are accessible.\n * Uses a HEAD request to avoid downloading the actual file.\n *\n * @param version - The version to validate (without 'v' prefix)\n * @param targetPlatform - The target platform string (e.g., \"Ubuntu-22.04-x86_64\")\n */\nexport const validateVersionExists = async (\n version: string,\n targetPlatform: string,\n): Promise<boolean> => {\n const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${PNAME}-${version}-${targetPlatform}.zip`;\n\n try {\n const response = await fetch(url, {\n method: \"HEAD\",\n headers: getGitHubHeaders(),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n\n/**\n * Get the CLI version to use.\n * If APTOS_CLI_VERSION is set, returns that version (after validation).\n * Otherwise, returns the latest version from GitHub.\n *\n * @param targetPlatform - Optional target platform for version validation\n */\nexport const getCliVersion = async (\n targetPlatform?: string,\n): Promise<string> => {\n const userVersion = getUserSpecifiedVersion();\n\n if (userVersion) {\n // If a target platform is provided, validate the version exists\n if (targetPlatform) {\n const exists = await validateVersionExists(userVersion, targetPlatform);\n if (!exists) {\n throw new Error(\n `Specified version ${userVersion} does not exist or is not available for ${targetPlatform}. ` +\n `Check https://github.com/aptos-labs/aptos-core/releases for available versions.`,\n );\n }\n }\n return userVersion;\n }\n\n return getLatestVersionGh();\n};\n\n/**\n * Query the GitHub API to find the latest CLI release. We assume that the CLI is in\n * the last 100 releases so we don't paginate through the releases.\n *\n * Set GITHUB_TOKEN environment variable for higher rate limits.\n */\nexport const getLatestVersionGh = async (): Promise<string> => {\n const prefix = `${PNAME}-v`;\n const url =\n \"https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100\";\n\n let response: Response;\n try {\n response = await fetch(url, { headers: getGitHubHeaders() });\n } catch (error) {\n throw new Error(\n `Failed to fetch releases from GitHub: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (!response.ok) {\n if (response.status === 403 || response.status === 429) {\n throw new Error(\n \"GitHub API rate limit exceeded. Please try again later or set a GITHUB_TOKEN environment variable.\",\n );\n }\n throw new Error(\n `GitHub API request failed with status ${response.status}: ${response.statusText}`,\n );\n }\n\n let releases: GitHubRelease[];\n try {\n releases = await response.json();\n } catch {\n throw new Error(\"Failed to parse GitHub API response as JSON\");\n }\n\n if (!Array.isArray(releases)) {\n throw new Error(\"Unexpected response format from GitHub API\");\n }\n\n for (const release of releases) {\n if (release.tag_name?.startsWith(prefix)) {\n return release.tag_name.replace(prefix, \"\");\n }\n }\n\n throw new Error(\n \"Could not determine latest version of Aptos CLI. No matching release found in the last 100 releases.\",\n );\n};\n"]}
{"version":3,"file":"ghOperations.js","sourceRoot":"","sources":["../../bin/utils/ghOperations.ts"],"names":[],"mappings":"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","sourcesContent":["import { GH_CLI_DOWNLOAD_URL, PNAME } from \"./consts.js\";\n\ninterface GitHubAsset {\n name: string;\n digest: string | null;\n [key: string]: unknown;\n}\n\ninterface GitHubRelease {\n tag_name: string;\n assets?: GitHubAsset[];\n [key: string]: unknown;\n}\n\n/**\n * Build headers for GitHub API requests.\n * Uses GITHUB_TOKEN environment variable if available for authenticated requests.\n */\nconst getGitHubHeaders = (): Record<string, string> => {\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github.v3+json\",\n \"User-Agent\": \"aptos-cli-npm\",\n };\n\n // Use GITHUB_TOKEN if available for higher rate limits\n const token = process.env.GITHUB_TOKEN;\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n\n return headers;\n};\n\n/**\n * Get the user-specified CLI version from environment variable.\n * Returns undefined if not set.\n */\nexport const getUserSpecifiedVersion = (): string | undefined => {\n const version = process.env.APTOS_CLI_VERSION;\n if (!version) {\n return undefined;\n }\n // Strip 'v' prefix if present (e.g., \"v1.2.3\" -> \"1.2.3\")\n const stripped = version.replace(/^v/, \"\");\n if (!/^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?$/.test(stripped)) {\n throw new Error(\n `Invalid APTOS_CLI_VERSION: \"${version}\". Must match MAJOR.MINOR.PATCH (e.g. \"4.5.0\" or \"v4.5.0\").`,\n );\n }\n return stripped;\n};\n\n/**\n * Check if a user has specified a CLI version via environment variable.\n */\nexport const hasUserSpecifiedVersion = (): boolean => {\n return !!process.env.APTOS_CLI_VERSION;\n};\n\n/**\n * Validate that a specific version exists by checking if the release assets are accessible.\n * Uses a HEAD request to avoid downloading the actual file.\n *\n * @param version - The version to validate (without 'v' prefix)\n * @param targetPlatform - The target platform string (e.g., \"Ubuntu-22.04-x86_64\")\n */\nexport const validateVersionExists = async (\n version: string,\n targetPlatform: string,\n): Promise<boolean> => {\n const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${PNAME}-${version}-${targetPlatform}.zip`;\n\n try {\n const response = await fetch(url, {\n method: \"HEAD\",\n headers: getGitHubHeaders(),\n });\n return response.ok;\n } catch {\n return false;\n }\n};\n\n/**\n * Get the CLI version to use.\n * If APTOS_CLI_VERSION is set, returns that version (after validation).\n * Otherwise, returns the latest version from GitHub.\n *\n * @param targetPlatform - Optional target platform for version validation\n */\nexport const getCliVersion = async (\n targetPlatform?: string,\n): Promise<string> => {\n const userVersion = getUserSpecifiedVersion();\n\n if (userVersion) {\n // If a target platform is provided, validate the version exists\n if (targetPlatform) {\n const exists = await validateVersionExists(userVersion, targetPlatform);\n if (!exists) {\n throw new Error(\n `Specified version ${userVersion} does not exist or is not available for ${targetPlatform}. ` +\n `Check https://github.com/aptos-labs/aptos-core/releases for available versions.`,\n );\n }\n }\n return userVersion;\n }\n\n return getLatestVersionGh();\n};\n\n/**\n * Query the GitHub API to find the latest CLI release. We assume that the CLI is in\n * the last 100 releases so we don't paginate through the releases.\n *\n * Set GITHUB_TOKEN environment variable for higher rate limits.\n */\nexport const getLatestVersionGh = async (): Promise<string> => {\n const prefix = `${PNAME}-v`;\n const url =\n \"https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100\";\n\n let response: Response;\n try {\n response = await fetch(url, { headers: getGitHubHeaders() });\n } catch (error) {\n throw new Error(\n `Failed to fetch releases from GitHub: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (!response.ok) {\n if (response.status === 403 || response.status === 429) {\n throw new Error(\n \"GitHub API rate limit exceeded. Please try again later or set a GITHUB_TOKEN environment variable.\",\n );\n }\n throw new Error(\n `GitHub API request failed with status ${response.status}: ${response.statusText}`,\n );\n }\n\n let releases: GitHubRelease[];\n try {\n releases = await response.json();\n } catch {\n throw new Error(\"Failed to parse GitHub API response as JSON\");\n }\n\n if (!Array.isArray(releases)) {\n throw new Error(\"Unexpected response format from GitHub API\");\n }\n\n for (const release of releases) {\n if (release.tag_name?.startsWith(prefix)) {\n return release.tag_name.replace(prefix, \"\");\n }\n }\n\n throw new Error(\n \"Could not determine latest version of Aptos CLI. No matching release found in the last 100 releases.\",\n );\n};\n\n/**\n * Fetch the SHA256 digest for a specific release asset from the GitHub API.\n * Returns the hex digest string, or null if unavailable.\n */\nexport const getAssetDigest = async (\n version: string,\n assetName: string,\n): Promise<string | null> => {\n const tag = `${PNAME}-v${version}`;\n const url = `https://api.github.com/repos/aptos-labs/aptos-core/releases/tags/${tag}`;\n\n try {\n const response = await fetch(url, { headers: getGitHubHeaders() });\n if (!response.ok) {\n return null;\n }\n\n const release: GitHubRelease = await response.json();\n const asset = release.assets?.find((a) => a.name === assetName);\n if (!asset?.digest) {\n return null;\n }\n\n // Digest format is \"sha256:<hex>\" — strip the prefix\n const digest = asset.digest;\n if (digest.startsWith(\"sha256:\")) {\n return digest.slice(7);\n }\n return null;\n } catch {\n return null;\n }\n};\n"]}

@@ -41,6 +41,9 @@ import { execSync } from "node:child_process";

export const getCliPathWinget = () => {
const localAppData = process.env.LOCALAPPDATA;
const programFiles = process.env.PROGRAMFILES;
const possiblePaths = [
`${process.env.LOCALAPPDATA}\\Microsoft\\WinGet\\Packages\\Aptos.Aptos_Microsoft.Winget.Source_8wekyb3d8bbwe\\aptos.exe`,
`${process.env.PROGRAMFILES}\\Aptos\\aptos.exe`,
`${process.env.LOCALAPPDATA}\\Aptos\\aptos.exe`,
localAppData &&
`${localAppData}\\Microsoft\\WinGet\\Packages\\Aptos.Aptos_Microsoft.Winget.Source_8wekyb3d8bbwe\\aptos.exe`,
programFiles && `${programFiles}\\Aptos\\aptos.exe`,
localAppData && `${localAppData}\\Aptos\\aptos.exe`,
];

@@ -47,0 +50,0 @@ for (const path of possiblePaths) {

@@ -1,1 +0,1 @@

{"version":3,"file":"windowsPackageManagers.js","sourceRoot":"","sources":["../../bin/utils/windowsPackageManagers.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { executableIsAvailable } from \"./executableIsAvailable.js\";\n\n/**\n * Check if winget is available on the system.\n */\nexport const isWingetAvailable = (): boolean => {\n return executableIsAvailable(\"winget\");\n};\n\n/**\n * Check if Chocolatey is available on the system.\n */\nexport const isChocoAvailable = (): boolean => {\n return executableIsAvailable(\"choco\");\n};\n\n/**\n * Check if the Aptos CLI was installed via winget.\n */\nexport const isInstalledViaWinget = (): boolean => {\n if (!isWingetAvailable()) {\n return false;\n }\n try {\n const output = execSync(\"winget list --id Aptos.Aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return output.includes(\"Aptos.Aptos\");\n } catch {\n return false;\n }\n};\n\n/**\n * Check if the Aptos CLI was installed via Chocolatey.\n */\nexport const isInstalledViaChoco = (): boolean => {\n if (!isChocoAvailable()) {\n return false;\n }\n try {\n const output = execSync(\"choco list aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return output.toLowerCase().includes(\"aptos\");\n } catch {\n return false;\n }\n};\n\n/**\n * Get the path to the Aptos CLI binary installed via winget.\n * Winget typically installs to the user's local app data or program files.\n */\nexport const getCliPathWinget = (): string | null => {\n // Winget installs to various locations, try common ones\n const possiblePaths = [\n `${process.env.LOCALAPPDATA}\\\\Microsoft\\\\WinGet\\\\Packages\\\\Aptos.Aptos_Microsoft.Winget.Source_8wekyb3d8bbwe\\\\aptos.exe`,\n `${process.env.PROGRAMFILES}\\\\Aptos\\\\aptos.exe`,\n `${process.env.LOCALAPPDATA}\\\\Aptos\\\\aptos.exe`,\n ];\n\n for (const path of possiblePaths) {\n if (path && existsSync(path)) {\n return path;\n }\n }\n\n // Try to find it via where command\n try {\n const output = execSync(\"where aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n if (output && existsSync(output.split(\"\\n\")[0])) {\n return output.split(\"\\n\")[0];\n }\n } catch {\n // Not found via where\n }\n\n return null;\n};\n\n/**\n * Get the path to the Aptos CLI binary installed via Chocolatey.\n */\nexport const getCliPathChoco = (): string | null => {\n const chocoPath = `${process.env.ChocolateyInstall || \"C:\\\\ProgramData\\\\chocolatey\"}\\\\bin\\\\aptos.exe`;\n if (existsSync(chocoPath)) {\n return chocoPath;\n }\n return null;\n};\n\n/**\n * Install the Aptos CLI via winget.\n */\nexport const installViaWinget = (): void => {\n console.log(\"Installing Aptos CLI via winget...\");\n execSync(\n \"winget install --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n {\n stdio: \"inherit\",\n },\n );\n};\n\n/**\n * Install the Aptos CLI via Chocolatey.\n */\nexport const installViaChoco = (): void => {\n console.log(\"Installing Aptos CLI via Chocolatey...\");\n execSync(\"choco install aptos -y\", { stdio: \"inherit\" });\n};\n\n/**\n * Update the Aptos CLI via winget.\n */\nexport const updateViaWinget = (): void => {\n console.log(\"Updating Aptos CLI via winget...\");\n execSync(\n \"winget upgrade --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n {\n stdio: \"inherit\",\n },\n );\n};\n\n/**\n * Update the Aptos CLI via Chocolatey.\n */\nexport const updateViaChoco = (): void => {\n console.log(\"Updating Aptos CLI via Chocolatey...\");\n execSync(\"choco upgrade aptos -y\", { stdio: \"inherit\" });\n};\n\n/**\n * Detect which Windows package manager was used to install the CLI.\n * Returns the package manager name or null if not installed via a package manager.\n */\nexport const detectWindowsPackageManager = (): \"winget\" | \"choco\" | null => {\n if (isInstalledViaWinget()) {\n return \"winget\";\n }\n if (isInstalledViaChoco()) {\n return \"choco\";\n }\n return null;\n};\n"]}
{"version":3,"file":"windowsPackageManagers.js","sourceRoot":"","sources":["../../bin/utils/windowsPackageManagers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAY,EAAE;IAC7C,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAY,EAAE;IAC5C,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAY,EAAE;IAChD,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,8BAA8B,EAAE;YACtD,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAY,EAAE;IAC/C,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,kBAAkB,EAAE;YAC1C,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAkB,EAAE;IAElD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC9C,MAAM,aAAa,GAAG;QACpB,YAAY;YACV,GAAG,YAAY,6FAA6F;QAC9G,YAAY,IAAI,GAAG,YAAY,oBAAoB;QACnD,YAAY,IAAI,GAAG,YAAY,oBAAoB;KACpD,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAGD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,EAAE;YACrC,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;IAET,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAkB,EAAE;IACjD,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,6BAA6B,kBAAkB,CAAC;IACtG,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,QAAQ,CACN,iGAAiG,EACjG;QACE,KAAK,EAAE,SAAS;KACjB,CACF,CAAC;AACJ,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAS,EAAE;IACxC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,QAAQ,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAS,EAAE;IACxC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,QAAQ,CACN,iGAAiG,EACjG;QACE,KAAK,EAAE,SAAS;KACjB,CACF,CAAC;AACJ,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAS,EAAE;IACvC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,QAAQ,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAA8B,EAAE;IACzE,IAAI,oBAAoB,EAAE,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,mBAAmB,EAAE,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { executableIsAvailable } from \"./executableIsAvailable.js\";\n\n/**\n * Check if winget is available on the system.\n */\nexport const isWingetAvailable = (): boolean => {\n return executableIsAvailable(\"winget\");\n};\n\n/**\n * Check if Chocolatey is available on the system.\n */\nexport const isChocoAvailable = (): boolean => {\n return executableIsAvailable(\"choco\");\n};\n\n/**\n * Check if the Aptos CLI was installed via winget.\n */\nexport const isInstalledViaWinget = (): boolean => {\n if (!isWingetAvailable()) {\n return false;\n }\n try {\n const output = execSync(\"winget list --id Aptos.Aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return output.includes(\"Aptos.Aptos\");\n } catch {\n return false;\n }\n};\n\n/**\n * Check if the Aptos CLI was installed via Chocolatey.\n */\nexport const isInstalledViaChoco = (): boolean => {\n if (!isChocoAvailable()) {\n return false;\n }\n try {\n const output = execSync(\"choco list aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n return output.toLowerCase().includes(\"aptos\");\n } catch {\n return false;\n }\n};\n\n/**\n * Get the path to the Aptos CLI binary installed via winget.\n * Winget typically installs to the user's local app data or program files.\n */\nexport const getCliPathWinget = (): string | null => {\n // Winget installs to various locations, try common ones\n const localAppData = process.env.LOCALAPPDATA;\n const programFiles = process.env.PROGRAMFILES;\n const possiblePaths = [\n localAppData &&\n `${localAppData}\\\\Microsoft\\\\WinGet\\\\Packages\\\\Aptos.Aptos_Microsoft.Winget.Source_8wekyb3d8bbwe\\\\aptos.exe`,\n programFiles && `${programFiles}\\\\Aptos\\\\aptos.exe`,\n localAppData && `${localAppData}\\\\Aptos\\\\aptos.exe`,\n ];\n\n for (const path of possiblePaths) {\n if (path && existsSync(path)) {\n return path;\n }\n }\n\n // Try to find it via where command\n try {\n const output = execSync(\"where aptos\", {\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n if (output && existsSync(output.split(\"\\n\")[0])) {\n return output.split(\"\\n\")[0];\n }\n } catch {\n // Not found via where\n }\n\n return null;\n};\n\n/**\n * Get the path to the Aptos CLI binary installed via Chocolatey.\n */\nexport const getCliPathChoco = (): string | null => {\n const chocoPath = `${process.env.ChocolateyInstall || \"C:\\\\ProgramData\\\\chocolatey\"}\\\\bin\\\\aptos.exe`;\n if (existsSync(chocoPath)) {\n return chocoPath;\n }\n return null;\n};\n\n/**\n * Install the Aptos CLI via winget.\n */\nexport const installViaWinget = (): void => {\n console.log(\"Installing Aptos CLI via winget...\");\n execSync(\n \"winget install --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n {\n stdio: \"inherit\",\n },\n );\n};\n\n/**\n * Install the Aptos CLI via Chocolatey.\n */\nexport const installViaChoco = (): void => {\n console.log(\"Installing Aptos CLI via Chocolatey...\");\n execSync(\"choco install aptos -y\", { stdio: \"inherit\" });\n};\n\n/**\n * Update the Aptos CLI via winget.\n */\nexport const updateViaWinget = (): void => {\n console.log(\"Updating Aptos CLI via winget...\");\n execSync(\n \"winget upgrade --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n {\n stdio: \"inherit\",\n },\n );\n};\n\n/**\n * Update the Aptos CLI via Chocolatey.\n */\nexport const updateViaChoco = (): void => {\n console.log(\"Updating Aptos CLI via Chocolatey...\");\n execSync(\"choco upgrade aptos -y\", { stdio: \"inherit\" });\n};\n\n/**\n * Detect which Windows package manager was used to install the CLI.\n * Returns the package manager name or null if not installed via a package manager.\n */\nexport const detectWindowsPackageManager = (): \"winget\" | \"choco\" | null => {\n if (isInstalledViaWinget()) {\n return \"winget\";\n }\n if (isInstalledViaChoco()) {\n return \"choco\";\n }\n return null;\n};\n"]}
{
"name": "@aptos-labs/aptos-cli",
"version": "2.0.0",
"version": "3.0.0",
"description": "Aptos CLI available from npmjs",
"packageManager": "pnpm@10.30.1",
"engines": {

@@ -25,2 +26,21 @@ "node": ">=22"

"license": "Apache-2.0",
"scripts": {
"clean": "node -e \"import('node:fs').then(({rmSync})=>rmSync('dist',{recursive:true,force:true})).catch(e=>{console.error(e);process.exit(1)})\"",
"build": "pnpm run clean && tsc",
"dev": "pnpm run build && node ./dist/aptos.js",
"test": "vitest run",
"test:watch": "vitest",
"check": "biome check",
"check:fix": "biome check --fix",
"format": "biome format --fix"
},
"os": [
"darwin",
"linux",
"win32"
],
"cpu": [
"x64",
"arm64"
],
"sideEffects": false,

@@ -37,15 +57,11 @@ "exports": {},

"@types/node": "^22",
"typescript": "^5.9.3",
"typescript": "^6.0.2",
"vitest": "^4.0.18"
},
"scripts": {
"clean": "node --input-type=commonjs -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
"build": "pnpm run clean && tsc",
"dev": "pnpm run build && node ./dist/aptos.js",
"test": "vitest run",
"test:watch": "vitest",
"check": "biome check",
"check:fix": "biome check --fix",
"format": "biome format --fix"
"pnpm": {
"overrides": {
"picomatch": ">=4.0.4",
"vite": ">=7.3.2"
}
}
}
}
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
const WORKSPACE_ROOT = join(__dirname, "../..");
const EXAMPLES_DIR = join(WORKSPACE_ROOT, "examples");
const HELLO_BLOCKCHAIN_DIR = join(EXAMPLES_DIR, "hello_blockchain");
describe("Example Move Projects", () => {
describe("hello_blockchain example", () => {
it("should have Move.toml configuration file", () => {
const moveTomlPath = join(HELLO_BLOCKCHAIN_DIR, "Move.toml");
expect(existsSync(moveTomlPath)).toBe(true);
const content = readFileSync(moveTomlPath, "utf-8");
expect(content).toContain("[package]");
expect(content).toContain('name = "HelloBlockchain"');
expect(content).toContain("[addresses]");
expect(content).toContain("hello_blockchain");
expect(content).toContain("[dependencies.AptosFramework]");
});
it("should have source files", () => {
const sourcesDir = join(HELLO_BLOCKCHAIN_DIR, "sources");
expect(existsSync(sourcesDir)).toBe(true);
const messageMovePath = join(sourcesDir, "message.move");
expect(existsSync(messageMovePath)).toBe(true);
});
it("should have valid Move module structure", () => {
const messageMovePath = join(HELLO_BLOCKCHAIN_DIR, "sources/message.move");
const content = readFileSync(messageMovePath, "utf-8");
expect(content).toContain("module hello_blockchain::message");
expect(content).toContain("public entry fun");
expect(content).toContain("has key");
expect(content).toContain("#[test");
});
});
});
describe("Build Move Artifacts Workflow", () => {
const workflowPath = join(WORKSPACE_ROOT, ".github/workflows/build-move-artifacts.yaml");
it("should have the workflow file", () => {
expect(existsSync(workflowPath)).toBe(true);
});
it("should contain required workflow configuration", () => {
const content = readFileSync(workflowPath, "utf-8");
expect(content).toContain("name: Build Move Artifacts");
expect(content).toContain("on:");
expect(content).toContain("jobs:");
expect(content).toContain("Install Aptos CLI");
expect(content).toContain("--install");
expect(content).toContain("Build Move package");
expect(content).toContain("move compile");
expect(content).toContain("--named-addresses");
expect(content).toContain("--save-metadata");
expect(content).toContain("Generate publish payload");
expect(content).toContain("build-publish-payload");
expect(content).toContain("--json-output-file");
expect(content).toContain("Upload build artifacts");
expect(content).toContain("actions/upload-artifact");
});
it("should have artifact download job for downstream usage", () => {
const content = readFileSync(workflowPath, "utf-8");
expect(content).toContain("use-artifacts");
expect(content).toContain("needs: build-artifacts");
expect(content).toContain("actions/download-artifact");
});
it("should demonstrate upgrade payload generation", () => {
const content = readFileSync(workflowPath, "utf-8");
expect(content).toContain("build-upgrade-payload");
expect(content).toContain("--object-address");
});
});
//# sourceMappingURL=examples.test.js.map
{"version":3,"file":"examples.test.js","sourceRoot":"","sources":["../../bin/examples/examples.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { describe, expect, it } from \"vitest\";\n\nconst WORKSPACE_ROOT = join(__dirname, \"../..\");\nconst EXAMPLES_DIR = join(WORKSPACE_ROOT, \"examples\");\nconst HELLO_BLOCKCHAIN_DIR = join(EXAMPLES_DIR, \"hello_blockchain\");\n\ndescribe(\"Example Move Projects\", () => {\n describe(\"hello_blockchain example\", () => {\n it(\"should have Move.toml configuration file\", () => {\n const moveTomlPath = join(HELLO_BLOCKCHAIN_DIR, \"Move.toml\");\n expect(existsSync(moveTomlPath)).toBe(true);\n\n const content = readFileSync(moveTomlPath, \"utf-8\");\n expect(content).toContain(\"[package]\");\n expect(content).toContain('name = \"HelloBlockchain\"');\n expect(content).toContain(\"[addresses]\");\n expect(content).toContain(\"hello_blockchain\");\n expect(content).toContain(\"[dependencies.AptosFramework]\");\n });\n\n it(\"should have source files\", () => {\n const sourcesDir = join(HELLO_BLOCKCHAIN_DIR, \"sources\");\n expect(existsSync(sourcesDir)).toBe(true);\n\n const messageMovePath = join(sourcesDir, \"message.move\");\n expect(existsSync(messageMovePath)).toBe(true);\n });\n\n it(\"should have valid Move module structure\", () => {\n const messageMovePath = join(\n HELLO_BLOCKCHAIN_DIR,\n \"sources/message.move\",\n );\n const content = readFileSync(messageMovePath, \"utf-8\");\n\n // Verify module declaration\n expect(content).toContain(\"module hello_blockchain::message\");\n\n // Verify it has required components for a deployable module\n expect(content).toContain(\"public entry fun\");\n expect(content).toContain(\"has key\");\n\n // Verify it has a test\n expect(content).toContain(\"#[test\");\n });\n });\n});\n\ndescribe(\"Build Move Artifacts Workflow\", () => {\n const workflowPath = join(\n WORKSPACE_ROOT,\n \".github/workflows/build-move-artifacts.yaml\",\n );\n\n it(\"should have the workflow file\", () => {\n expect(existsSync(workflowPath)).toBe(true);\n });\n\n it(\"should contain required workflow configuration\", () => {\n const content = readFileSync(workflowPath, \"utf-8\");\n\n // Verify workflow structure\n expect(content).toContain(\"name: Build Move Artifacts\");\n expect(content).toContain(\"on:\");\n expect(content).toContain(\"jobs:\");\n\n // Verify it installs the CLI\n expect(content).toContain(\"Install Aptos CLI\");\n expect(content).toContain(\"--install\");\n\n // Verify it builds Move package\n expect(content).toContain(\"Build Move package\");\n expect(content).toContain(\"move compile\");\n expect(content).toContain(\"--named-addresses\");\n expect(content).toContain(\"--save-metadata\");\n\n // Verify it generates publish payload\n expect(content).toContain(\"Generate publish payload\");\n expect(content).toContain(\"build-publish-payload\");\n expect(content).toContain(\"--json-output-file\");\n\n // Verify artifact upload step\n expect(content).toContain(\"Upload build artifacts\");\n expect(content).toContain(\"actions/upload-artifact\");\n });\n\n it(\"should have artifact download job for downstream usage\", () => {\n const content = readFileSync(workflowPath, \"utf-8\");\n\n // Verify there's a job that uses artifacts\n expect(content).toContain(\"use-artifacts\");\n expect(content).toContain(\"needs: build-artifacts\");\n expect(content).toContain(\"actions/download-artifact\");\n });\n\n it(\"should demonstrate upgrade payload generation\", () => {\n const content = readFileSync(workflowPath, \"utf-8\");\n\n // Verify upgrade payload example is present\n expect(content).toContain(\"build-upgrade-payload\");\n expect(content).toContain(\"--object-address\");\n });\n});\n"]}
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("child_process", () => ({
execSync: vi.fn(),
}));
vi.mock("fs", () => ({
existsSync: vi.fn(),
chmodSync: vi.fn(),
mkdirSync: vi.fn(),
}));
vi.mock("os", () => ({
tmpdir: () => "/tmp",
homedir: () => "/home/user",
platform: vi.fn(() => "linux"),
arch: vi.fn(() => "x64"),
}));
vi.mock("../utils/getUserOs.js", () => ({
getOS: vi.fn(),
getTargetPlatform: vi.fn(),
}));
vi.mock("../utils/getLocalBinPath.js", () => ({
getLocalBinPath: vi.fn(),
getBinDir: vi.fn(),
invalidateBinPathCache: vi.fn(),
}));
vi.mock("../utils/ghOperations.js", () => ({
getCliVersion: vi.fn(),
hasUserSpecifiedVersion: vi.fn(),
}));
vi.mock("../utils/brewOperations.js", () => ({
isBrewAvailable: vi.fn(),
isInstalledViaBrew: vi.fn(),
installViaBrew: vi.fn(),
}));
vi.mock("../utils/windowsPackageManagers.js", () => ({
isWingetAvailable: vi.fn(),
isChocoAvailable: vi.fn(),
isInstalledViaWinget: vi.fn(),
isInstalledViaChoco: vi.fn(),
installViaWinget: vi.fn(),
installViaChoco: vi.fn(),
}));
import { execSync } from "node:child_process";
import { existsSync, mkdirSync } from "node:fs";
import { installViaBrew, isBrewAvailable, isInstalledViaBrew, } from "../utils/brewOperations.js";
import { getBinDir, getLocalBinPath } from "../utils/getLocalBinPath.js";
import { getOS, getTargetPlatform } from "../utils/getUserOs.js";
import { getCliVersion, hasUserSpecifiedVersion, } from "../utils/ghOperations.js";
import { installViaChoco, installViaWinget, isChocoAvailable, isInstalledViaChoco, isInstalledViaWinget, isWingetAvailable, } from "../utils/windowsPackageManagers.js";
import { installCli } from "./install.js";
describe("install", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(getLocalBinPath).mockReturnValue("/home/user/.local/bin/aptos");
vi.mocked(getBinDir).mockReturnValue("/home/user/.local/bin");
vi.mocked(getCliVersion).mockResolvedValue("1.0.0");
vi.mocked(hasUserSpecifiedVersion).mockReturnValue(false);
vi.mocked(getTargetPlatform).mockReturnValue("Linux-x86_64");
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("macOS with Homebrew", () => {
beforeEach(() => {
vi.mocked(getOS).mockReturnValue("MacOS");
vi.mocked(isBrewAvailable).mockReturnValue(true);
});
it("should use Homebrew when available", async () => {
vi.mocked(isInstalledViaBrew).mockReturnValue(false);
await installCli();
expect(installViaBrew).toHaveBeenCalled();
expect(execSync).not.toHaveBeenCalled();
});
it("should skip if already installed via Homebrew", async () => {
vi.mocked(isInstalledViaBrew).mockReturnValue(true);
await installCli();
expect(installViaBrew).not.toHaveBeenCalled();
});
it("should skip Homebrew when directDownload is true", async () => {
vi.mocked(isInstalledViaBrew).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
vi.mocked(getTargetPlatform).mockReturnValue("macos-x86_64");
await installCli(true);
expect(installViaBrew).not.toHaveBeenCalled();
expect(execSync).toHaveBeenCalled();
});
});
describe("Windows with winget", () => {
beforeEach(() => {
vi.mocked(getOS).mockReturnValue("Windows");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(isWingetAvailable).mockReturnValue(true);
vi.mocked(isChocoAvailable).mockReturnValue(false);
});
it("should use winget when available", async () => {
vi.mocked(isInstalledViaWinget).mockReturnValue(false);
await installCli();
expect(installViaWinget).toHaveBeenCalled();
expect(installViaChoco).not.toHaveBeenCalled();
});
it("should skip if already installed via winget", async () => {
vi.mocked(isInstalledViaWinget).mockReturnValue(true);
await installCli();
expect(installViaWinget).not.toHaveBeenCalled();
});
});
describe("Windows with Chocolatey", () => {
beforeEach(() => {
vi.mocked(getOS).mockReturnValue("Windows");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(isWingetAvailable).mockReturnValue(false);
vi.mocked(isChocoAvailable).mockReturnValue(true);
});
it("should use Chocolatey when winget is not available", async () => {
vi.mocked(isInstalledViaChoco).mockReturnValue(false);
await installCli();
expect(installViaChoco).toHaveBeenCalled();
expect(installViaWinget).not.toHaveBeenCalled();
});
it("should skip if already installed via Chocolatey", async () => {
vi.mocked(isInstalledViaChoco).mockReturnValue(true);
await installCli();
expect(installViaChoco).not.toHaveBeenCalled();
});
});
describe("Windows direct download", () => {
beforeEach(() => {
vi.mocked(getOS).mockReturnValue("Windows");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(isWingetAvailable).mockReturnValue(false);
vi.mocked(isChocoAvailable).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(getTargetPlatform).mockReturnValue("Windows-x86_64");
});
it("should download directly when no package manager available", async () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
await installCli();
expect(installViaWinget).not.toHaveBeenCalled();
expect(installViaChoco).not.toHaveBeenCalled();
expect(execSync).toHaveBeenCalledWith(expect.stringContaining("powershell"), expect.any(Object));
});
it("should skip package managers when directDownload is true", async () => {
vi.mocked(isWingetAvailable).mockReturnValue(true);
vi.mocked(isChocoAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
await installCli(true);
expect(installViaWinget).not.toHaveBeenCalled();
expect(installViaChoco).not.toHaveBeenCalled();
expect(execSync).toHaveBeenCalled();
});
});
describe("Linux direct download", () => {
beforeEach(() => {
vi.mocked(getOS).mockReturnValue("Linux");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(getTargetPlatform).mockReturnValue("Ubuntu-22.04-x86_64");
});
it("should download directly on Linux", async () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
await installCli();
expect(execSync).toHaveBeenCalledWith(expect.stringContaining("curl"), expect.any(Object));
});
it("should create bin directory if it doesn't exist", async () => {
vi.mocked(existsSync).mockImplementation((path) => {
if (path === "/home/user/.local/bin")
return false;
return false;
});
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
await installCli();
expect(mkdirSync).toHaveBeenCalledWith("/home/user/.local/bin", {
recursive: true,
});
});
});
describe("already installed", () => {
it("should skip if binary already exists", async () => {
vi.mocked(getOS).mockReturnValue("Linux");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(true);
await installCli();
expect(execSync).not.toHaveBeenCalled();
expect(getCliVersion).not.toHaveBeenCalled();
});
});
describe("specific version via APTOS_CLI_VERSION", () => {
beforeEach(() => {
vi.mocked(hasUserSpecifiedVersion).mockReturnValue(true);
vi.mocked(getCliVersion).mockResolvedValue("4.5.0");
});
it("should skip package managers when specific version is set", async () => {
vi.mocked(getOS).mockReturnValue("MacOS");
vi.mocked(isBrewAvailable).mockReturnValue(true);
vi.mocked(isInstalledViaBrew).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
vi.mocked(getTargetPlatform).mockReturnValue("macos-x86_64");
await installCli();
expect(installViaBrew).not.toHaveBeenCalled();
expect(execSync).toHaveBeenCalled();
});
it("should skip winget when specific version is set on Windows", async () => {
vi.mocked(getOS).mockReturnValue("Windows");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(isWingetAvailable).mockReturnValue(true);
vi.mocked(isChocoAvailable).mockReturnValue(true);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
vi.mocked(getTargetPlatform).mockReturnValue("Windows-x86_64");
await installCli();
expect(installViaWinget).not.toHaveBeenCalled();
expect(installViaChoco).not.toHaveBeenCalled();
expect(execSync).toHaveBeenCalled();
});
it("should use specific version in download URL", async () => {
vi.mocked(getOS).mockReturnValue("Linux");
vi.mocked(isBrewAvailable).mockReturnValue(false);
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
vi.mocked(getTargetPlatform).mockReturnValue("Ubuntu-22.04-x86_64");
await installCli();
expect(execSync).toHaveBeenCalledWith(expect.stringContaining("4.5.0"), expect.any(Object));
});
});
});
//# sourceMappingURL=install.test.js.map
{"version":3,"file":"install.test.js","sourceRoot":"","sources":["../../bin/tasks/install.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\n// Mock all dependencies before importing the module under test\nvi.mock(\"child_process\", () => ({\n execSync: vi.fn(),\n}));\n\nvi.mock(\"fs\", () => ({\n existsSync: vi.fn(),\n chmodSync: vi.fn(),\n mkdirSync: vi.fn(),\n}));\n\nvi.mock(\"os\", () => ({\n tmpdir: () => \"/tmp\",\n homedir: () => \"/home/user\",\n platform: vi.fn(() => \"linux\"),\n arch: vi.fn(() => \"x64\"),\n}));\n\nvi.mock(\"../utils/getUserOs.js\", () => ({\n getOS: vi.fn(),\n getTargetPlatform: vi.fn(),\n}));\n\nvi.mock(\"../utils/getLocalBinPath.js\", () => ({\n getLocalBinPath: vi.fn(),\n getBinDir: vi.fn(),\n invalidateBinPathCache: vi.fn(),\n}));\n\nvi.mock(\"../utils/ghOperations.js\", () => ({\n getCliVersion: vi.fn(),\n hasUserSpecifiedVersion: vi.fn(),\n}));\n\nvi.mock(\"../utils/brewOperations.js\", () => ({\n isBrewAvailable: vi.fn(),\n isInstalledViaBrew: vi.fn(),\n installViaBrew: vi.fn(),\n}));\n\nvi.mock(\"../utils/windowsPackageManagers.js\", () => ({\n isWingetAvailable: vi.fn(),\n isChocoAvailable: vi.fn(),\n isInstalledViaWinget: vi.fn(),\n isInstalledViaChoco: vi.fn(),\n installViaWinget: vi.fn(),\n installViaChoco: vi.fn(),\n}));\n\nimport { execSync } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport {\n installViaBrew,\n isBrewAvailable,\n isInstalledViaBrew,\n} from \"../utils/brewOperations.js\";\nimport { getBinDir, getLocalBinPath } from \"../utils/getLocalBinPath.js\";\nimport { getOS, getTargetPlatform } from \"../utils/getUserOs.js\";\nimport {\n getCliVersion,\n hasUserSpecifiedVersion,\n} from \"../utils/ghOperations.js\";\nimport {\n installViaChoco,\n installViaWinget,\n isChocoAvailable,\n isInstalledViaChoco,\n isInstalledViaWinget,\n isWingetAvailable,\n} from \"../utils/windowsPackageManagers.js\";\nimport { installCli } from \"./install.js\";\n\ndescribe(\"install\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n vi.mocked(getLocalBinPath).mockReturnValue(\"/home/user/.local/bin/aptos\");\n vi.mocked(getBinDir).mockReturnValue(\"/home/user/.local/bin\");\n vi.mocked(getCliVersion).mockResolvedValue(\"1.0.0\");\n vi.mocked(hasUserSpecifiedVersion).mockReturnValue(false);\n vi.mocked(getTargetPlatform).mockReturnValue(\"Linux-x86_64\");\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe(\"macOS with Homebrew\", () => {\n beforeEach(() => {\n vi.mocked(getOS).mockReturnValue(\"MacOS\");\n vi.mocked(isBrewAvailable).mockReturnValue(true);\n });\n\n it(\"should use Homebrew when available\", async () => {\n vi.mocked(isInstalledViaBrew).mockReturnValue(false);\n\n await installCli();\n\n expect(installViaBrew).toHaveBeenCalled();\n expect(execSync).not.toHaveBeenCalled();\n });\n\n it(\"should skip if already installed via Homebrew\", async () => {\n vi.mocked(isInstalledViaBrew).mockReturnValue(true);\n\n await installCli();\n\n expect(installViaBrew).not.toHaveBeenCalled();\n });\n\n it(\"should skip Homebrew when directDownload is true\", async () => {\n vi.mocked(isInstalledViaBrew).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n vi.mocked(getTargetPlatform).mockReturnValue(\"macos-x86_64\");\n\n await installCli(true);\n\n expect(installViaBrew).not.toHaveBeenCalled();\n expect(execSync).toHaveBeenCalled();\n });\n });\n\n describe(\"Windows with winget\", () => {\n beforeEach(() => {\n vi.mocked(getOS).mockReturnValue(\"Windows\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(isWingetAvailable).mockReturnValue(true);\n vi.mocked(isChocoAvailable).mockReturnValue(false);\n });\n\n it(\"should use winget when available\", async () => {\n vi.mocked(isInstalledViaWinget).mockReturnValue(false);\n\n await installCli();\n\n expect(installViaWinget).toHaveBeenCalled();\n expect(installViaChoco).not.toHaveBeenCalled();\n });\n\n it(\"should skip if already installed via winget\", async () => {\n vi.mocked(isInstalledViaWinget).mockReturnValue(true);\n\n await installCli();\n\n expect(installViaWinget).not.toHaveBeenCalled();\n });\n });\n\n describe(\"Windows with Chocolatey\", () => {\n beforeEach(() => {\n vi.mocked(getOS).mockReturnValue(\"Windows\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(isWingetAvailable).mockReturnValue(false);\n vi.mocked(isChocoAvailable).mockReturnValue(true);\n });\n\n it(\"should use Chocolatey when winget is not available\", async () => {\n vi.mocked(isInstalledViaChoco).mockReturnValue(false);\n\n await installCli();\n\n expect(installViaChoco).toHaveBeenCalled();\n expect(installViaWinget).not.toHaveBeenCalled();\n });\n\n it(\"should skip if already installed via Chocolatey\", async () => {\n vi.mocked(isInstalledViaChoco).mockReturnValue(true);\n\n await installCli();\n\n expect(installViaChoco).not.toHaveBeenCalled();\n });\n });\n\n describe(\"Windows direct download\", () => {\n beforeEach(() => {\n vi.mocked(getOS).mockReturnValue(\"Windows\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(isWingetAvailable).mockReturnValue(false);\n vi.mocked(isChocoAvailable).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(getTargetPlatform).mockReturnValue(\"Windows-x86_64\");\n });\n\n it(\"should download directly when no package manager available\", async () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n await installCli();\n\n expect(installViaWinget).not.toHaveBeenCalled();\n expect(installViaChoco).not.toHaveBeenCalled();\n expect(execSync).toHaveBeenCalledWith(\n expect.stringContaining(\"powershell\"),\n expect.any(Object),\n );\n });\n\n it(\"should skip package managers when directDownload is true\", async () => {\n vi.mocked(isWingetAvailable).mockReturnValue(true);\n vi.mocked(isChocoAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n await installCli(true);\n\n expect(installViaWinget).not.toHaveBeenCalled();\n expect(installViaChoco).not.toHaveBeenCalled();\n expect(execSync).toHaveBeenCalled();\n });\n });\n\n describe(\"Linux direct download\", () => {\n beforeEach(() => {\n vi.mocked(getOS).mockReturnValue(\"Linux\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(getTargetPlatform).mockReturnValue(\"Ubuntu-22.04-x86_64\");\n });\n\n it(\"should download directly on Linux\", async () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n await installCli();\n\n expect(execSync).toHaveBeenCalledWith(\n expect.stringContaining(\"curl\"),\n expect.any(Object),\n );\n });\n\n it(\"should create bin directory if it doesn't exist\", async () => {\n vi.mocked(existsSync).mockImplementation((path) => {\n if (path === \"/home/user/.local/bin\") return false;\n return false;\n });\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n await installCli();\n\n expect(mkdirSync).toHaveBeenCalledWith(\"/home/user/.local/bin\", {\n recursive: true,\n });\n });\n });\n\n describe(\"already installed\", () => {\n it(\"should skip if binary already exists\", async () => {\n vi.mocked(getOS).mockReturnValue(\"Linux\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(true);\n\n await installCli();\n\n expect(execSync).not.toHaveBeenCalled();\n expect(getCliVersion).not.toHaveBeenCalled();\n });\n });\n\n describe(\"specific version via APTOS_CLI_VERSION\", () => {\n beforeEach(() => {\n vi.mocked(hasUserSpecifiedVersion).mockReturnValue(true);\n vi.mocked(getCliVersion).mockResolvedValue(\"4.5.0\");\n });\n\n it(\"should skip package managers when specific version is set\", async () => {\n vi.mocked(getOS).mockReturnValue(\"MacOS\");\n vi.mocked(isBrewAvailable).mockReturnValue(true);\n vi.mocked(isInstalledViaBrew).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n vi.mocked(getTargetPlatform).mockReturnValue(\"macos-x86_64\");\n\n await installCli();\n\n // Should NOT use Homebrew even though it's available\n expect(installViaBrew).not.toHaveBeenCalled();\n // Should download directly\n expect(execSync).toHaveBeenCalled();\n });\n\n it(\"should skip winget when specific version is set on Windows\", async () => {\n vi.mocked(getOS).mockReturnValue(\"Windows\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(isWingetAvailable).mockReturnValue(true);\n vi.mocked(isChocoAvailable).mockReturnValue(true);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n vi.mocked(getTargetPlatform).mockReturnValue(\"Windows-x86_64\");\n\n await installCli();\n\n expect(installViaWinget).not.toHaveBeenCalled();\n expect(installViaChoco).not.toHaveBeenCalled();\n expect(execSync).toHaveBeenCalled();\n });\n\n it(\"should use specific version in download URL\", async () => {\n vi.mocked(getOS).mockReturnValue(\"Linux\");\n vi.mocked(isBrewAvailable).mockReturnValue(false);\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n vi.mocked(getTargetPlatform).mockReturnValue(\"Ubuntu-22.04-x86_64\");\n\n await installCli();\n\n // Verify the URL contains the specific version\n expect(execSync).toHaveBeenCalledWith(\n expect.stringContaining(\"4.5.0\"),\n expect.any(Object),\n );\n });\n });\n});\n"]}
import { EventEmitter } from "node:events";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const createMockChildProcess = () => {
const emitter = new EventEmitter();
return emitter;
};
let mockChildProcess;
vi.mock("child_process", () => ({
spawn: vi.fn(() => mockChildProcess),
}));
vi.mock("fs", () => ({
existsSync: vi.fn(),
}));
vi.mock("../utils/getUserOs.js", () => ({
getPlatformInfo: vi.fn(() => ({ os: "linux", arch: "x64" })),
}));
vi.mock("../utils/getLocalBinPath.js", () => ({
getLocalBinPath: vi.fn(() => "/home/user/.local/bin/aptos"),
}));
import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { runCLI } from "./run.js";
describe("run", () => {
const mockExit = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
mockChildProcess = createMockChildProcess();
vi.stubGlobal("process", {
...process,
exit: mockExit,
});
});
afterEach(() => {
vi.unstubAllGlobals();
});
describe("runCLI", () => {
it("should spawn the CLI with provided arguments", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["info", "--verbose"]);
expect(spawn).toHaveBeenCalledWith("/home/user/.local/bin/aptos", ["info", "--verbose"], expect.objectContaining({
stdio: "inherit",
}));
});
it("should use custom binary path when provided", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["info"], "/custom/path/aptos");
expect(spawn).toHaveBeenCalledWith("/custom/path/aptos", ["info"], expect.any(Object));
});
it("should exit with non-zero code when child process exits with non-zero code", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["invalid-command"]);
mockChildProcess.emit("exit", 1);
expect(mockExit).toHaveBeenCalledWith(1);
});
it("should exit with the exact exit code from child process", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["some-command"]);
mockChildProcess.emit("exit", 42);
expect(mockExit).toHaveBeenCalledWith(42);
});
it("should not call process.exit when child process exits with code 0", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["info"]);
mockChildProcess.emit("exit", 0);
expect(mockExit).not.toHaveBeenCalled();
});
it("should not call process.exit when child process exits with null code", async () => {
vi.mocked(existsSync).mockReturnValue(true);
await runCLI(["info"]);
mockChildProcess.emit("exit", null);
expect(mockExit).not.toHaveBeenCalled();
});
it("should print error and exit if custom binary path does not exist", async () => {
vi.mocked(existsSync).mockReturnValue(false);
const consoleSpy = vi
.spyOn(console, "error")
.mockImplementation(() => { });
await runCLI(["info"], "/nonexistent/path/aptos");
expect(consoleSpy).toHaveBeenCalledWith("Error: Binary not found at specified path: /nonexistent/path/aptos");
expect(mockExit).toHaveBeenCalledWith(1);
expect(spawn).not.toHaveBeenCalled();
});
it("should print install message if default binary does not exist", async () => {
vi.mocked(existsSync).mockReturnValue(false);
const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
await runCLI(["info"]);
expect(consoleSpy).toHaveBeenCalledWith("Aptos CLI not installed, run `npx aptos --install` to install");
expect(spawn).not.toHaveBeenCalled();
});
});
});
//# sourceMappingURL=run.test.js.map
{"version":3,"file":"run.test.js","sourceRoot":"","sources":["../../bin/tasks/run.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from \"node:events\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\n// Create a mock child process that can emit events\nconst createMockChildProcess = () => {\n const emitter = new EventEmitter();\n return emitter;\n};\n\nlet mockChildProcess: EventEmitter;\n\nvi.mock(\"child_process\", () => ({\n spawn: vi.fn(() => mockChildProcess),\n}));\n\nvi.mock(\"fs\", () => ({\n existsSync: vi.fn(),\n}));\n\nvi.mock(\"../utils/getUserOs.js\", () => ({\n getPlatformInfo: vi.fn(() => ({ os: \"linux\", arch: \"x64\" })),\n}));\n\nvi.mock(\"../utils/getLocalBinPath.js\", () => ({\n getLocalBinPath: vi.fn(() => \"/home/user/.local/bin/aptos\"),\n}));\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { runCLI } from \"./run.js\";\n\ndescribe(\"run\", () => {\n const mockExit = vi.fn<(code?: number) => never>();\n\n beforeEach(() => {\n vi.clearAllMocks();\n mockChildProcess = createMockChildProcess();\n vi.stubGlobal(\"process\", {\n ...process,\n exit: mockExit,\n });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n });\n\n describe(\"runCLI\", () => {\n it(\"should spawn the CLI with provided arguments\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"info\", \"--verbose\"]);\n\n expect(spawn).toHaveBeenCalledWith(\n \"/home/user/.local/bin/aptos\",\n [\"info\", \"--verbose\"],\n expect.objectContaining({\n stdio: \"inherit\",\n }),\n );\n });\n\n it(\"should use custom binary path when provided\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"info\"], \"/custom/path/aptos\");\n\n expect(spawn).toHaveBeenCalledWith(\n \"/custom/path/aptos\",\n [\"info\"],\n expect.any(Object),\n );\n });\n\n it(\"should exit with non-zero code when child process exits with non-zero code\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"invalid-command\"]);\n\n // Simulate child process exiting with code 1\n mockChildProcess.emit(\"exit\", 1);\n\n expect(mockExit).toHaveBeenCalledWith(1);\n });\n\n it(\"should exit with the exact exit code from child process\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"some-command\"]);\n\n // Simulate child process exiting with code 42\n mockChildProcess.emit(\"exit\", 42);\n\n expect(mockExit).toHaveBeenCalledWith(42);\n });\n\n it(\"should not call process.exit when child process exits with code 0\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"info\"]);\n\n // Simulate child process exiting with code 0 (success)\n mockChildProcess.emit(\"exit\", 0);\n\n expect(mockExit).not.toHaveBeenCalled();\n });\n\n it(\"should not call process.exit when child process exits with null code\", async () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n await runCLI([\"info\"]);\n\n // Simulate child process exiting with null (e.g., killed by signal)\n mockChildProcess.emit(\"exit\", null);\n\n expect(mockExit).not.toHaveBeenCalled();\n });\n\n it(\"should print error and exit if custom binary path does not exist\", async () => {\n vi.mocked(existsSync).mockReturnValue(false);\n const consoleSpy = vi\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n await runCLI([\"info\"], \"/nonexistent/path/aptos\");\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Error: Binary not found at specified path: /nonexistent/path/aptos\",\n );\n expect(mockExit).toHaveBeenCalledWith(1);\n expect(spawn).not.toHaveBeenCalled();\n });\n\n it(\"should print install message if default binary does not exist\", async () => {\n vi.mocked(existsSync).mockReturnValue(false);\n const consoleSpy = vi.spyOn(console, \"log\").mockImplementation(() => {});\n\n await runCLI([\"info\"]);\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Aptos CLI not installed, run `npx aptos --install` to install\",\n );\n expect(spawn).not.toHaveBeenCalled();\n });\n });\n});\n"]}
import { execSync } from "node:child_process";
import { existsSync } from "node:fs";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("child_process", () => ({
execSync: vi.fn(),
}));
vi.mock("fs", () => ({
existsSync: vi.fn(),
}));
vi.mock("./executableIsAvailable.js", () => ({
executableIsAvailable: vi.fn(),
}));
import { getCliPathBrew, installViaBrew, isBrewAvailable, isInstalledViaBrew, updateViaBrew, } from "./brewOperations.js";
import { executableIsAvailable } from "./executableIsAvailable.js";
describe("brewOperations", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("isBrewAvailable", () => {
it("should return true when brew is available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
expect(isBrewAvailable()).toBe(true);
expect(executableIsAvailable).toHaveBeenCalledWith("brew");
});
it("should return false when brew is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isBrewAvailable()).toBe(false);
});
});
describe("isInstalledViaBrew", () => {
it("should return true when aptos is installed via brew", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("/opt/homebrew/Cellar/aptos");
vi.mocked(existsSync).mockReturnValue(true);
expect(isInstalledViaBrew()).toBe(true);
});
it("should return false when brew is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isInstalledViaBrew()).toBe(false);
});
it("should return false when aptos path doesn't exist", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("/opt/homebrew/Cellar/aptos");
vi.mocked(existsSync).mockReturnValue(false);
expect(isInstalledViaBrew()).toBe(false);
});
it("should return false when brew --prefix throws", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockImplementation(() => {
throw new Error("aptos not installed");
});
expect(isInstalledViaBrew()).toBe(false);
});
});
describe("getCliPathBrew", () => {
it("should return the correct path", () => {
vi.mocked(execSync).mockReturnValue("/opt/homebrew/Cellar/aptos\n");
expect(getCliPathBrew()).toBe("/opt/homebrew/Cellar/aptos/bin/aptos");
});
});
describe("installViaBrew", () => {
it("should call brew install aptos", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
installViaBrew();
expect(execSync).toHaveBeenCalledWith("brew install aptos", {
stdio: "inherit",
});
});
});
describe("updateViaBrew", () => {
it("should call brew upgrade aptos", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
updateViaBrew();
expect(execSync).toHaveBeenCalledWith("brew upgrade aptos", {
stdio: "inherit",
});
});
});
});
//# sourceMappingURL=brewOperations.test.js.map
{"version":3,"file":"brewOperations.test.js","sourceRoot":"","sources":["../../bin/utils/brewOperations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nvi.mock(\"child_process\", () => ({\n execSync: vi.fn(),\n}));\n\nvi.mock(\"fs\", () => ({\n existsSync: vi.fn(),\n}));\n\nvi.mock(\"./executableIsAvailable.js\", () => ({\n executableIsAvailable: vi.fn(),\n}));\n\nimport {\n getCliPathBrew,\n installViaBrew,\n isBrewAvailable,\n isInstalledViaBrew,\n updateViaBrew,\n} from \"./brewOperations.js\";\nimport { executableIsAvailable } from \"./executableIsAvailable.js\";\n\ndescribe(\"brewOperations\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe(\"isBrewAvailable\", () => {\n it(\"should return true when brew is available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n\n expect(isBrewAvailable()).toBe(true);\n expect(executableIsAvailable).toHaveBeenCalledWith(\"brew\");\n });\n\n it(\"should return false when brew is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isBrewAvailable()).toBe(false);\n });\n });\n\n describe(\"isInstalledViaBrew\", () => {\n it(\"should return true when aptos is installed via brew\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"/opt/homebrew/Cellar/aptos\");\n vi.mocked(existsSync).mockReturnValue(true);\n\n expect(isInstalledViaBrew()).toBe(true);\n });\n\n it(\"should return false when brew is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isInstalledViaBrew()).toBe(false);\n });\n\n it(\"should return false when aptos path doesn't exist\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"/opt/homebrew/Cellar/aptos\");\n vi.mocked(existsSync).mockReturnValue(false);\n\n expect(isInstalledViaBrew()).toBe(false);\n });\n\n it(\"should return false when brew --prefix throws\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockImplementation(() => {\n throw new Error(\"aptos not installed\");\n });\n\n expect(isInstalledViaBrew()).toBe(false);\n });\n });\n\n describe(\"getCliPathBrew\", () => {\n it(\"should return the correct path\", () => {\n vi.mocked(execSync).mockReturnValue(\"/opt/homebrew/Cellar/aptos\\n\");\n\n expect(getCliPathBrew()).toBe(\"/opt/homebrew/Cellar/aptos/bin/aptos\");\n });\n });\n\n describe(\"installViaBrew\", () => {\n it(\"should call brew install aptos\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n installViaBrew();\n\n expect(execSync).toHaveBeenCalledWith(\"brew install aptos\", {\n stdio: \"inherit\",\n });\n });\n });\n\n describe(\"updateViaBrew\", () => {\n it(\"should call brew upgrade aptos\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n updateViaBrew();\n\n expect(execSync).toHaveBeenCalledWith(\"brew upgrade aptos\", {\n stdio: \"inherit\",\n });\n });\n });\n});\n"]}
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("os", async () => {
const actual = await vi.importActual("os");
return {
...actual,
platform: vi.fn(),
arch: vi.fn(),
};
});
vi.mock("fs", async () => {
const actual = await vi.importActual("fs");
return {
...actual,
existsSync: vi.fn(),
readFileSync: vi.fn(),
};
});
import { existsSync, readFileSync } from "node:fs";
import { arch, platform } from "node:os";
import { getOS, getPlatformInfo, getTargetPlatform } from "./getUserOs.js";
describe("getUserOs", () => {
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("getPlatformInfo", () => {
it("should detect macOS x86_64", () => {
vi.mocked(platform).mockReturnValue("darwin");
vi.mocked(arch).mockReturnValue("x64");
const result = getPlatformInfo();
expect(result).toEqual({ os: "macos", arch: "x86_64" });
});
it("should detect macOS ARM64", () => {
vi.mocked(platform).mockReturnValue("darwin");
vi.mocked(arch).mockReturnValue("arm64");
const result = getPlatformInfo();
expect(result).toEqual({ os: "macos", arch: "aarch64" });
});
it("should detect Linux x86_64", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
const result = getPlatformInfo();
expect(result).toEqual({ os: "linux", arch: "x86_64" });
});
it("should detect Linux ARM64", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("arm64");
const result = getPlatformInfo();
expect(result).toEqual({ os: "linux", arch: "aarch64" });
});
it("should detect Windows x86_64", () => {
vi.mocked(platform).mockReturnValue("win32");
vi.mocked(arch).mockReturnValue("x64");
const result = getPlatformInfo();
expect(result).toEqual({ os: "windows", arch: "x86_64" });
});
it("should throw for unsupported OS", () => {
vi.mocked(platform).mockReturnValue("freebsd");
vi.mocked(arch).mockReturnValue("x64");
expect(() => getPlatformInfo()).toThrow("Unsupported operating system");
});
it("should throw for unsupported architecture", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("mips");
expect(() => getPlatformInfo()).toThrow("Unsupported architecture");
});
});
describe("getTargetPlatform", () => {
it("should return macos-x86_64 for Intel Mac", () => {
vi.mocked(platform).mockReturnValue("darwin");
vi.mocked(arch).mockReturnValue("x64");
expect(getTargetPlatform()).toBe("macos-x86_64");
});
it("should return macos-arm64 for Apple Silicon Mac", () => {
vi.mocked(platform).mockReturnValue("darwin");
vi.mocked(arch).mockReturnValue("arm64");
expect(getTargetPlatform()).toBe("macos-arm64");
});
it("should return Ubuntu-24.04-x86_64 for Ubuntu 24.04", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
vi.mocked(existsSync).mockReturnValue(true);
vi.mocked(readFileSync).mockReturnValue('ID=ubuntu\nVERSION_ID="24.04"\n');
expect(getTargetPlatform()).toBe("Ubuntu-24.04-x86_64");
});
it("should return Ubuntu-22.04-x86_64 for Ubuntu 22.04", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
vi.mocked(existsSync).mockReturnValue(true);
vi.mocked(readFileSync).mockReturnValue('ID=ubuntu\nVERSION_ID="22.04"\n');
expect(getTargetPlatform()).toBe("Ubuntu-22.04-x86_64");
});
it("should return Linux-x86_64 for non-Ubuntu Linux", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
vi.mocked(existsSync).mockReturnValue(true);
vi.mocked(readFileSync).mockReturnValue('ID=fedora\nVERSION_ID="39"\n');
expect(getTargetPlatform()).toBe("Linux-x86_64");
});
it("should return Linux-x86_64 when /etc/os-release doesn't exist", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
vi.mocked(existsSync).mockReturnValue(false);
expect(getTargetPlatform()).toBe("Linux-x86_64");
});
it("should return Linux-aarch64 for ARM64 Linux", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("arm64");
vi.mocked(existsSync).mockReturnValue(false);
expect(getTargetPlatform()).toBe("Linux-aarch64");
});
it("should return Windows-x86_64 for Windows", () => {
vi.mocked(platform).mockReturnValue("win32");
vi.mocked(arch).mockReturnValue("x64");
expect(getTargetPlatform()).toBe("Windows-x86_64");
});
it("should throw for Windows ARM64", () => {
vi.mocked(platform).mockReturnValue("win32");
vi.mocked(arch).mockReturnValue("arm64");
expect(() => getTargetPlatform()).toThrow("Windows ARM64 is not currently supported");
});
});
describe("getOS", () => {
it("should return MacOS for darwin", () => {
vi.mocked(platform).mockReturnValue("darwin");
vi.mocked(arch).mockReturnValue("x64");
expect(getOS()).toBe("MacOS");
});
it("should return Linux for linux", () => {
vi.mocked(platform).mockReturnValue("linux");
vi.mocked(arch).mockReturnValue("x64");
expect(getOS()).toBe("Linux");
});
it("should return Windows for win32", () => {
vi.mocked(platform).mockReturnValue("win32");
vi.mocked(arch).mockReturnValue("x64");
expect(getOS()).toBe("Windows");
});
});
});
//# sourceMappingURL=getUserOs.test.js.map
{"version":3,"file":"getUserOs.test.js","sourceRoot":"","sources":["../../bin/utils/getUserOs.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as os from \"node:os\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\n// We need to mock the os module before importing the module under test\nvi.mock(\"os\", async () => {\n const actual = await vi.importActual<typeof os>(\"os\");\n return {\n ...actual,\n platform: vi.fn(),\n arch: vi.fn(),\n };\n});\n\n// We need to mock fs for the Linux distro detection\nvi.mock(\"fs\", async () => {\n const actual = await vi.importActual<typeof import(\"fs\")>(\"fs\");\n return {\n ...actual,\n existsSync: vi.fn(),\n readFileSync: vi.fn(),\n };\n});\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { arch, platform } from \"node:os\";\nimport { getOS, getPlatformInfo, getTargetPlatform } from \"./getUserOs.js\";\n\ndescribe(\"getUserOs\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe(\"getPlatformInfo\", () => {\n it(\"should detect macOS x86_64\", () => {\n vi.mocked(platform).mockReturnValue(\"darwin\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n const result = getPlatformInfo();\n expect(result).toEqual({ os: \"macos\", arch: \"x86_64\" });\n });\n\n it(\"should detect macOS ARM64\", () => {\n vi.mocked(platform).mockReturnValue(\"darwin\");\n vi.mocked(arch).mockReturnValue(\"arm64\");\n\n const result = getPlatformInfo();\n expect(result).toEqual({ os: \"macos\", arch: \"aarch64\" });\n });\n\n it(\"should detect Linux x86_64\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n const result = getPlatformInfo();\n expect(result).toEqual({ os: \"linux\", arch: \"x86_64\" });\n });\n\n it(\"should detect Linux ARM64\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"arm64\");\n\n const result = getPlatformInfo();\n expect(result).toEqual({ os: \"linux\", arch: \"aarch64\" });\n });\n\n it(\"should detect Windows x86_64\", () => {\n vi.mocked(platform).mockReturnValue(\"win32\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n const result = getPlatformInfo();\n expect(result).toEqual({ os: \"windows\", arch: \"x86_64\" });\n });\n\n it(\"should throw for unsupported OS\", () => {\n vi.mocked(platform).mockReturnValue(\"freebsd\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(() => getPlatformInfo()).toThrow(\"Unsupported operating system\");\n });\n\n it(\"should throw for unsupported architecture\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"mips\");\n\n expect(() => getPlatformInfo()).toThrow(\"Unsupported architecture\");\n });\n });\n\n describe(\"getTargetPlatform\", () => {\n it(\"should return macos-x86_64 for Intel Mac\", () => {\n vi.mocked(platform).mockReturnValue(\"darwin\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(getTargetPlatform()).toBe(\"macos-x86_64\");\n });\n\n it(\"should return macos-arm64 for Apple Silicon Mac\", () => {\n vi.mocked(platform).mockReturnValue(\"darwin\");\n vi.mocked(arch).mockReturnValue(\"arm64\");\n\n expect(getTargetPlatform()).toBe(\"macos-arm64\");\n });\n\n it(\"should return Ubuntu-24.04-x86_64 for Ubuntu 24.04\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n vi.mocked(existsSync).mockReturnValue(true);\n vi.mocked(readFileSync).mockReturnValue(\n 'ID=ubuntu\\nVERSION_ID=\"24.04\"\\n',\n );\n\n expect(getTargetPlatform()).toBe(\"Ubuntu-24.04-x86_64\");\n });\n\n it(\"should return Ubuntu-22.04-x86_64 for Ubuntu 22.04\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n vi.mocked(existsSync).mockReturnValue(true);\n vi.mocked(readFileSync).mockReturnValue(\n 'ID=ubuntu\\nVERSION_ID=\"22.04\"\\n',\n );\n\n expect(getTargetPlatform()).toBe(\"Ubuntu-22.04-x86_64\");\n });\n\n it(\"should return Linux-x86_64 for non-Ubuntu Linux\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n vi.mocked(existsSync).mockReturnValue(true);\n vi.mocked(readFileSync).mockReturnValue('ID=fedora\\nVERSION_ID=\"39\"\\n');\n\n expect(getTargetPlatform()).toBe(\"Linux-x86_64\");\n });\n\n it(\"should return Linux-x86_64 when /etc/os-release doesn't exist\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n vi.mocked(existsSync).mockReturnValue(false);\n\n expect(getTargetPlatform()).toBe(\"Linux-x86_64\");\n });\n\n it(\"should return Linux-aarch64 for ARM64 Linux\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"arm64\");\n vi.mocked(existsSync).mockReturnValue(false);\n\n expect(getTargetPlatform()).toBe(\"Linux-aarch64\");\n });\n\n it(\"should return Windows-x86_64 for Windows\", () => {\n vi.mocked(platform).mockReturnValue(\"win32\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(getTargetPlatform()).toBe(\"Windows-x86_64\");\n });\n\n it(\"should throw for Windows ARM64\", () => {\n vi.mocked(platform).mockReturnValue(\"win32\");\n vi.mocked(arch).mockReturnValue(\"arm64\");\n\n expect(() => getTargetPlatform()).toThrow(\n \"Windows ARM64 is not currently supported\",\n );\n });\n });\n\n describe(\"getOS\", () => {\n it(\"should return MacOS for darwin\", () => {\n vi.mocked(platform).mockReturnValue(\"darwin\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(getOS()).toBe(\"MacOS\");\n });\n\n it(\"should return Linux for linux\", () => {\n vi.mocked(platform).mockReturnValue(\"linux\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(getOS()).toBe(\"Linux\");\n });\n\n it(\"should return Windows for win32\", () => {\n vi.mocked(platform).mockReturnValue(\"win32\");\n vi.mocked(arch).mockReturnValue(\"x64\");\n\n expect(getOS()).toBe(\"Windows\");\n });\n });\n});\n"]}
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mockFetch = vi.fn();
global.fetch = mockFetch;
import { getCliVersion, getLatestVersionGh, getUserSpecifiedVersion, hasUserSpecifiedVersion, validateVersionExists, } from "./ghOperations.js";
describe("ghOperations", () => {
beforeEach(() => {
vi.clearAllMocks();
delete process.env.GITHUB_TOKEN;
delete process.env.APTOS_CLI_VERSION;
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("getLatestVersionGh", () => {
it("should return the latest version", async () => {
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve([
{ tag_name: "aptos-cli-v1.2.3" },
{ tag_name: "aptos-cli-v1.2.2" },
]),
});
const version = await getLatestVersionGh();
expect(version).toBe("1.2.3");
expect(mockFetch).toHaveBeenCalledWith("https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100", expect.objectContaining({
headers: expect.objectContaining({
Accept: "application/vnd.github.v3+json",
"User-Agent": "aptos-cli-npm",
}),
}));
});
it("should use GITHUB_TOKEN when available", async () => {
process.env.GITHUB_TOKEN = "test-token";
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve([{ tag_name: "aptos-cli-v1.0.0" }]),
});
await getLatestVersionGh();
expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer test-token",
}),
}));
});
it("should skip non-CLI releases", async () => {
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve([
{ tag_name: "other-release-v2.0.0" },
{ tag_name: "aptos-cli-v1.5.0" },
]),
});
const version = await getLatestVersionGh();
expect(version).toBe("1.5.0");
});
it("should throw on rate limit (403)", async () => {
mockFetch.mockResolvedValue({
ok: false,
status: 403,
statusText: "Forbidden",
});
await expect(getLatestVersionGh()).rejects.toThrow("GitHub API rate limit exceeded");
});
it("should throw on rate limit (429)", async () => {
mockFetch.mockResolvedValue({
ok: false,
status: 429,
statusText: "Too Many Requests",
});
await expect(getLatestVersionGh()).rejects.toThrow("GitHub API rate limit exceeded");
});
it("should throw on other HTTP errors", async () => {
mockFetch.mockResolvedValue({
ok: false,
status: 500,
statusText: "Internal Server Error",
});
await expect(getLatestVersionGh()).rejects.toThrow("GitHub API request failed with status 500");
});
it("should throw on network error", async () => {
mockFetch.mockRejectedValue(new Error("Network error"));
await expect(getLatestVersionGh()).rejects.toThrow("Failed to fetch releases from GitHub");
});
it("should throw when no CLI release found", async () => {
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve([
{ tag_name: "other-release-v1.0.0" },
{ tag_name: "another-release-v2.0.0" },
]),
});
await expect(getLatestVersionGh()).rejects.toThrow("Could not determine latest version of Aptos CLI");
});
it("should throw on invalid JSON response", async () => {
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.reject(new Error("Invalid JSON")),
});
await expect(getLatestVersionGh()).rejects.toThrow("Failed to parse GitHub API response");
});
it("should throw when response is not an array", async () => {
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve({ message: "not an array" }),
});
await expect(getLatestVersionGh()).rejects.toThrow("Unexpected response format");
});
});
describe("getUserSpecifiedVersion", () => {
it("should return undefined when APTOS_CLI_VERSION is not set", () => {
delete process.env.APTOS_CLI_VERSION;
expect(getUserSpecifiedVersion()).toBeUndefined();
});
it("should return the version when APTOS_CLI_VERSION is set", () => {
process.env.APTOS_CLI_VERSION = "1.2.3";
expect(getUserSpecifiedVersion()).toBe("1.2.3");
});
it("should strip v prefix from version", () => {
process.env.APTOS_CLI_VERSION = "v1.2.3";
expect(getUserSpecifiedVersion()).toBe("1.2.3");
});
it("should handle version without v prefix", () => {
process.env.APTOS_CLI_VERSION = "2.0.0";
expect(getUserSpecifiedVersion()).toBe("2.0.0");
});
it("should accept pre-release versions", () => {
process.env.APTOS_CLI_VERSION = "v1.2.3-rc.1";
expect(getUserSpecifiedVersion()).toBe("1.2.3-rc.1");
});
it("should reject invalid version strings", () => {
process.env.APTOS_CLI_VERSION = "not-a-version";
expect(() => getUserSpecifiedVersion()).toThrow("Invalid APTOS_CLI_VERSION");
});
it("should reject version with shell metacharacters", () => {
process.env.APTOS_CLI_VERSION = '1.0.0"; rm -rf /; echo "';
expect(() => getUserSpecifiedVersion()).toThrow("Invalid APTOS_CLI_VERSION");
});
});
describe("hasUserSpecifiedVersion", () => {
it("should return false when APTOS_CLI_VERSION is not set", () => {
delete process.env.APTOS_CLI_VERSION;
expect(hasUserSpecifiedVersion()).toBe(false);
});
it("should return true when APTOS_CLI_VERSION is set", () => {
process.env.APTOS_CLI_VERSION = "1.0.0";
expect(hasUserSpecifiedVersion()).toBe(true);
});
it("should return false when APTOS_CLI_VERSION is empty string", () => {
process.env.APTOS_CLI_VERSION = "";
expect(hasUserSpecifiedVersion()).toBe(false);
});
});
describe("validateVersionExists", () => {
it("should return true when version exists", async () => {
mockFetch.mockResolvedValue({ ok: true });
const result = await validateVersionExists("1.0.0", "Linux-x86_64");
expect(result).toBe(true);
expect(mockFetch).toHaveBeenCalledWith("https://github.com/aptos-labs/aptos-core/releases/download/aptos-cli-v1.0.0/aptos-cli-1.0.0-Linux-x86_64.zip", expect.objectContaining({ method: "HEAD" }));
});
it("should return false when version does not exist", async () => {
mockFetch.mockResolvedValue({ ok: false });
const result = await validateVersionExists("99.99.99", "Linux-x86_64");
expect(result).toBe(false);
});
it("should return false on network error", async () => {
mockFetch.mockRejectedValue(new Error("Network error"));
const result = await validateVersionExists("1.0.0", "Linux-x86_64");
expect(result).toBe(false);
});
it("should use GITHUB_TOKEN when available", async () => {
process.env.GITHUB_TOKEN = "test-token";
mockFetch.mockResolvedValue({ ok: true });
await validateVersionExists("1.0.0", "Linux-x86_64");
expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer test-token",
}),
}));
});
});
describe("getCliVersion", () => {
it("should return latest version when APTOS_CLI_VERSION is not set", async () => {
delete process.env.APTOS_CLI_VERSION;
mockFetch.mockResolvedValue({
ok: true,
json: () => Promise.resolve([{ tag_name: "aptos-cli-v2.0.0" }]),
});
const version = await getCliVersion();
expect(version).toBe("2.0.0");
});
it("should return user-specified version when APTOS_CLI_VERSION is set", async () => {
process.env.APTOS_CLI_VERSION = "1.5.0";
const version = await getCliVersion();
expect(version).toBe("1.5.0");
expect(mockFetch).not.toHaveBeenCalled();
});
it("should validate version when targetPlatform is provided", async () => {
process.env.APTOS_CLI_VERSION = "1.5.0";
mockFetch.mockResolvedValue({ ok: true });
const version = await getCliVersion("Linux-x86_64");
expect(version).toBe("1.5.0");
expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining("1.5.0"), expect.objectContaining({ method: "HEAD" }));
});
it("should throw error when specified version does not exist", async () => {
process.env.APTOS_CLI_VERSION = "99.99.99";
mockFetch.mockResolvedValue({ ok: false });
await expect(getCliVersion("Linux-x86_64")).rejects.toThrow("Specified version 99.99.99 does not exist");
});
it("should strip v prefix and validate version", async () => {
process.env.APTOS_CLI_VERSION = "v1.5.0";
mockFetch.mockResolvedValue({ ok: true });
const version = await getCliVersion("Linux-x86_64");
expect(version).toBe("1.5.0");
});
});
});
//# sourceMappingURL=ghOperations.test.js.map
{"version":3,"file":"ghOperations.test.js","sourceRoot":"","sources":["../../bin/utils/ghOperations.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\n// Mock global fetch\nconst mockFetch = vi.fn();\nglobal.fetch = mockFetch;\n\nimport {\n getCliVersion,\n getLatestVersionGh,\n getUserSpecifiedVersion,\n hasUserSpecifiedVersion,\n validateVersionExists,\n} from \"./ghOperations.js\";\n\ndescribe(\"ghOperations\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n delete process.env.GITHUB_TOKEN;\n delete process.env.APTOS_CLI_VERSION;\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe(\"getLatestVersionGh\", () => {\n it(\"should return the latest version\", async () => {\n mockFetch.mockResolvedValue({\n ok: true,\n json: () =>\n Promise.resolve([\n { tag_name: \"aptos-cli-v1.2.3\" },\n { tag_name: \"aptos-cli-v1.2.2\" },\n ]),\n });\n\n const version = await getLatestVersionGh();\n\n expect(version).toBe(\"1.2.3\");\n expect(mockFetch).toHaveBeenCalledWith(\n \"https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100\",\n expect.objectContaining({\n headers: expect.objectContaining({\n Accept: \"application/vnd.github.v3+json\",\n \"User-Agent\": \"aptos-cli-npm\",\n }),\n }),\n );\n });\n\n it(\"should use GITHUB_TOKEN when available\", async () => {\n process.env.GITHUB_TOKEN = \"test-token\";\n\n mockFetch.mockResolvedValue({\n ok: true,\n json: () => Promise.resolve([{ tag_name: \"aptos-cli-v1.0.0\" }]),\n });\n\n await getLatestVersionGh();\n\n expect(mockFetch).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n Authorization: \"Bearer test-token\",\n }),\n }),\n );\n });\n\n it(\"should skip non-CLI releases\", async () => {\n mockFetch.mockResolvedValue({\n ok: true,\n json: () =>\n Promise.resolve([\n { tag_name: \"other-release-v2.0.0\" },\n { tag_name: \"aptos-cli-v1.5.0\" },\n ]),\n });\n\n const version = await getLatestVersionGh();\n\n expect(version).toBe(\"1.5.0\");\n });\n\n it(\"should throw on rate limit (403)\", async () => {\n mockFetch.mockResolvedValue({\n ok: false,\n status: 403,\n statusText: \"Forbidden\",\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"GitHub API rate limit exceeded\",\n );\n });\n\n it(\"should throw on rate limit (429)\", async () => {\n mockFetch.mockResolvedValue({\n ok: false,\n status: 429,\n statusText: \"Too Many Requests\",\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"GitHub API rate limit exceeded\",\n );\n });\n\n it(\"should throw on other HTTP errors\", async () => {\n mockFetch.mockResolvedValue({\n ok: false,\n status: 500,\n statusText: \"Internal Server Error\",\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"GitHub API request failed with status 500\",\n );\n });\n\n it(\"should throw on network error\", async () => {\n mockFetch.mockRejectedValue(new Error(\"Network error\"));\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"Failed to fetch releases from GitHub\",\n );\n });\n\n it(\"should throw when no CLI release found\", async () => {\n mockFetch.mockResolvedValue({\n ok: true,\n json: () =>\n Promise.resolve([\n { tag_name: \"other-release-v1.0.0\" },\n { tag_name: \"another-release-v2.0.0\" },\n ]),\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"Could not determine latest version of Aptos CLI\",\n );\n });\n\n it(\"should throw on invalid JSON response\", async () => {\n mockFetch.mockResolvedValue({\n ok: true,\n json: () => Promise.reject(new Error(\"Invalid JSON\")),\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"Failed to parse GitHub API response\",\n );\n });\n\n it(\"should throw when response is not an array\", async () => {\n mockFetch.mockResolvedValue({\n ok: true,\n json: () => Promise.resolve({ message: \"not an array\" }),\n });\n\n await expect(getLatestVersionGh()).rejects.toThrow(\n \"Unexpected response format\",\n );\n });\n });\n\n describe(\"getUserSpecifiedVersion\", () => {\n it(\"should return undefined when APTOS_CLI_VERSION is not set\", () => {\n delete process.env.APTOS_CLI_VERSION;\n expect(getUserSpecifiedVersion()).toBeUndefined();\n });\n\n it(\"should return the version when APTOS_CLI_VERSION is set\", () => {\n process.env.APTOS_CLI_VERSION = \"1.2.3\";\n expect(getUserSpecifiedVersion()).toBe(\"1.2.3\");\n });\n\n it(\"should strip v prefix from version\", () => {\n process.env.APTOS_CLI_VERSION = \"v1.2.3\";\n expect(getUserSpecifiedVersion()).toBe(\"1.2.3\");\n });\n\n it(\"should handle version without v prefix\", () => {\n process.env.APTOS_CLI_VERSION = \"2.0.0\";\n expect(getUserSpecifiedVersion()).toBe(\"2.0.0\");\n });\n\n it(\"should accept pre-release versions\", () => {\n process.env.APTOS_CLI_VERSION = \"v1.2.3-rc.1\";\n expect(getUserSpecifiedVersion()).toBe(\"1.2.3-rc.1\");\n });\n\n it(\"should reject invalid version strings\", () => {\n process.env.APTOS_CLI_VERSION = \"not-a-version\";\n expect(() => getUserSpecifiedVersion()).toThrow(\n \"Invalid APTOS_CLI_VERSION\",\n );\n });\n\n it(\"should reject version with shell metacharacters\", () => {\n process.env.APTOS_CLI_VERSION = '1.0.0\"; rm -rf /; echo \"';\n expect(() => getUserSpecifiedVersion()).toThrow(\n \"Invalid APTOS_CLI_VERSION\",\n );\n });\n });\n\n describe(\"hasUserSpecifiedVersion\", () => {\n it(\"should return false when APTOS_CLI_VERSION is not set\", () => {\n delete process.env.APTOS_CLI_VERSION;\n expect(hasUserSpecifiedVersion()).toBe(false);\n });\n\n it(\"should return true when APTOS_CLI_VERSION is set\", () => {\n process.env.APTOS_CLI_VERSION = \"1.0.0\";\n expect(hasUserSpecifiedVersion()).toBe(true);\n });\n\n it(\"should return false when APTOS_CLI_VERSION is empty string\", () => {\n process.env.APTOS_CLI_VERSION = \"\";\n expect(hasUserSpecifiedVersion()).toBe(false);\n });\n });\n\n describe(\"validateVersionExists\", () => {\n it(\"should return true when version exists\", async () => {\n mockFetch.mockResolvedValue({ ok: true });\n\n const result = await validateVersionExists(\"1.0.0\", \"Linux-x86_64\");\n\n expect(result).toBe(true);\n expect(mockFetch).toHaveBeenCalledWith(\n \"https://github.com/aptos-labs/aptos-core/releases/download/aptos-cli-v1.0.0/aptos-cli-1.0.0-Linux-x86_64.zip\",\n expect.objectContaining({ method: \"HEAD\" }),\n );\n });\n\n it(\"should return false when version does not exist\", async () => {\n mockFetch.mockResolvedValue({ ok: false });\n\n const result = await validateVersionExists(\"99.99.99\", \"Linux-x86_64\");\n\n expect(result).toBe(false);\n });\n\n it(\"should return false on network error\", async () => {\n mockFetch.mockRejectedValue(new Error(\"Network error\"));\n\n const result = await validateVersionExists(\"1.0.0\", \"Linux-x86_64\");\n\n expect(result).toBe(false);\n });\n\n it(\"should use GITHUB_TOKEN when available\", async () => {\n process.env.GITHUB_TOKEN = \"test-token\";\n mockFetch.mockResolvedValue({ ok: true });\n\n await validateVersionExists(\"1.0.0\", \"Linux-x86_64\");\n\n expect(mockFetch).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n Authorization: \"Bearer test-token\",\n }),\n }),\n );\n });\n });\n\n describe(\"getCliVersion\", () => {\n it(\"should return latest version when APTOS_CLI_VERSION is not set\", async () => {\n delete process.env.APTOS_CLI_VERSION;\n mockFetch.mockResolvedValue({\n ok: true,\n json: () => Promise.resolve([{ tag_name: \"aptos-cli-v2.0.0\" }]),\n });\n\n const version = await getCliVersion();\n\n expect(version).toBe(\"2.0.0\");\n });\n\n it(\"should return user-specified version when APTOS_CLI_VERSION is set\", async () => {\n process.env.APTOS_CLI_VERSION = \"1.5.0\";\n // Don't validate when no targetPlatform is provided\n const version = await getCliVersion();\n\n expect(version).toBe(\"1.5.0\");\n // Should not call fetch for releases API\n expect(mockFetch).not.toHaveBeenCalled();\n });\n\n it(\"should validate version when targetPlatform is provided\", async () => {\n process.env.APTOS_CLI_VERSION = \"1.5.0\";\n mockFetch.mockResolvedValue({ ok: true });\n\n const version = await getCliVersion(\"Linux-x86_64\");\n\n expect(version).toBe(\"1.5.0\");\n expect(mockFetch).toHaveBeenCalledWith(\n expect.stringContaining(\"1.5.0\"),\n expect.objectContaining({ method: \"HEAD\" }),\n );\n });\n\n it(\"should throw error when specified version does not exist\", async () => {\n process.env.APTOS_CLI_VERSION = \"99.99.99\";\n mockFetch.mockResolvedValue({ ok: false });\n\n await expect(getCliVersion(\"Linux-x86_64\")).rejects.toThrow(\n \"Specified version 99.99.99 does not exist\",\n );\n });\n\n it(\"should strip v prefix and validate version\", async () => {\n process.env.APTOS_CLI_VERSION = \"v1.5.0\";\n mockFetch.mockResolvedValue({ ok: true });\n\n const version = await getCliVersion(\"Linux-x86_64\");\n\n expect(version).toBe(\"1.5.0\");\n });\n });\n});\n"]}
import { execSync } from "node:child_process";
import { existsSync } from "node:fs";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("child_process", () => ({
execSync: vi.fn(),
}));
vi.mock("fs", () => ({
existsSync: vi.fn(),
}));
vi.mock("./executableIsAvailable.js", () => ({
executableIsAvailable: vi.fn(),
}));
import { executableIsAvailable } from "./executableIsAvailable.js";
import { detectWindowsPackageManager, getCliPathChoco, getCliPathWinget, installViaChoco, installViaWinget, isChocoAvailable, isInstalledViaChoco, isInstalledViaWinget, isWingetAvailable, updateViaChoco, updateViaWinget, } from "./windowsPackageManagers.js";
describe("windowsPackageManagers", () => {
beforeEach(() => {
vi.clearAllMocks();
process.env.LOCALAPPDATA = "C:\\Users\\Test\\AppData\\Local";
process.env.PROGRAMFILES = "C:\\Program Files";
process.env.ChocolateyInstall = "C:\\ProgramData\\chocolatey";
});
afterEach(() => {
vi.restoreAllMocks();
});
describe("isWingetAvailable", () => {
it("should return true when winget is available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
expect(isWingetAvailable()).toBe(true);
expect(executableIsAvailable).toHaveBeenCalledWith("winget");
});
it("should return false when winget is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isWingetAvailable()).toBe(false);
});
});
describe("isChocoAvailable", () => {
it("should return true when choco is available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
expect(isChocoAvailable()).toBe(true);
expect(executableIsAvailable).toHaveBeenCalledWith("choco");
});
it("should return false when choco is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isChocoAvailable()).toBe(false);
});
});
describe("isInstalledViaWinget", () => {
it("should return true when aptos is installed via winget", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("Aptos.Aptos 1.0.0");
expect(isInstalledViaWinget()).toBe(true);
});
it("should return false when winget is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isInstalledViaWinget()).toBe(false);
});
it("should return false when aptos is not in winget list", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("No packages found");
expect(isInstalledViaWinget()).toBe(false);
});
it("should return false when winget list throws", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockImplementation(() => {
throw new Error("winget error");
});
expect(isInstalledViaWinget()).toBe(false);
});
});
describe("isInstalledViaChoco", () => {
it("should return true when aptos is installed via choco", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("aptos 1.0.0");
expect(isInstalledViaChoco()).toBe(true);
});
it("should return false when choco is not available", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(isInstalledViaChoco()).toBe(false);
});
it("should return false when aptos is not in choco list", () => {
vi.mocked(executableIsAvailable).mockReturnValue(true);
vi.mocked(execSync).mockReturnValue("0 packages installed");
expect(isInstalledViaChoco()).toBe(false);
});
});
describe("getCliPathWinget", () => {
it("should return path when found via where command", () => {
vi.mocked(existsSync).mockImplementation((path) => {
return path === "C:\\found\\aptos.exe";
});
vi.mocked(execSync).mockReturnValue("C:\\found\\aptos.exe\n");
expect(getCliPathWinget()).toBe("C:\\found\\aptos.exe");
});
it("should return null when not found", () => {
vi.mocked(existsSync).mockReturnValue(false);
vi.mocked(execSync).mockImplementation(() => {
throw new Error("not found");
});
expect(getCliPathWinget()).toBeNull();
});
});
describe("getCliPathChoco", () => {
it("should return path when exists", () => {
vi.mocked(existsSync).mockReturnValue(true);
expect(getCliPathChoco()).toBe("C:\\ProgramData\\chocolatey\\bin\\aptos.exe");
});
it("should return null when not found", () => {
vi.mocked(existsSync).mockReturnValue(false);
expect(getCliPathChoco()).toBeNull();
});
});
describe("installViaWinget", () => {
it("should call winget install", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
installViaWinget();
expect(execSync).toHaveBeenCalledWith("winget install --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements", { stdio: "inherit" });
});
});
describe("installViaChoco", () => {
it("should call choco install", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
installViaChoco();
expect(execSync).toHaveBeenCalledWith("choco install aptos -y", {
stdio: "inherit",
});
});
});
describe("updateViaWinget", () => {
it("should call winget upgrade", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
updateViaWinget();
expect(execSync).toHaveBeenCalledWith("winget upgrade --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements", { stdio: "inherit" });
});
});
describe("updateViaChoco", () => {
it("should call choco upgrade", () => {
vi.mocked(execSync).mockReturnValue(Buffer.from(""));
updateViaChoco();
expect(execSync).toHaveBeenCalledWith("choco upgrade aptos -y", {
stdio: "inherit",
});
});
});
describe("detectWindowsPackageManager", () => {
it("should return winget when installed via winget", () => {
vi.mocked(executableIsAvailable).mockImplementation((name) => {
return name === "winget";
});
vi.mocked(execSync).mockReturnValue("Aptos.Aptos 1.0.0");
expect(detectWindowsPackageManager()).toBe("winget");
});
it("should return choco when installed via choco", () => {
vi.mocked(executableIsAvailable).mockImplementation((name) => {
if (name === "winget")
return false;
if (name === "choco")
return true;
return false;
});
vi.mocked(execSync).mockReturnValue("aptos 1.0.0");
expect(detectWindowsPackageManager()).toBe("choco");
});
it("should return null when not installed via package manager", () => {
vi.mocked(executableIsAvailable).mockReturnValue(false);
expect(detectWindowsPackageManager()).toBeNull();
});
});
});
//# sourceMappingURL=windowsPackageManagers.test.js.map
{"version":3,"file":"windowsPackageManagers.test.js","sourceRoot":"","sources":["../../bin/utils/windowsPackageManagers.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\n\nvi.mock(\"child_process\", () => ({\n execSync: vi.fn(),\n}));\n\nvi.mock(\"fs\", () => ({\n existsSync: vi.fn(),\n}));\n\nvi.mock(\"./executableIsAvailable.js\", () => ({\n executableIsAvailable: vi.fn(),\n}));\n\nimport { executableIsAvailable } from \"./executableIsAvailable.js\";\nimport {\n detectWindowsPackageManager,\n getCliPathChoco,\n getCliPathWinget,\n installViaChoco,\n installViaWinget,\n isChocoAvailable,\n isInstalledViaChoco,\n isInstalledViaWinget,\n isWingetAvailable,\n updateViaChoco,\n updateViaWinget,\n} from \"./windowsPackageManagers.js\";\n\ndescribe(\"windowsPackageManagers\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n // Set up default environment variables\n process.env.LOCALAPPDATA = \"C:\\\\Users\\\\Test\\\\AppData\\\\Local\";\n process.env.PROGRAMFILES = \"C:\\\\Program Files\";\n process.env.ChocolateyInstall = \"C:\\\\ProgramData\\\\chocolatey\";\n });\n\n afterEach(() => {\n vi.restoreAllMocks();\n });\n\n describe(\"isWingetAvailable\", () => {\n it(\"should return true when winget is available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n\n expect(isWingetAvailable()).toBe(true);\n expect(executableIsAvailable).toHaveBeenCalledWith(\"winget\");\n });\n\n it(\"should return false when winget is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isWingetAvailable()).toBe(false);\n });\n });\n\n describe(\"isChocoAvailable\", () => {\n it(\"should return true when choco is available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n\n expect(isChocoAvailable()).toBe(true);\n expect(executableIsAvailable).toHaveBeenCalledWith(\"choco\");\n });\n\n it(\"should return false when choco is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isChocoAvailable()).toBe(false);\n });\n });\n\n describe(\"isInstalledViaWinget\", () => {\n it(\"should return true when aptos is installed via winget\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"Aptos.Aptos 1.0.0\");\n\n expect(isInstalledViaWinget()).toBe(true);\n });\n\n it(\"should return false when winget is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isInstalledViaWinget()).toBe(false);\n });\n\n it(\"should return false when aptos is not in winget list\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"No packages found\");\n\n expect(isInstalledViaWinget()).toBe(false);\n });\n\n it(\"should return false when winget list throws\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockImplementation(() => {\n throw new Error(\"winget error\");\n });\n\n expect(isInstalledViaWinget()).toBe(false);\n });\n });\n\n describe(\"isInstalledViaChoco\", () => {\n it(\"should return true when aptos is installed via choco\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"aptos 1.0.0\");\n\n expect(isInstalledViaChoco()).toBe(true);\n });\n\n it(\"should return false when choco is not available\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(isInstalledViaChoco()).toBe(false);\n });\n\n it(\"should return false when aptos is not in choco list\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(true);\n vi.mocked(execSync).mockReturnValue(\"0 packages installed\");\n\n expect(isInstalledViaChoco()).toBe(false);\n });\n });\n\n describe(\"getCliPathWinget\", () => {\n it(\"should return path when found via where command\", () => {\n vi.mocked(existsSync).mockImplementation((path) => {\n return path === \"C:\\\\found\\\\aptos.exe\";\n });\n vi.mocked(execSync).mockReturnValue(\"C:\\\\found\\\\aptos.exe\\n\");\n\n expect(getCliPathWinget()).toBe(\"C:\\\\found\\\\aptos.exe\");\n });\n\n it(\"should return null when not found\", () => {\n vi.mocked(existsSync).mockReturnValue(false);\n vi.mocked(execSync).mockImplementation(() => {\n throw new Error(\"not found\");\n });\n\n expect(getCliPathWinget()).toBeNull();\n });\n });\n\n describe(\"getCliPathChoco\", () => {\n it(\"should return path when exists\", () => {\n vi.mocked(existsSync).mockReturnValue(true);\n\n expect(getCliPathChoco()).toBe(\n \"C:\\\\ProgramData\\\\chocolatey\\\\bin\\\\aptos.exe\",\n );\n });\n\n it(\"should return null when not found\", () => {\n vi.mocked(existsSync).mockReturnValue(false);\n\n expect(getCliPathChoco()).toBeNull();\n });\n });\n\n describe(\"installViaWinget\", () => {\n it(\"should call winget install\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n installViaWinget();\n\n expect(execSync).toHaveBeenCalledWith(\n \"winget install --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n { stdio: \"inherit\" },\n );\n });\n });\n\n describe(\"installViaChoco\", () => {\n it(\"should call choco install\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n installViaChoco();\n\n expect(execSync).toHaveBeenCalledWith(\"choco install aptos -y\", {\n stdio: \"inherit\",\n });\n });\n });\n\n describe(\"updateViaWinget\", () => {\n it(\"should call winget upgrade\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n updateViaWinget();\n\n expect(execSync).toHaveBeenCalledWith(\n \"winget upgrade --id Aptos.Aptos --silent --accept-package-agreements --accept-source-agreements\",\n { stdio: \"inherit\" },\n );\n });\n });\n\n describe(\"updateViaChoco\", () => {\n it(\"should call choco upgrade\", () => {\n vi.mocked(execSync).mockReturnValue(Buffer.from(\"\"));\n\n updateViaChoco();\n\n expect(execSync).toHaveBeenCalledWith(\"choco upgrade aptos -y\", {\n stdio: \"inherit\",\n });\n });\n });\n\n describe(\"detectWindowsPackageManager\", () => {\n it(\"should return winget when installed via winget\", () => {\n vi.mocked(executableIsAvailable).mockImplementation((name) => {\n return name === \"winget\";\n });\n vi.mocked(execSync).mockReturnValue(\"Aptos.Aptos 1.0.0\");\n\n expect(detectWindowsPackageManager()).toBe(\"winget\");\n });\n\n it(\"should return choco when installed via choco\", () => {\n vi.mocked(executableIsAvailable).mockImplementation((name) => {\n if (name === \"winget\") return false;\n if (name === \"choco\") return true;\n return false;\n });\n vi.mocked(execSync).mockReturnValue(\"aptos 1.0.0\");\n\n expect(detectWindowsPackageManager()).toBe(\"choco\");\n });\n\n it(\"should return null when not installed via package manager\", () => {\n vi.mocked(executableIsAvailable).mockReturnValue(false);\n\n expect(detectWindowsPackageManager()).toBeNull();\n });\n });\n});\n"]}