()
| 212 | } |
| 213 | |
| 214 | function install() { |
| 215 | const mirrorUrls = getMirrorUrls(process.env); |
| 216 | const downloadUrls = [GITHUB_URL, ...mirrorUrls]; |
| 217 | |
| 218 | fs.mkdirSync(binDir, { recursive: true }); |
| 219 | |
| 220 | const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "lark-cli-")); |
| 221 | const archivePath = path.join(tmpDir, archiveName); |
| 222 | |
| 223 | try { |
| 224 | // Walk the chain in order; stop at the first success. Default chain: |
| 225 | // GitHub → derived(npm_config_registry)? → npmmirror. The npmmirror |
| 226 | // tail preserves the pre-PR safety net when a corporate proxy doesn't |
| 227 | // actually host /-/binary/<pkg>/... |
| 228 | let lastErr; |
| 229 | let downloaded = false; |
| 230 | for (const url of downloadUrls) { |
| 231 | try { |
| 232 | download(url, archivePath); |
| 233 | downloaded = true; |
| 234 | break; |
| 235 | } catch (e) { |
| 236 | lastErr = e; |
| 237 | } |
| 238 | } |
| 239 | if (!downloaded) throw lastErr; |
| 240 | |
| 241 | const expectedHash = getExpectedChecksum(archiveName); |
| 242 | verifyChecksum(archivePath, expectedHash); |
| 243 | |
| 244 | if (isWindows) { |
| 245 | extractZipWindows(archivePath, tmpDir); |
| 246 | } else { |
| 247 | execFileSync("tar", ["-xzf", archivePath, "-C", tmpDir], { |
| 248 | stdio: "ignore", |
| 249 | }); |
| 250 | } |
| 251 | |
| 252 | const binaryName = NAME + (isWindows ? ".exe" : ""); |
| 253 | const extractedBinary = path.join(tmpDir, binaryName); |
| 254 | |
| 255 | fs.copyFileSync(extractedBinary, dest); |
| 256 | fs.chmodSync(dest, 0o755); |
| 257 | console.log(`${NAME} v${VERSION} installed successfully`); |
| 258 | } finally { |
| 259 | fs.rmSync(tmpDir, { recursive: true, force: true }); |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | function getExpectedChecksum(archiveName, checksumsDir) { |
| 264 | const dir = checksumsDir || path.join(__dirname, ".."); |
no test coverage detected