mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-13 19:20:06 +00:00
154 lines
4.0 KiB
JavaScript
154 lines
4.0 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
|
||
|
|
const { execSync, spawnSync } = require("child_process");
|
||
|
|
const fs = require("fs");
|
||
|
|
const path = require("path");
|
||
|
|
const https = require("https");
|
||
|
|
const { createWriteStream, mkdirSync, chmodSync, unlinkSync } = fs;
|
||
|
|
|
||
|
|
const REPO = "mark3labs/kit";
|
||
|
|
const BINARY = "kit";
|
||
|
|
|
||
|
|
// Get version from package.json
|
||
|
|
const packageJson = require("./package.json");
|
||
|
|
const VERSION = packageJson.version;
|
||
|
|
|
||
|
|
// Platform mapping
|
||
|
|
const PLATFORM_MAP = {
|
||
|
|
darwin: "darwin",
|
||
|
|
linux: "linux",
|
||
|
|
win32: "windows",
|
||
|
|
};
|
||
|
|
|
||
|
|
// Arch mapping
|
||
|
|
const ARCH_MAP = {
|
||
|
|
x64: "amd64",
|
||
|
|
arm64: "arm64",
|
||
|
|
};
|
||
|
|
|
||
|
|
function getPlatform() {
|
||
|
|
const platform = PLATFORM_MAP[process.platform];
|
||
|
|
if (!platform) {
|
||
|
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
||
|
|
}
|
||
|
|
return platform;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getArch() {
|
||
|
|
const arch = ARCH_MAP[process.arch];
|
||
|
|
if (!arch) {
|
||
|
|
throw new Error(`Unsupported architecture: ${process.arch}`);
|
||
|
|
}
|
||
|
|
return arch;
|
||
|
|
}
|
||
|
|
|
||
|
|
function getExtension(platform) {
|
||
|
|
return platform === "windows" ? "zip" : "tar.gz";
|
||
|
|
}
|
||
|
|
|
||
|
|
function getBinaryName(platform) {
|
||
|
|
// Use different name to avoid conflict with JS wrapper on Unix
|
||
|
|
return platform === "windows" ? `${BINARY}.exe` : `${BINARY}-bin`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function download(url, dest) {
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
const follow = (url, redirects = 0) => {
|
||
|
|
if (redirects > 10) {
|
||
|
|
reject(new Error("Too many redirects"));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
https
|
||
|
|
.get(url, (response) => {
|
||
|
|
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
||
|
|
follow(response.headers.location, redirects + 1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (response.statusCode !== 200) {
|
||
|
|
reject(new Error(`Failed to download: ${response.statusCode}`));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const file = createWriteStream(dest);
|
||
|
|
response.pipe(file);
|
||
|
|
file.on("finish", () => {
|
||
|
|
file.close();
|
||
|
|
resolve();
|
||
|
|
});
|
||
|
|
file.on("error", (err) => {
|
||
|
|
unlinkSync(dest);
|
||
|
|
reject(err);
|
||
|
|
});
|
||
|
|
})
|
||
|
|
.on("error", reject);
|
||
|
|
};
|
||
|
|
|
||
|
|
follow(url);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function extract(archivePath, destDir, platform) {
|
||
|
|
if (platform === "windows") {
|
||
|
|
// Use PowerShell to extract zip on Windows
|
||
|
|
spawnSync("powershell", [
|
||
|
|
"-Command",
|
||
|
|
`Expand-Archive -Path "${archivePath}" -DestinationPath "${destDir}" -Force`,
|
||
|
|
]);
|
||
|
|
} else {
|
||
|
|
// Use tar for Unix systems
|
||
|
|
spawnSync("tar", ["-xzf", archivePath, "-C", destDir]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const platform = getPlatform();
|
||
|
|
const arch = getArch();
|
||
|
|
const ext = getExtension(platform);
|
||
|
|
const binaryName = getBinaryName(platform);
|
||
|
|
|
||
|
|
const filename = `${BINARY}_${VERSION}_${platform}_${arch}.${ext}`;
|
||
|
|
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${filename}`;
|
||
|
|
|
||
|
|
const binDir = path.join(__dirname, "bin");
|
||
|
|
const archivePath = path.join(__dirname, filename);
|
||
|
|
const binaryPath = path.join(binDir, binaryName);
|
||
|
|
|
||
|
|
console.log(`Installing ${BINARY} v${VERSION} (${platform}/${arch})...`);
|
||
|
|
console.log(`Downloading from ${url}...`);
|
||
|
|
|
||
|
|
try {
|
||
|
|
// Ensure bin directory exists
|
||
|
|
mkdirSync(binDir, { recursive: true });
|
||
|
|
|
||
|
|
// Download archive
|
||
|
|
await download(url, archivePath);
|
||
|
|
|
||
|
|
// Extract
|
||
|
|
extract(archivePath, binDir, platform);
|
||
|
|
|
||
|
|
// Rename binary (archive contains "kit", we want "kit-bin" on Unix)
|
||
|
|
const extractedName = platform === "windows" ? `${BINARY}.exe` : BINARY;
|
||
|
|
const extractedPath = path.join(binDir, extractedName);
|
||
|
|
if (extractedPath !== binaryPath && fs.existsSync(extractedPath)) {
|
||
|
|
fs.renameSync(extractedPath, binaryPath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Make executable on Unix
|
||
|
|
if (platform !== "windows") {
|
||
|
|
chmodSync(binaryPath, 0o755);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clean up archive
|
||
|
|
unlinkSync(archivePath);
|
||
|
|
|
||
|
|
console.log(`Successfully installed ${BINARY} to ${binaryPath}`);
|
||
|
|
} catch (err) {
|
||
|
|
console.error(`Failed to install ${BINARY}: ${err.message}`);
|
||
|
|
process.exit(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
main();
|