/** * Bootstrap: downloads native binary for @matrix-org/matrix-sdk-crypto-nodejs * if it doesn't exist. * * This is needed because opencode's npm doesn't run postinstall scripts. * The binary is cached in the plugin's node_modules, so it only downloads once. * * Must be imported BEFORE any import from matrix-bot-sdk. */ import https from "https"; import fs from "fs"; import path from "path"; const CRYPTO_PACKAGE_DIR = path.join(__dirname, "..", "node_modules", "@matrix-org", "matrix-sdk-crypto-nodejs"); const VERSION = "0.4.0"; function isMusl() { if (!process.report || typeof process.report.getReport !== "function") { try { const lddPath = require("child_process") .execSync("which ldd") .toString() .trim(); return fs.readFileSync(lddPath, "utf8").includes("musl"); } catch { return true; } } const { glibcVersionRuntime } = process.report.getReport().header; return !glibcVersionRuntime; } function getBinaryName() { const platform = process.platform; const arch = process.arch; switch (platform) { case "linux": if (arch === "x64") { return isMusl() ? "matrix-sdk-crypto.linux-x64-musl.node" : "matrix-sdk-crypto.linux-x64-gnu.node"; } if (arch === "arm64") { return isMusl() ? "matrix-sdk-crypto.linux-arm64-musl.node" : "matrix-sdk-crypto.linux-arm64-gnu.node"; } if (arch === "arm") { return "matrix-sdk-crypto.linux-arm-gnueabihf.node"; } if (arch === "s390x") { return "matrix-sdk-crypto.linux-s390x-gnu.node"; } break; case "darwin": if (arch === "x64") return "matrix-sdk-crypto.darwin-x64.node"; if (arch === "arm64") return "matrix-sdk-crypto.darwin-arm64.node"; break; case "win32": if (arch === "x64") return "matrix-sdk-crypto.win32-x64-msvc.node"; if (arch === "arm64") return "matrix-sdk-crypto.win32-arm64-msvc.node"; break; } throw new Error(`Unsupported platform: ${platform}-${arch}. ` + "matrix-bot-sdk requires a native crypto binary for this platform."); } export function ensureNativeBinary() { const binaryName = getBinaryName(); const binaryPath = path.join(CRYPTO_PACKAGE_DIR, binaryName); if (fs.existsSync(binaryPath)) { return; // Already downloaded } const url = `https://github.com/matrix-org/matrix-rust-sdk-crypto-nodejs/releases/download/v${VERSION}/${binaryName}`; const filePath = binaryPath; console.error(`[matrix-plugin] Downloading native crypto binary: ${binaryName}`); https .get(url, (res) => { const statusCode = res.statusCode ?? 200; if (statusCode >= 300 && statusCode < 400 && res.headers.location) { // Follow redirects https.get(res.headers.location, (redirectRes) => { const file = fs.createWriteStream(filePath); redirectRes.pipe(file); file.on("finish", () => { file.close(); console.error(`[matrix-plugin] Native binary downloaded: ${binaryName}`); }); }).on("error", (err) => { console.error(`[matrix-plugin] Failed to download native binary: ${err.message}`); console.error(`[matrix-plugin] Please ensure you have network access to GitHub releases.`); }); return; } const file = fs.createWriteStream(filePath); res.pipe(file); file.on("finish", () => { file.close(); console.error(`[matrix-plugin] Native binary downloaded: ${binaryName}`); }); }) .on("error", (err) => { console.error(`[matrix-plugin] Failed to download native binary: ${err.message}`); console.error(`[matrix-plugin] Please ensure you have network access to GitHub releases.`); }); }