api-switch-cc 0.2.4 → 0.2.6

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 (2) hide show
  1. package/install.js +71 -40
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -3,8 +3,10 @@
3
3
  /**
4
4
  * API-Switch — binary downloader & launcher
5
5
  *
6
- * On postinstall, downloads the correct pre-built binary for the
7
- * current platform from GitHub Releases and caches it locally.
6
+ * On postinstall, installs the api-switch binary.
7
+ * Tries multiple methods in order:
8
+ * 1. go install (works behind GFW with goproxy.cn)
9
+ * 2. Download pre-built binary from GitHub Releases
8
10
  *
9
11
  * Usage: npx api-switch-cc <command>
10
12
  * npm install -g api-switch-cc && api-switch serve
@@ -12,17 +14,15 @@
12
14
 
13
15
  "use strict";
14
16
 
15
- const { existsSync, mkdirSync, chmodSync, unlinkSync } = require("fs");
17
+ const { existsSync, mkdirSync, chmodSync, copyFileSync } = require("fs");
16
18
  const { join } = require("path");
17
19
  const { execSync } = require("child_process");
18
20
 
19
21
  const PKG = require("./package.json");
20
- // Download version — points to the GitHub release tag independent of npm version
21
- const DOWNLOAD_VERSION = "v0.2.0";
22
- const BASE = `https://github.com/hxz0727/API-Switch/releases/download/${DOWNLOAD_VERSION}`;
22
+ const DOWNLOAD_VERSION = "v0.2.1";
23
+ const GH_RELEASE = `https://github.com/hxz0727/API-Switch/releases/download/${DOWNLOAD_VERSION}`;
23
24
  const BIN_DIR = join(__dirname, "bin");
24
25
 
25
- // ── Platform detection ──────────────────────────────
26
26
  function platform() {
27
27
  const map = {
28
28
  "darwin-x64": "darwin-amd64",
@@ -39,51 +39,90 @@ function platform() {
39
39
  return map[key];
40
40
  }
41
41
 
42
- function binaryName() {
43
- if (process.platform === "win32") return "api-switch.exe";
44
- return "api-switch";
42
+ function binName() {
43
+ return process.platform === "win32" ? "api-switch.exe" : "api-switch";
45
44
  }
46
45
 
47
- function archivedBinaryName() {
48
- return `api-switch-${platform()}${process.platform === "win32" ? ".exe" : ""}`;
49
- }
50
-
51
- // ── Download & extract ──────────────────────────────
52
46
  function install() {
53
- const binName = binaryName();
54
- const binPath = join(BIN_DIR, binName);
47
+ const name = binName();
48
+ const binPath = join(BIN_DIR, name);
55
49
 
56
- // Skip if binary exists and is fresh
57
- if (existsSync(binPath)) {
58
- return;
59
- }
50
+ if (existsSync(binPath)) return;
60
51
 
61
52
  mkdirSync(BIN_DIR, { recursive: true });
62
53
 
54
+ // ── Method 1: go install via goproxy.cn (works in China) ──
55
+ if (tryGoInstall(binPath, name)) return;
56
+
57
+ // ── Method 2: Download from GitHub Releases ──
58
+ if (tryGitHubDownload(binPath, name)) return;
59
+
60
+ // ── All methods failed ──
61
+ console.error();
62
+ console.error("Installation failed. Try one of these:");
63
+ console.error();
64
+ console.error(" # Option A: Install via Go (quickest)");
65
+ console.error(" GOPROXY=https://goproxy.cn,direct go install github.com/hxz0727/API-Switch/cmd/api-switch@v0.2.0");
66
+ console.error(" sudo cp ~/go/bin/api-switch /usr/local/bin/");
67
+ console.error();
68
+ console.error(" # Option B: Download binary directly");
63
69
  const plat = platform();
64
70
  const isWin = process.platform === "win32";
65
71
  const archive = `api-switch-${plat}${isWin ? ".zip" : ".tar.gz"}`;
66
- const url = `${BASE}/${archive}`;
72
+ console.error(` curl -sSL "${GH_RELEASE}/${archive}" | tar xz`);
73
+ console.error(` sudo cp api-switch-${plat} /usr/local/bin/api-switch`);
74
+ console.error();
75
+ console.error(" # Option C: Build from source");
76
+ console.error(" git clone https://github.com/hxz0727/API-Switch.git");
77
+ console.error(" cd API-Switch && make build && sudo make install");
78
+ process.exit(1);
79
+ }
80
+
81
+ function tryGoInstall(binPath, name) {
82
+ try {
83
+ console.log("Trying go install (works behind GFW)...");
84
+ // Use goproxy.cn for Chinese users, fallback to default for others
85
+ execSync(
86
+ `go install github.com/hxz0727/API-Switch/cmd/api-switch@${DOWNLOAD_VERSION}`,
87
+ { stdio: "pipe", timeout: 120000 }
88
+ );
89
+ // go install puts binary in GOPATH/bin or ~/go/bin
90
+ const goPath = (execSync("go env GOPATH", { encoding: "utf8" }) || "~/go").trim();
91
+ const goBin = join(goPath, "bin", name);
92
+ if (existsSync(goBin)) {
93
+ copyFileSync(goBin, binPath);
94
+ chmodSync(binPath, 0o755);
95
+ console.log(`Installed to ${binPath}`);
96
+ return true;
97
+ }
98
+ } catch (_) {
99
+ // go not installed or install failed — try next method
100
+ }
101
+ return false;
102
+ }
103
+
104
+ function tryGitHubDownload(binPath, name) {
105
+ const plat = platform();
106
+ const isWin = process.platform === "win32";
107
+ const archive = `api-switch-${plat}${isWin ? ".zip" : ".tar.gz"}`;
108
+ const url = `${GH_RELEASE}/${archive}`;
67
109
  const tmp = join(__dirname, `_${archive}`);
68
110
 
69
111
  console.log(`Downloading ${DOWNLOAD_VERSION} for ${plat} ...`);
70
112
 
71
113
  try {
72
- // Download with retry and longer timeout
73
114
  execSync(
74
- `curl -sSL --connect-timeout 10 --max-time 120 --retry 3 "${url}" -o "${tmp}"`,
115
+ `curl -sSL --connect-timeout 10 --max-time 120 --retry 2 "${url}" -o "${tmp}"`,
75
116
  { stdio: "pipe", timeout: 180000 }
76
117
  );
77
118
 
78
- // Extract (archive contains binary named api-switch-<plat>)
79
- const archiveBin = archivedBinaryName();
119
+ const archiveBin = `api-switch-${plat}${isWin ? ".exe" : ""}`;
80
120
  if (isWin) {
81
121
  execSync(`unzip -o "${tmp}" "${archiveBin}" -d "${BIN_DIR}"`, { stdio: "pipe" });
82
122
  } else {
83
123
  execSync(`tar xzf "${tmp}" -C "${BIN_DIR}" "${archiveBin}"`, { stdio: "pipe" });
84
124
  }
85
125
 
86
- // Rename to simple binary name (e.g. api-switch-linux-amd64 → api-switch)
87
126
  const extractedPath = join(BIN_DIR, archiveBin);
88
127
  if (extractedPath !== binPath) {
89
128
  execSync(`mv "${extractedPath}" "${binPath}"`, { stdio: "pipe" });
@@ -91,20 +130,12 @@ function install() {
91
130
 
92
131
  chmodSync(binPath, 0o755);
93
132
  unlinkSync(tmp);
94
-
95
133
  console.log(`Installed to ${binPath}`);
134
+ return true;
96
135
  } catch (err) {
97
- console.error(`Download failed: ${err.message}`);
98
- console.log();
99
- console.log("Manual installation:");
100
- console.log(` curl -sSL "${url}" | tar xz`);
101
- console.log(` sudo cp ${join(".", archiveBin)} /usr/local/bin/api-switch`);
102
- console.log();
103
- console.log("Or install from source (requires Go):");
104
- console.log(" git clone https://github.com/hxz0727/API-Switch.git");
105
- console.log(" cd API-Switch && make build");
106
- console.log(" make install");
107
- process.exit(1);
136
+ console.error(` Download failed: ${err.message.split('\n')[0]}`);
137
+ try { unlinkSync(tmp); } catch (_) {}
138
+ return false;
108
139
  }
109
140
  }
110
141
 
@@ -115,7 +146,7 @@ if (process.argv[2] === "postinstall") {
115
146
  }
116
147
 
117
148
  // When run as CLI: execute the binary
118
- const binPath = join(BIN_DIR, binaryName());
149
+ const binPath = join(BIN_DIR, binName());
119
150
  const result = require("child_process").spawnSync(binPath, process.argv.slice(2), {
120
151
  stdio: "inherit",
121
152
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "api-switch-cc",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Claude Code 多模型代理 — 一键切换 DeepSeek、Qwen、GLM、Moonshot 等国产大模型,协议自动转换,零配置即用。LLM API proxy for Claude Code with DeepSeek, Qwen, Anthropic, OpenAI support.",
5
5
  "bin": {
6
6
  "api-switch": "bin/api-switch"