dll plugin loading heavily improved
This commit is contained in:
@@ -357,6 +357,8 @@ export type PluginManifest = {
|
||||
name: string;
|
||||
apiVersion?: number;
|
||||
runtime?: "native" | "wasm" | "server" | string;
|
||||
nativeLoader?: "memory" | "os" | string;
|
||||
nativeEntrypoints?: PluginNativeEntrypoints;
|
||||
version?: string;
|
||||
description?: string;
|
||||
binary?: string;
|
||||
@@ -378,6 +380,14 @@ export type PluginManifest = {
|
||||
hasServer?: boolean;
|
||||
};
|
||||
|
||||
export type PluginNativeEntrypoints = {
|
||||
onLoad?: string;
|
||||
onEvent?: string;
|
||||
onUnload?: string;
|
||||
setCallback?: string;
|
||||
getRuntime?: string;
|
||||
};
|
||||
|
||||
export type PluginDashboardIntegration = {
|
||||
clientBadges?: PluginDashboardBadgeDefinition[];
|
||||
};
|
||||
|
||||
@@ -96,6 +96,40 @@ describe("loadPluginBundle", () => {
|
||||
expect(bundle.binaryPath).toBe(join(root, "plink", "plink-windows-amd64.dll"));
|
||||
});
|
||||
|
||||
test("preserves native loader and custom entrypoint metadata from config", async () => {
|
||||
const root = await createTempRoot();
|
||||
const AdmZip = require("adm-zip");
|
||||
const zip = new AdmZip();
|
||||
zip.addFile("config.json", Buffer.from(JSON.stringify({
|
||||
name: "Native Loader Demo",
|
||||
apiVersion: 2,
|
||||
runtime: "native",
|
||||
nativeLoader: "loadlibraryex",
|
||||
nativeEntrypoints: {
|
||||
onLoad: "StartPlugin",
|
||||
onEvent: "HandlePluginEvent",
|
||||
onUnload: "StopPlugin",
|
||||
setCallback: "SetHostCallback",
|
||||
getRuntime: "RuntimeName",
|
||||
},
|
||||
})));
|
||||
zip.addFile("native-loader-demo.html", Buffer.from("<div id=\"native-loader-demo\"></div>"));
|
||||
zip.addFile("native-loader-demo.css", Buffer.from("#native-loader-demo { display: block; }"));
|
||||
zip.addFile("native-loader-demo.js", Buffer.from("document.body.dataset.nativeLoaderDemo = '1';"));
|
||||
zip.addFile("native-loader-demo-windows-amd64.dll", Buffer.from("native-dll"));
|
||||
zip.writeZip(join(root, "native-loader-demo.zip"));
|
||||
|
||||
await ensurePluginExtracted(root, "native-loader-demo", (name) => name);
|
||||
const manifest = JSON.parse(await readFile(join(root, "native-loader-demo", "manifest.json"), "utf-8"));
|
||||
|
||||
expect(manifest.nativeLoader).toBe("os");
|
||||
expect(manifest.nativeEntrypoints.onLoad).toBe("StartPlugin");
|
||||
expect(manifest.nativeEntrypoints.onEvent).toBe("HandlePluginEvent");
|
||||
expect(manifest.nativeEntrypoints.onUnload).toBe("StopPlugin");
|
||||
expect(manifest.nativeEntrypoints.setCallback).toBe("SetHostCallback");
|
||||
expect(manifest.nativeEntrypoints.getRuntime).toBe("RuntimeName");
|
||||
});
|
||||
|
||||
test("preserves dashboard badge metadata from config", async () => {
|
||||
const root = await createTempRoot();
|
||||
const AdmZip = require("adm-zip");
|
||||
|
||||
@@ -200,6 +200,8 @@ export async function ensurePluginExtracted(
|
||||
}
|
||||
|
||||
const runtime = normalizePluginRuntime(extraConfig.runtime, wasmEntry !== null);
|
||||
const nativeLoader = normalizeNativeLoader(extraConfig.nativeLoader);
|
||||
const nativeEntrypoints = normalizeNativeEntrypoints(extraConfig.nativeEntrypoints);
|
||||
const needs = normalizePluginNeeds(extraConfig.needs);
|
||||
const build = normalizePluginBuildIntegration(extraConfig.build);
|
||||
const manifest: PluginManifest = {
|
||||
@@ -207,6 +209,8 @@ export async function ensurePluginExtracted(
|
||||
name: extraConfig.name || safeId,
|
||||
apiVersion: Number(extraConfig.apiVersion) === 2 || runtime === "wasm" ? 2 : 1,
|
||||
runtime,
|
||||
...(nativeLoader && { nativeLoader }),
|
||||
...(nativeEntrypoints && { nativeEntrypoints }),
|
||||
version: extraConfig.version || "1.0.0",
|
||||
description: extraConfig.description,
|
||||
...(typeof extraConfig.binary === "string" && extraConfig.binary && { binary: extraConfig.binary }),
|
||||
@@ -634,6 +638,26 @@ function normalizePluginRuntime(runtime: any, hasWasm: boolean): "native" | "was
|
||||
return "native";
|
||||
}
|
||||
|
||||
function normalizeNativeLoader(loader: any): "memory" | "os" | undefined {
|
||||
const value = typeof loader === "string" ? loader.trim().toLowerCase() : "";
|
||||
if (["memory", "mem", "reflective", "manual"].includes(value)) return "memory";
|
||||
if (["os", "disk", "file", "loadlibrary", "loadlibraryex"].includes(value)) return "os";
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function normalizeNativeEntrypoints(raw: any): any | undefined {
|
||||
if (!raw || typeof raw !== "object") return undefined;
|
||||
const out: any = {};
|
||||
for (const key of ["onLoad", "onEvent", "onUnload", "setCallback", "getRuntime"]) {
|
||||
const value = raw[key];
|
||||
if (typeof value !== "string") continue;
|
||||
const trimmed = value.trim();
|
||||
if (!/^[A-Za-z_][A-Za-z0-9_@$?.-]{0,127}$/.test(trimmed)) continue;
|
||||
out[key] = trimmed;
|
||||
}
|
||||
return Object.keys(out).length > 0 ? out : undefined;
|
||||
}
|
||||
|
||||
function normalizePluginBuildIntegration(raw: any): any | undefined {
|
||||
if (!raw || typeof raw !== "object") return undefined;
|
||||
const build: any = {};
|
||||
|
||||
Reference in New Issue
Block a user