@aptos-labs/aptos-cli
Advanced tools
+44
-17
@@ -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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3D,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,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,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;AAwB5C,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,iBAA0B,KAAK,EAChB,EAAE;IACjB,sBAAsB,EAAE,CAAC;IACzB,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IAInB,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,GAAG,GAAG,GAAG,mBAAmB,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,cAAc,MAAM,CAAC;IAEpG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;IAEzB,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YAErB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAC/C,QAAQ,CACN,uBAAuB;gBACrB,2BAA2B,GAAG,eAAe,OAAO,KAAK;gBACzD,yBAAyB,OAAO,uBAAuB,MAAM,YAAY;gBACzE,sBAAsB,OAAO,WAAW,EAC1C,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;QACJ,CAAC;aAAM,CAAC;YAEN,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAG/C,QAAQ,CAAC,eAAe,OAAO,MAAM,GAAG,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAGnE,QAAQ,CAAC,gBAAgB,OAAO,SAAS,OAAO,GAAG,EAAE;gBACnD,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAGH,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/C,QAAQ,CAAC,OAAO,eAAe,MAAM,UAAU,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAG1E,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAG7B,IAAI,CAAC;gBACH,QAAQ,CAAC,UAAU,OAAO,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACtD,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 { 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":"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","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":"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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 // 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":"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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 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":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAkBzD,MAAM,gBAAgB,GAAG,GAA2B,EAAE;IACpD,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,gCAAgC;QACxC,YAAY,EAAE,eAAe;KAC9B,CAAC;IAGF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACvC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAuB,EAAE;IAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,+BAA+B,OAAO,6DAA6D,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAY,EAAE;IACnD,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACzC,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,OAAe,EACf,cAAsB,EACJ,EAAE;IACpB,MAAM,GAAG,GAAG,GAAG,mBAAmB,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,cAAc,MAAM,CAAC;IAEpG,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gBAAgB,EAAE;SAC5B,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,cAAuB,EACN,EAAE;IACnB,MAAM,WAAW,GAAG,uBAAuB,EAAE,CAAC;IAE9C,IAAI,WAAW,EAAE,CAAC;QAEhB,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YACxE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,qBAAqB,WAAW,2CAA2C,cAAc,IAAI;oBAC3F,iFAAiF,CACpF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC,CAAC;AAQF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAqB,EAAE;IAC5D,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC;IAC5B,MAAM,GAAG,GACP,0EAA0E,CAAC;IAE7E,IAAI,QAAkB,CAAC;IACvB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,yCAAyC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClG,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yCAAyC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CACnF,CAAC;IACJ,CAAC;IAED,IAAI,QAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAC;AACJ,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,OAAe,EACf,SAAiB,EACO,EAAE;IAC1B,MAAM,GAAG,GAAG,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,oEAAoE,GAAG,EAAE,CAAC;IAEtF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAkB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC","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"]} |
+28
-12
| { | ||
| "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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGzE,MAAM,sBAAsB,GAAG,GAAG,EAAE;IAClC,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IACnC,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,IAAI,gBAA8B,CAAC;AAEnC,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC;CACrC,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;CACpB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;CAC7D,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,6BAA6B,CAAC;CAC5D,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAA4B,CAAC;IAEnD,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,gBAAgB,GAAG,sBAAsB,EAAE,CAAC;QAC5C,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE;YACvB,GAAG,OAAO;YACV,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;YAEpC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAChC,6BAA6B,EAC7B,CAAC,MAAM,EAAE,WAAW,CAAC,EACrB,MAAM,CAAC,gBAAgB,CAAC;gBACtB,KAAK,EAAE,SAAS;aACjB,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC;YAE7C,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAChC,oBAAoB,EACpB,CAAC,MAAM,CAAC,EACR,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CACnB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;YAC1F,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAGlC,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAEjC,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;YAG/B,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAElC,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACjF,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAGvB,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAEjC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;YACpF,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAGvB,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAEpC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;YAChF,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,EAAE;iBAClB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;iBACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEhC,MAAM,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAElD,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,oEAAoE,CACrE,CAAC;YACF,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEzE,MAAM,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAEvB,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,+DAA+D,CAChE,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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"]} |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
19
-60.42%9
-35.71%103441
-55.98%29
-32.56%695
-57.9%