fix: download native crypto binary at plugin startup
Add bootstrap-native.ts that downloads @matrix-org/matrix-sdk-crypto-nodejs native binary before loading matrix-bot-sdk. This is needed because opencode's npm doesn't run postinstall scripts, and the binary is required for the Matrix SDK to work.
This commit is contained in:
parent
56aa069c64
commit
04a12d6f3e
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* 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.`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
/**
|
||||||
|
* 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.`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
import { ensureNativeBinary } from "./bootstrap-native.js";
|
||||||
|
// Ensure native binary is available before loading matrix-bot-sdk
|
||||||
|
// (opencode's npm doesn't run postinstall scripts)
|
||||||
|
ensureNativeBinary();
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
|
||||||
5
index.ts
5
index.ts
|
|
@ -1,3 +1,8 @@
|
||||||
|
import { ensureNativeBinary } from "./bootstrap-native.js"
|
||||||
|
// Ensure native binary is available before loading matrix-bot-sdk
|
||||||
|
// (opencode's npm doesn't run postinstall scripts)
|
||||||
|
ensureNativeBinary()
|
||||||
|
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import os from "os"
|
import os from "os"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue