Files
WRNexusJS/packages/plugin/src/compatibility.ts
T
Clintchiz 586a6db8ff
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-02 23:18:51 +05:30

79 lines
2.4 KiB
TypeScript

import type { WrnexusPackageManifest } from "./types.ts";
export interface PluginCompatibilityTarget {
runtime: "bun" | "node" | "edge" | "worker" | "service-worker" | "browser";
version?: string;
os?: "win32" | "linux" | "darwin" | string;
capabilities?: readonly string[];
}
export interface PluginCompatibilityResult {
target: PluginCompatibilityTarget;
ok: boolean;
issues: Array<{
code:
| "WRN-PLUGIN-MATRIX-RUNTIME"
| "WRN-PLUGIN-MATRIX-VERSION"
| "WRN-PLUGIN-MATRIX-OS"
| "WRN-PLUGIN-MATRIX-CAPABILITY";
message: string;
}>;
}
function parts(version: string): number[] {
return version
.replace(/^[^\d]*/, "")
.split(/[.-]/)
.slice(0, 3)
.map((value) => Number(value) || 0);
}
function atLeast(version: string, minimum: string): boolean {
const left = parts(version);
const right = parts(minimum);
for (let index = 0; index < 3; index += 1) {
if (left[index] !== right[index]) return (left[index] ?? 0) > (right[index] ?? 0);
}
return true;
}
export function testPluginCompatibility(
manifest: WrnexusPackageManifest,
targets: readonly PluginCompatibilityTarget[],
): PluginCompatibilityResult[] {
return targets.map((target) => {
const issues: PluginCompatibilityResult["issues"] = [];
if (manifest.runtimes?.length && !manifest.runtimes.includes(target.runtime)) {
issues.push({
code: "WRN-PLUGIN-MATRIX-RUNTIME",
message: `${target.runtime} is not declared.`,
});
}
const compatibility = manifest.compatibility;
if (
target.runtime === "bun" &&
target.version &&
compatibility?.bunMin &&
!atLeast(target.version, compatibility.bunMin)
) {
issues.push({
code: "WRN-PLUGIN-MATRIX-VERSION",
message: `Bun ${target.version} is below ${compatibility.bunMin}.`,
});
}
if (target.os && compatibility?.os?.length && !compatibility.os.includes(target.os)) {
issues.push({ code: "WRN-PLUGIN-MATRIX-OS", message: `${target.os} is not declared.` });
}
const missing = (manifest.requires ?? []).filter(
(capability) => !target.capabilities?.includes(capability),
);
if (missing.length) {
issues.push({
code: "WRN-PLUGIN-MATRIX-CAPABILITY",
message: `Missing: ${missing.join(", ")}.`,
});
}
return { target: { ...target }, ok: issues.length === 0, issues };
});
}