@aptos-labs/aptos-cli 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +109 -0
  2. package/dist/aptos.js +7 -2
  3. package/dist/aptos.js.map +1 -1
  4. package/dist/examples/examples.test.js +69 -0
  5. package/dist/examples/examples.test.js.map +1 -0
  6. package/dist/tasks/install.js +82 -31
  7. package/dist/tasks/install.js.map +1 -1
  8. package/dist/tasks/install.test.js +227 -0
  9. package/dist/tasks/install.test.js.map +1 -0
  10. package/dist/tasks/run.js +13 -8
  11. package/dist/tasks/run.js.map +1 -1
  12. package/dist/tasks/run.test.js +92 -0
  13. package/dist/tasks/run.test.js.map +1 -0
  14. package/dist/tasks/update.js +55 -20
  15. package/dist/tasks/update.js.map +1 -1
  16. package/dist/utils/brewOperations.js +30 -4
  17. package/dist/utils/brewOperations.js.map +1 -1
  18. package/dist/utils/brewOperations.test.js +83 -0
  19. package/dist/utils/brewOperations.test.js.map +1 -0
  20. package/dist/utils/consts.js.map +1 -1
  21. package/dist/utils/execSyncShell.js +6 -2
  22. package/dist/utils/execSyncShell.js.map +1 -1
  23. package/dist/utils/executableIsAvailable.js +12 -0
  24. package/dist/utils/executableIsAvailable.js.map +1 -0
  25. package/dist/utils/getLocalBinPath.js +76 -20
  26. package/dist/utils/getLocalBinPath.js.map +1 -1
  27. package/dist/utils/getUserOs.js +92 -6
  28. package/dist/utils/getUserOs.js.map +1 -1
  29. package/dist/utils/getUserOs.test.js +143 -0
  30. package/dist/utils/getUserOs.test.js.map +1 -0
  31. package/dist/utils/ghOperations.js +81 -6
  32. package/dist/utils/ghOperations.js.map +1 -1
  33. package/dist/utils/ghOperations.test.js +217 -0
  34. package/dist/utils/ghOperations.test.js.map +1 -0
  35. package/dist/utils/parseCommandOptions.js +4 -4
  36. package/dist/utils/parseCommandOptions.js.map +1 -1
  37. package/dist/utils/windowsPackageManagers.js +100 -0
  38. package/dist/utils/windowsPackageManagers.js.map +1 -0
  39. package/dist/utils/windowsPackageManagers.test.js +169 -0
  40. package/dist/utils/windowsPackageManagers.test.js.map +1 -0
  41. package/package.json +22 -11
  42. package/bin/.gitkeep +0 -0
  43. package/bin/aptos.ts +0 -44
  44. package/bin/tasks/install.ts +0 -55
  45. package/bin/tasks/run.ts +0 -27
  46. package/bin/tasks/update.ts +0 -41
  47. package/bin/utils/aptosExecutableIsAvailable.ts +0 -14
  48. package/bin/utils/brewOperations.ts +0 -12
  49. package/bin/utils/consts.ts +0 -3
  50. package/bin/utils/execSyncShell.ts +0 -8
  51. package/bin/utils/getLocalBinPath.ts +0 -28
  52. package/bin/utils/getUserOs.ts +0 -18
  53. package/bin/utils/ghOperations.ts +0 -20
  54. package/bin/utils/handleHelpOptions.ts +0 -38
  55. package/bin/utils/parseCommandOptions.ts +0 -28
  56. package/bin/utils/versions.ts +0 -9
  57. package/dist/aptos.d.ts +0 -2
  58. package/dist/tasks/install.d.ts +0 -1
  59. package/dist/tasks/run.d.ts +0 -1
  60. package/dist/tasks/update.d.ts +0 -1
  61. package/dist/utils/aptosExecutableIsAvailable.d.ts +0 -1
  62. package/dist/utils/aptosExecutableIsAvailable.js +0 -11
  63. package/dist/utils/aptosExecutableIsAvailable.js.map +0 -1
  64. package/dist/utils/brewOperations.d.ts +0 -1
  65. package/dist/utils/consts.d.ts +0 -2
  66. package/dist/utils/execSyncShell.d.ts +0 -1
  67. package/dist/utils/getLocalBinPath.d.ts +0 -1
  68. package/dist/utils/getUserOs.d.ts +0 -1
  69. package/dist/utils/ghOperations.d.ts +0 -1
  70. package/dist/utils/handleHelpOptions.d.ts +0 -2
  71. package/dist/utils/handleHelpOptions.js +0 -16
  72. package/dist/utils/handleHelpOptions.js.map +0 -1
  73. package/dist/utils/parseCommandOptions.d.ts +0 -5
  74. package/dist/utils/versions.d.ts +0 -1
  75. package/dist/utils/versions.js +0 -6
  76. package/dist/utils/versions.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getLocalBinPath.js","sourceRoot":"","sources":["../../bin/utils/getLocalBinPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,IAAI,IAAI,CAAC;IACT,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;QAEnB,MAAM,aAAa,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,mDAAmD,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC;YACH,IAAI,GAAG,cAAc,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;SAAM,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
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"]}
@@ -1,15 +1,101 @@
1
- import { platform } from "os";
2
- export const getOS = () => {
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { arch, platform } from "node:os";
3
+ export const getPlatformInfo = () => {
3
4
  const osPlatform = platform();
5
+ const osArch = arch();
6
+ let os;
4
7
  switch (osPlatform) {
5
8
  case "darwin":
6
- return "MacOS";
9
+ os = "macos";
10
+ break;
7
11
  case "linux":
8
- return "Ubuntu";
12
+ os = "linux";
13
+ break;
9
14
  case "win32":
10
- return "Windows";
15
+ os = "windows";
16
+ break;
17
+ default:
18
+ throw new Error(`Unsupported operating system: ${osPlatform}`);
19
+ }
20
+ let architecture;
21
+ switch (osArch) {
22
+ case "x64":
23
+ case "x86_64":
24
+ architecture = "x86_64";
25
+ break;
26
+ case "arm64":
27
+ case "aarch64":
28
+ architecture = "aarch64";
29
+ break;
30
+ default:
31
+ throw new Error(`Unsupported architecture: ${osArch}`);
32
+ }
33
+ return { os, arch: architecture };
34
+ };
35
+ const getLinuxDistroInfo = () => {
36
+ const osReleasePath = "/etc/os-release";
37
+ if (!existsSync(osReleasePath)) {
38
+ return null;
39
+ }
40
+ try {
41
+ const content = readFileSync(osReleasePath, "utf8");
42
+ const lines = content.split("\n");
43
+ let id = "";
44
+ let versionId = "";
45
+ for (const line of lines) {
46
+ const [key, ...valueParts] = line.split("=");
47
+ const value = valueParts.join("=").replace(/^["']|["']$/g, "");
48
+ if (key === "ID") {
49
+ id = value.toLowerCase();
50
+ }
51
+ else if (key === "VERSION_ID") {
52
+ versionId = value;
53
+ }
54
+ }
55
+ return { id, versionId };
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ };
61
+ export const getTargetPlatform = () => {
62
+ const { os, arch: architecture } = getPlatformInfo();
63
+ switch (os) {
64
+ case "macos":
65
+ return architecture === "aarch64" ? "macos-arm64" : "macos-x86_64";
66
+ case "linux": {
67
+ if (architecture === "aarch64") {
68
+ return "Linux-aarch64";
69
+ }
70
+ const distroInfo = getLinuxDistroInfo();
71
+ if (distroInfo?.id === "ubuntu") {
72
+ if (distroInfo.versionId.startsWith("24.04")) {
73
+ return "Ubuntu-24.04-x86_64";
74
+ }
75
+ if (distroInfo.versionId.startsWith("22.04")) {
76
+ return "Ubuntu-22.04-x86_64";
77
+ }
78
+ }
79
+ return "Linux-x86_64";
80
+ }
81
+ case "windows":
82
+ if (architecture === "aarch64") {
83
+ throw new Error("Windows ARM64 is not currently supported. Please use x86_64 emulation or build from source.");
84
+ }
85
+ return "Windows-x86_64";
11
86
  default:
12
- throw new Error(`Unsupported OS ${osPlatform}`);
87
+ throw new Error(`Unsupported OS: ${os}`);
88
+ }
89
+ };
90
+ export const getOS = () => {
91
+ const { os } = getPlatformInfo();
92
+ switch (os) {
93
+ case "macos":
94
+ return "MacOS";
95
+ case "linux":
96
+ return "Linux";
97
+ case "windows":
98
+ return "Windows";
13
99
  }
14
100
  };
15
101
  //# sourceMappingURL=getUserOs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getUserOs.js","sourceRoot":"","sources":["../../bin/utils/getUserOs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAK9B,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,MAAM,UAAU,GAAG,QAAQ,EAAE,CAAC;IAC9B,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,SAAS,CAAC;QACnB;YACE,MAAM,IAAI,KAAK,CAAC,kBAAkB,UAAU,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC,CAAC"}
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"]}
@@ -0,0 +1,143 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ vi.mock("os", async () => {
3
+ const actual = await vi.importActual("os");
4
+ return {
5
+ ...actual,
6
+ platform: vi.fn(),
7
+ arch: vi.fn(),
8
+ };
9
+ });
10
+ vi.mock("fs", async () => {
11
+ const actual = await vi.importActual("fs");
12
+ return {
13
+ ...actual,
14
+ existsSync: vi.fn(),
15
+ readFileSync: vi.fn(),
16
+ };
17
+ });
18
+ import { existsSync, readFileSync } from "node:fs";
19
+ import { arch, platform } from "node:os";
20
+ import { getOS, getPlatformInfo, getTargetPlatform } from "./getUserOs.js";
21
+ describe("getUserOs", () => {
22
+ beforeEach(() => {
23
+ vi.clearAllMocks();
24
+ });
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+ describe("getPlatformInfo", () => {
29
+ it("should detect macOS x86_64", () => {
30
+ vi.mocked(platform).mockReturnValue("darwin");
31
+ vi.mocked(arch).mockReturnValue("x64");
32
+ const result = getPlatformInfo();
33
+ expect(result).toEqual({ os: "macos", arch: "x86_64" });
34
+ });
35
+ it("should detect macOS ARM64", () => {
36
+ vi.mocked(platform).mockReturnValue("darwin");
37
+ vi.mocked(arch).mockReturnValue("arm64");
38
+ const result = getPlatformInfo();
39
+ expect(result).toEqual({ os: "macos", arch: "aarch64" });
40
+ });
41
+ it("should detect Linux x86_64", () => {
42
+ vi.mocked(platform).mockReturnValue("linux");
43
+ vi.mocked(arch).mockReturnValue("x64");
44
+ const result = getPlatformInfo();
45
+ expect(result).toEqual({ os: "linux", arch: "x86_64" });
46
+ });
47
+ it("should detect Linux ARM64", () => {
48
+ vi.mocked(platform).mockReturnValue("linux");
49
+ vi.mocked(arch).mockReturnValue("arm64");
50
+ const result = getPlatformInfo();
51
+ expect(result).toEqual({ os: "linux", arch: "aarch64" });
52
+ });
53
+ it("should detect Windows x86_64", () => {
54
+ vi.mocked(platform).mockReturnValue("win32");
55
+ vi.mocked(arch).mockReturnValue("x64");
56
+ const result = getPlatformInfo();
57
+ expect(result).toEqual({ os: "windows", arch: "x86_64" });
58
+ });
59
+ it("should throw for unsupported OS", () => {
60
+ vi.mocked(platform).mockReturnValue("freebsd");
61
+ vi.mocked(arch).mockReturnValue("x64");
62
+ expect(() => getPlatformInfo()).toThrow("Unsupported operating system");
63
+ });
64
+ it("should throw for unsupported architecture", () => {
65
+ vi.mocked(platform).mockReturnValue("linux");
66
+ vi.mocked(arch).mockReturnValue("mips");
67
+ expect(() => getPlatformInfo()).toThrow("Unsupported architecture");
68
+ });
69
+ });
70
+ describe("getTargetPlatform", () => {
71
+ it("should return macos-x86_64 for Intel Mac", () => {
72
+ vi.mocked(platform).mockReturnValue("darwin");
73
+ vi.mocked(arch).mockReturnValue("x64");
74
+ expect(getTargetPlatform()).toBe("macos-x86_64");
75
+ });
76
+ it("should return macos-arm64 for Apple Silicon Mac", () => {
77
+ vi.mocked(platform).mockReturnValue("darwin");
78
+ vi.mocked(arch).mockReturnValue("arm64");
79
+ expect(getTargetPlatform()).toBe("macos-arm64");
80
+ });
81
+ it("should return Ubuntu-24.04-x86_64 for Ubuntu 24.04", () => {
82
+ vi.mocked(platform).mockReturnValue("linux");
83
+ vi.mocked(arch).mockReturnValue("x64");
84
+ vi.mocked(existsSync).mockReturnValue(true);
85
+ vi.mocked(readFileSync).mockReturnValue('ID=ubuntu\nVERSION_ID="24.04"\n');
86
+ expect(getTargetPlatform()).toBe("Ubuntu-24.04-x86_64");
87
+ });
88
+ it("should return Ubuntu-22.04-x86_64 for Ubuntu 22.04", () => {
89
+ vi.mocked(platform).mockReturnValue("linux");
90
+ vi.mocked(arch).mockReturnValue("x64");
91
+ vi.mocked(existsSync).mockReturnValue(true);
92
+ vi.mocked(readFileSync).mockReturnValue('ID=ubuntu\nVERSION_ID="22.04"\n');
93
+ expect(getTargetPlatform()).toBe("Ubuntu-22.04-x86_64");
94
+ });
95
+ it("should return Linux-x86_64 for non-Ubuntu Linux", () => {
96
+ vi.mocked(platform).mockReturnValue("linux");
97
+ vi.mocked(arch).mockReturnValue("x64");
98
+ vi.mocked(existsSync).mockReturnValue(true);
99
+ vi.mocked(readFileSync).mockReturnValue('ID=fedora\nVERSION_ID="39"\n');
100
+ expect(getTargetPlatform()).toBe("Linux-x86_64");
101
+ });
102
+ it("should return Linux-x86_64 when /etc/os-release doesn't exist", () => {
103
+ vi.mocked(platform).mockReturnValue("linux");
104
+ vi.mocked(arch).mockReturnValue("x64");
105
+ vi.mocked(existsSync).mockReturnValue(false);
106
+ expect(getTargetPlatform()).toBe("Linux-x86_64");
107
+ });
108
+ it("should return Linux-aarch64 for ARM64 Linux", () => {
109
+ vi.mocked(platform).mockReturnValue("linux");
110
+ vi.mocked(arch).mockReturnValue("arm64");
111
+ vi.mocked(existsSync).mockReturnValue(false);
112
+ expect(getTargetPlatform()).toBe("Linux-aarch64");
113
+ });
114
+ it("should return Windows-x86_64 for Windows", () => {
115
+ vi.mocked(platform).mockReturnValue("win32");
116
+ vi.mocked(arch).mockReturnValue("x64");
117
+ expect(getTargetPlatform()).toBe("Windows-x86_64");
118
+ });
119
+ it("should throw for Windows ARM64", () => {
120
+ vi.mocked(platform).mockReturnValue("win32");
121
+ vi.mocked(arch).mockReturnValue("arm64");
122
+ expect(() => getTargetPlatform()).toThrow("Windows ARM64 is not currently supported");
123
+ });
124
+ });
125
+ describe("getOS", () => {
126
+ it("should return MacOS for darwin", () => {
127
+ vi.mocked(platform).mockReturnValue("darwin");
128
+ vi.mocked(arch).mockReturnValue("x64");
129
+ expect(getOS()).toBe("MacOS");
130
+ });
131
+ it("should return Linux for linux", () => {
132
+ vi.mocked(platform).mockReturnValue("linux");
133
+ vi.mocked(arch).mockReturnValue("x64");
134
+ expect(getOS()).toBe("Linux");
135
+ });
136
+ it("should return Windows for win32", () => {
137
+ vi.mocked(platform).mockReturnValue("win32");
138
+ vi.mocked(arch).mockReturnValue("x64");
139
+ expect(getOS()).toBe("Windows");
140
+ });
141
+ });
142
+ });
143
+ //# sourceMappingURL=getUserOs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getUserOs.test.js","sourceRoot":"","sources":["../../bin/utils/getUserOs.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGzE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;IACvB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAAY,IAAI,CAAC,CAAC;IACtD,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;QACjB,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;KACd,CAAC;AACJ,CAAC,CAAC,CAAC;AAGH,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;IACvB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAAsB,IAAI,CAAC,CAAC;IAChE,OAAO;QACL,GAAG,MAAM;QACT,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;QACnB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;KACtB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE3E,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAEzC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAEzC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC/C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAExC,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAEzC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC5C,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,eAAe,CACrC,iCAAiC,CAClC,CAAC;YAEF,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC5C,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,eAAe,CACrC,iCAAiC,CAClC,CAAC;YAEF,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAC5C,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,eAAe,CAAC,8BAA8B,CAAC,CAAC;YAExE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACvC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAE7C,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YACzC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAE7C,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAEzC,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,OAAO,CACvC,0CAA0C,CAC3C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC7C,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","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"]}
@@ -1,12 +1,87 @@
1
- import { PNAME } from "./consts.js";
1
+ import { GH_CLI_DOWNLOAD_URL, PNAME } from "./consts.js";
2
+ const getGitHubHeaders = () => {
3
+ const headers = {
4
+ Accept: "application/vnd.github.v3+json",
5
+ "User-Agent": "aptos-cli-npm",
6
+ };
7
+ const token = process.env.GITHUB_TOKEN;
8
+ if (token) {
9
+ headers.Authorization = `Bearer ${token}`;
10
+ }
11
+ return headers;
12
+ };
13
+ export const getUserSpecifiedVersion = () => {
14
+ const version = process.env.APTOS_CLI_VERSION;
15
+ if (!version) {
16
+ return undefined;
17
+ }
18
+ const stripped = version.replace(/^v/, "");
19
+ if (!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/.test(stripped)) {
20
+ throw new Error(`Invalid APTOS_CLI_VERSION: "${version}". Must match MAJOR.MINOR.PATCH (e.g. "4.5.0" or "v4.5.0").`);
21
+ }
22
+ return stripped;
23
+ };
24
+ export const hasUserSpecifiedVersion = () => {
25
+ return !!process.env.APTOS_CLI_VERSION;
26
+ };
27
+ export const validateVersionExists = async (version, targetPlatform) => {
28
+ const url = `${GH_CLI_DOWNLOAD_URL}/${PNAME}-v${version}/${PNAME}-${version}-${targetPlatform}.zip`;
29
+ try {
30
+ const response = await fetch(url, {
31
+ method: "HEAD",
32
+ headers: getGitHubHeaders(),
33
+ });
34
+ return response.ok;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ };
40
+ export const getCliVersion = async (targetPlatform) => {
41
+ const userVersion = getUserSpecifiedVersion();
42
+ if (userVersion) {
43
+ if (targetPlatform) {
44
+ const exists = await validateVersionExists(userVersion, targetPlatform);
45
+ if (!exists) {
46
+ throw new Error(`Specified version ${userVersion} does not exist or is not available for ${targetPlatform}. ` +
47
+ `Check https://github.com/aptos-labs/aptos-core/releases for available versions.`);
48
+ }
49
+ }
50
+ return userVersion;
51
+ }
52
+ return getLatestVersionGh();
53
+ };
2
54
  export const getLatestVersionGh = async () => {
3
55
  const prefix = `${PNAME}-v`;
4
- const response = await (await fetch("https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100")).json();
5
- for (const release of response) {
6
- if (release["tag_name"].startsWith(`${prefix}`)) {
7
- return release.tag_name.replace(`${prefix}`, "");
56
+ const url = "https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100";
57
+ let response;
58
+ try {
59
+ response = await fetch(url, { headers: getGitHubHeaders() });
60
+ }
61
+ catch (error) {
62
+ throw new Error(`Failed to fetch releases from GitHub: ${error instanceof Error ? error.message : String(error)}`);
63
+ }
64
+ if (!response.ok) {
65
+ if (response.status === 403 || response.status === 429) {
66
+ throw new Error("GitHub API rate limit exceeded. Please try again later or set a GITHUB_TOKEN environment variable.");
67
+ }
68
+ throw new Error(`GitHub API request failed with status ${response.status}: ${response.statusText}`);
69
+ }
70
+ let releases;
71
+ try {
72
+ releases = await response.json();
73
+ }
74
+ catch {
75
+ throw new Error("Failed to parse GitHub API response as JSON");
76
+ }
77
+ if (!Array.isArray(releases)) {
78
+ throw new Error("Unexpected response format from GitHub API");
79
+ }
80
+ for (const release of releases) {
81
+ if (release.tag_name?.startsWith(prefix)) {
82
+ return release.tag_name.replace(prefix, "");
8
83
  }
9
84
  }
10
- throw "Could not determine latest version of Aptos CLI";
85
+ throw new Error("Could not determine latest version of Aptos CLI. No matching release found in the last 100 releases.");
11
86
  };
12
87
  //# sourceMappingURL=ghOperations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ghOperations.js","sourceRoot":"","sources":["../../bin/utils/ghOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAMpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;IAC3C,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,CACrB,MAAM,KAAK,CACT,0EAA0E,CAC3E,CACF,CAAC,IAAI,EAAE,CAAC;IACT,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;YAChD,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IACD,MAAM,iDAAiD,CAAC;AAC1D,CAAC,CAAC"}
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"]}