api-switch-cc 0.2.7 → 0.3.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 (3) hide show
  1. package/api-switch.js +103 -0
  2. package/install.js +36 -13
  3. package/package.json +2 -6
package/api-switch.js ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * API-Switch — lazy-install launcher
5
+ *
6
+ * On first run, installs the api-switch binary (via go/gitee/github),
7
+ * then execs it with the original arguments.
8
+ * Subsequent runs use the cached binary directly.
9
+ *
10
+ * Usage: api-switch <args...>
11
+ */
12
+
13
+ "use strict";
14
+
15
+ const { existsSync, mkdirSync, chmodSync, unlinkSync, copyFileSync } = require("fs");
16
+ const { join } = require("path");
17
+ const { execSync, spawnSync } = require("child_process");
18
+
19
+ const VERSION = "v0.2.1";
20
+ const BIN_DIR = join(__dirname, ".bin");
21
+ const BIN_NAME = process.platform === "win32" ? "api-switch.exe" : "api-switch";
22
+ const BIN_PATH = join(BIN_DIR, BIN_NAME);
23
+
24
+ const GITEE_REPO = "https://gitee.com/776311606/API-Switch.git";
25
+ const GH_RELEASE = `https://github.com/hxz0727/API-Switch/releases/download/${VERSION}`;
26
+
27
+ function platform() {
28
+ const map = {
29
+ "darwin-x64": "darwin-amd64", "darwin-arm64": "darwin-arm64",
30
+ "linux-x64": "linux-amd64", "linux-arm64": "linux-arm64",
31
+ "win32-x64": "windows-amd64",
32
+ };
33
+ return map[`${process.platform}-${process.arch}`];
34
+ }
35
+
36
+ // ── Install binary (lazy, on first use) ──
37
+ function ensureInstalled() {
38
+ if (existsSync(BIN_PATH)) return;
39
+
40
+ mkdirSync(BIN_DIR, { recursive: true });
41
+ console.log("First run — installing api-switch...");
42
+
43
+ // 1. go install via goproxy.cn
44
+ try {
45
+ const gopath = (execSync("go env GOPATH", { encoding: "utf8", stdio: "pipe" }) || "~/go").trim();
46
+ const goBin = join(gopath, "bin", BIN_NAME);
47
+ execSync(`GOPROXY=https://goproxy.cn,direct GOTOOLCHAIN=local go install github.com/hxz0727/API-Switch/cmd/api-switch@${VERSION}`, { stdio: "pipe", timeout: 120000 });
48
+ if (existsSync(goBin)) {
49
+ copyFileSync(goBin, BIN_PATH);
50
+ chmodSync(BIN_PATH, 0o755);
51
+ console.log("Installed via go install.");
52
+ return;
53
+ }
54
+ } catch (_) {}
55
+
56
+ // 2. Clone from Gitee + build
57
+ try {
58
+ console.log("Trying Gitee mirror...");
59
+ const tmp = join(__dirname, ".gitee-build");
60
+ execSync(`rm -rf ${tmp} && git clone --depth=1 ${GITEE_REPO} ${tmp}`, { stdio: "pipe", timeout: 60000 });
61
+ execSync(`cd ${tmp} && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -ldflags="-s -w -X main.Version=${VERSION}" -o "${BIN_PATH}" ./cmd/api-switch/`, { stdio: "pipe", timeout: 120000 });
62
+ execSync(`rm -rf ${tmp}`, { stdio: "pipe" });
63
+ chmodSync(BIN_PATH, 0o755);
64
+ console.log("Installed via Gitee mirror.");
65
+ return;
66
+ } catch (_) {}
67
+
68
+ // 3. GitHub release download
69
+ const plat = platform();
70
+ if (plat) {
71
+ try {
72
+ console.log("Trying GitHub release...");
73
+ const isWin = process.platform === "win32";
74
+ const archive = `api-switch-${plat}${isWin ? ".zip" : ".tar.gz"}`;
75
+ const url = `${GH_RELEASE}/${archive}`;
76
+ const tmp = join(__dirname, ".gh-download");
77
+ execSync(`curl -sSL --connect-timeout 10 --max-time 120 "${url}" -o "${tmp}"`, { stdio: "pipe", timeout: 150000 });
78
+ if (isWin) {
79
+ execSync(`unzip -o "${tmp}" "api-switch-${plat}.exe"`, { stdio: "pipe" });
80
+ renameSync(`api-switch-${plat}.exe`, BIN_PATH);
81
+ } else {
82
+ execSync(`tar xzf "${tmp}" -C "${BIN_DIR}" "api-switch-${plat}"`, { stdio: "pipe" });
83
+ execSync(`mv "${join(BIN_DIR, 'api-switch-' + plat)}" "${BIN_PATH}"`, { stdio: "pipe" });
84
+ }
85
+ unlinkSync(tmp);
86
+ chmodSync(BIN_PATH, 0o755);
87
+ console.log("Installed via GitHub.");
88
+ return;
89
+ } catch (_) {}
90
+ }
91
+
92
+ console.error();
93
+ console.error("Installation failed. Run manually:");
94
+ console.error(` git clone --depth=1 ${GITEE_REPO}`);
95
+ console.error(" cd API-Switch && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -o api-switch ./cmd/api-switch/");
96
+ console.error(" cp api-switch /usr/local/bin/");
97
+ process.exit(1);
98
+ }
99
+
100
+ // ── Entry ──
101
+ ensureInstalled();
102
+ const r = spawnSync(BIN_PATH, process.argv.slice(2), { stdio: "inherit" });
103
+ process.exit(r.status ?? 1);
package/install.js CHANGED
@@ -5,8 +5,9 @@
5
5
  *
6
6
  * On postinstall, installs the api-switch binary.
7
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
+ * 1. go install (via goproxy.cn, works behind GFW)
9
+ * 2. Build from Gitee mirror (fast in China)
10
+ * 3. Download from GitHub Releases
10
11
  *
11
12
  * Usage: npx api-switch-cc <command>
12
13
  * npm install -g api-switch-cc && api-switch serve
@@ -21,6 +22,7 @@ const { execSync } = require("child_process");
21
22
  const PKG = require("./package.json");
22
23
  const DOWNLOAD_VERSION = "v0.2.1";
23
24
  const GH_RELEASE = `https://github.com/hxz0727/API-Switch/releases/download/${DOWNLOAD_VERSION}`;
25
+ const GITEE_REPO = "https://gitee.com/776311606/API-Switch.git";
24
26
  const BIN_DIR = join(__dirname, "bin");
25
27
 
26
28
  function platform() {
@@ -54,7 +56,10 @@ function install() {
54
56
  // ── Method 1: go install via goproxy.cn (works in China) ──
55
57
  if (tryGoInstall(binPath, name)) return;
56
58
 
57
- // ── Method 2: Download from GitHub Releases ──
59
+ // ── Method 2: Clone from Gitee + build (fast for Chinese users) ──
60
+ if (tryGiteeBuild(binPath)) return;
61
+
62
+ // ── Method 3: Download from GitHub Releases ──
58
63
  if (tryGitHubDownload(binPath, name)) return;
59
64
 
60
65
  // ── All methods failed ──
@@ -65,28 +70,27 @@ function install() {
65
70
  console.error(" GOPROXY=https://goproxy.cn,direct go install github.com/hxz0727/API-Switch/cmd/api-switch@v0.2.1");
66
71
  console.error(" sudo cp ~/go/bin/api-switch /usr/local/bin/");
67
72
  console.error();
68
- console.error(" # Option B: Download binary directly");
73
+ console.error(" # Option B: Clone from Gitee and build");
74
+ console.error(` git clone --depth=1 ${GITEE_REPO}`);
75
+ console.error(" cd API-Switch && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -o api-switch ./cmd/api-switch/");
76
+ console.error(" sudo cp api-switch /usr/local/bin/");
77
+ console.error();
78
+ console.error(" # Option C: Download from GitHub");
69
79
  const plat = platform();
70
80
  const isWin = process.platform === "win32";
71
81
  const archive = `api-switch-${plat}${isWin ? ".zip" : ".tar.gz"}`;
72
82
  console.error(` curl -sSL "${GH_RELEASE}/${archive}" | tar xz`);
73
83
  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
84
  process.exit(1);
79
85
  }
80
86
 
81
87
  function tryGoInstall(binPath, name) {
82
88
  try {
83
89
  console.log("Trying go install (works behind GFW)...");
84
- // Use goproxy.cn for Chinese users who can't reach proxy.golang.org
85
90
  execSync(
86
91
  `GOPROXY=https://goproxy.cn,direct GOTOOLCHAIN=local go install github.com/hxz0727/API-Switch/cmd/api-switch@${DOWNLOAD_VERSION}`,
87
92
  { stdio: "pipe", timeout: 120000 }
88
93
  );
89
- // go install puts binary in GOPATH/bin or ~/go/bin
90
94
  const goPath = (execSync("go env GOPATH", { encoding: "utf8" }) || "~/go").trim();
91
95
  const goBin = join(goPath, "bin", name);
92
96
  if (existsSync(goBin)) {
@@ -95,9 +99,28 @@ function tryGoInstall(binPath, name) {
95
99
  console.log(`Installed to ${binPath}`);
96
100
  return true;
97
101
  }
98
- } catch (_) {
99
- // go not installed or install failed — try next method
100
- }
102
+ } catch (_) {}
103
+ return false;
104
+ }
105
+
106
+ function tryGiteeBuild(binPath) {
107
+ try {
108
+ console.log("Trying Gitee mirror build...");
109
+ const tmpDir = join(__dirname, "_build");
110
+ execSync("rm -rf " + tmpDir, { stdio: "pipe" });
111
+ execSync(
112
+ `git clone --depth=1 ${GITEE_REPO} ${tmpDir}`,
113
+ { stdio: "pipe", timeout: 60000 }
114
+ );
115
+ execSync(
116
+ `cd ${tmpDir} && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -ldflags="-s -w -X main.Version=v0.2.1" -o "${binPath}" ./cmd/api-switch/`,
117
+ { stdio: "pipe", timeout: 120000 }
118
+ );
119
+ execSync("rm -rf " + tmpDir, { stdio: "pipe" });
120
+ chmodSync(binPath, 0o755);
121
+ console.log(`Installed to ${binPath}`);
122
+ return true;
123
+ } catch (_) {}
101
124
  return false;
102
125
  }
103
126
 
package/package.json CHANGED
@@ -1,13 +1,9 @@
1
1
  {
2
2
  "name": "api-switch-cc",
3
- "version": "0.2.7",
3
+ "version": "0.3.0",
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
- "api-switch": "bin/api-switch"
7
- },
8
- "scripts": {
9
- "postinstall": "node install.js",
10
- "postupdate": "node install.js"
6
+ "api-switch": "api-switch.js"
11
7
  },
12
8
  "repository": {
13
9
  "type": "git",