/** * 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(): boolean { 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 as any).getReport().header return !glibcVersionRuntime } function getBinaryName(): string { 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(): void { 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.`) }) }