fix
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
arePluginNeedsApproved,
|
||||
compilePluginTypeScript,
|
||||
computePluginNeedsHash,
|
||||
ensurePluginExtracted,
|
||||
loadPluginBundle,
|
||||
type PluginState,
|
||||
} from "./plugin-state-bundle";
|
||||
@@ -70,6 +71,31 @@ describe("loadPluginBundle", () => {
|
||||
expect(bundle.size).toBe(4);
|
||||
});
|
||||
|
||||
test("keeps helper DLLs out of the native platform binary map", async () => {
|
||||
const root = await createTempRoot();
|
||||
const AdmZip = require("adm-zip");
|
||||
const zip = new AdmZip();
|
||||
zip.addFile("config.json", Buffer.from(JSON.stringify({
|
||||
name: "Plink",
|
||||
apiVersion: 2,
|
||||
runtime: "native",
|
||||
uiEntry: "src/ui.ts",
|
||||
})));
|
||||
zip.addFile("plink.html", Buffer.from("<div id=\"plink-root\"></div>"));
|
||||
zip.addFile("plink.css", Buffer.from("#plink-root { display: block; }"));
|
||||
zip.addFile("src/ui.ts", Buffer.from("document.body.dataset.plugin = 'plink';"));
|
||||
zip.addFile("plink-windows-amd64.dll", Buffer.from("entry-dll"));
|
||||
zip.addFile("plink-payload.dll", Buffer.from("helper-dll"));
|
||||
zip.writeZip(join(root, "plink.zip"));
|
||||
|
||||
await ensurePluginExtracted(root, "plink", (name) => name);
|
||||
const manifest = JSON.parse(await readFile(join(root, "plink", "manifest.json"), "utf-8"));
|
||||
expect(manifest.binaries["windows-amd64"]).toBe("plink-windows-amd64.dll");
|
||||
|
||||
const bundle = await loadPluginBundle(root, "plink", async () => {}, "Windows 11", "amd64");
|
||||
expect(bundle.binaryPath).toBe(join(root, "plink", "plink-windows-amd64.dll"));
|
||||
});
|
||||
|
||||
test("computes stable need hashes and invalidates changed approvals", () => {
|
||||
const state: PluginState = {
|
||||
enabled: {},
|
||||
|
||||
@@ -149,11 +149,17 @@ export async function ensurePluginExtracted(
|
||||
throw new Error(`Invalid plugin bundle: ${safeId} (missing .html, .css, and either .js or src/ui.ts)`);
|
||||
}
|
||||
|
||||
const binariesMap: Record<string, string> = {};
|
||||
for (const [filename, data] of nativeBinaries) {
|
||||
await fs.writeFile(path.join(pluginDir, filename), data);
|
||||
}
|
||||
|
||||
const binariesMap: Record<string, string> = {};
|
||||
applyConfiguredNativeBinaries(binariesMap, extraConfig, nativeBinaries);
|
||||
const nativeBinaryNames = Array.from(nativeBinaries.keys())
|
||||
.sort((a, b) => nativeBinaryPriority(a, safeId) - nativeBinaryPriority(b, safeId) || a.localeCompare(b));
|
||||
for (const filename of nativeBinaryNames) {
|
||||
const platformKey = derivePlatformKey(filename);
|
||||
if (platformKey) {
|
||||
if (platformKey && !binariesMap[platformKey]) {
|
||||
binariesMap[platformKey] = filename;
|
||||
}
|
||||
}
|
||||
@@ -203,6 +209,7 @@ export async function ensurePluginExtracted(
|
||||
runtime,
|
||||
version: extraConfig.version || "1.0.0",
|
||||
description: extraConfig.description,
|
||||
...(typeof extraConfig.binary === "string" && extraConfig.binary && { binary: extraConfig.binary }),
|
||||
...(runtime === "wasm" && { wasm: String(extraConfig.wasm || wasmEntry?.filename || binariesMap["wasm32-wasi"] || "") }),
|
||||
...(needs && { needs }),
|
||||
binaries: binariesMap,
|
||||
@@ -345,7 +352,7 @@ export async function loadPluginBundle(
|
||||
const files = await fs.readdir(dir);
|
||||
const archRegex = /-(linux|darwin|windows|freebsd)-(amd64|arm64|arm|386)\.(so|dll|dylib)$/i;
|
||||
|
||||
const found = files.find((f) => {
|
||||
const found = files.find((f: string) => {
|
||||
const m = f.match(archRegex);
|
||||
if (m) {
|
||||
return (
|
||||
@@ -733,3 +740,38 @@ function derivePlatformKey(filename: string): string {
|
||||
if (lower.endsWith(".so")) return "linux-amd64";
|
||||
return "";
|
||||
}
|
||||
|
||||
function applyConfiguredNativeBinaries(
|
||||
binariesMap: Record<string, string>,
|
||||
config: any,
|
||||
nativeBinaries: Map<string, Buffer>,
|
||||
): void {
|
||||
if (config?.binaries && typeof config.binaries === "object") {
|
||||
for (const [platformKey, filename] of Object.entries(config.binaries)) {
|
||||
if (typeof platformKey !== "string" || typeof filename !== "string") continue;
|
||||
const base = path.basename(filename);
|
||||
if (!nativeBinaries.has(base)) continue;
|
||||
binariesMap[platformKey.toLowerCase()] = base;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof config?.binary === "string" && config.binary) {
|
||||
const base = path.basename(config.binary);
|
||||
if (!nativeBinaries.has(base)) return;
|
||||
const platformKey = derivePlatformKey(base);
|
||||
if (platformKey) {
|
||||
binariesMap[platformKey] = base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function nativeBinaryPriority(filename: string, pluginId: string): number {
|
||||
const escapedId = pluginId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
if (new RegExp(`^${escapedId}-(linux|darwin|windows|freebsd)-(amd64|arm64|arm|386)\\.(so|dll|dylib)$`, "i").test(filename)) {
|
||||
return 0;
|
||||
}
|
||||
if (/-(linux|darwin|windows|freebsd)-(amd64|arm64|arm|386)\.(so|dll|dylib)$/i.test(filename)) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user