Archived
fix: keep federated docker updates tab visible
This commit is contained in:
@@ -6,11 +6,20 @@ import { PiWebPluginService, type PiPackageProvider } from "./piWebPluginService
|
||||
|
||||
let tempDir: string;
|
||||
|
||||
const originalDockerRuntime = process.env["PI_WEB_DOCKER_RUNTIME"];
|
||||
const originalDockerMode = process.env["PI_WEB_DOCKER_MODE"];
|
||||
const originalDockerDevRepoRoot = process.env["PI_WEB_DOCKER_DEV_REPO_ROOT"];
|
||||
const originalDockerInstallDir = process.env["PI_WEB_DOCKER_INSTALL_DIR"];
|
||||
|
||||
beforeEach(async () => {
|
||||
tempDir = await mkdtemp(join(tmpdir(), "pi-web-plugin-service-test-"));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
restoreEnv("PI_WEB_DOCKER_RUNTIME", originalDockerRuntime);
|
||||
restoreEnv("PI_WEB_DOCKER_MODE", originalDockerMode);
|
||||
restoreEnv("PI_WEB_DOCKER_DEV_REPO_ROOT", originalDockerDevRepoRoot);
|
||||
restoreEnv("PI_WEB_DOCKER_INSTALL_DIR", originalDockerInstallDir);
|
||||
await rm(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
@@ -47,6 +56,20 @@ describe("PiWebPluginService", () => {
|
||||
await expect(service.plugins()).resolves.toMatchObject({ plugins: [{ id: "updates", machineSpecific: true, enabled: true }] });
|
||||
});
|
||||
|
||||
it("adds Docker runtime hints to the Updates plugin module URL", async () => {
|
||||
process.env["PI_WEB_DOCKER_RUNTIME"] = "1";
|
||||
process.env["PI_WEB_DOCKER_MODE"] = "dev";
|
||||
await writePlugin(join(tempDir, "plugins", "updates"), {
|
||||
packageJson: { piWeb: { plugins: [{ id: "updates", module: "pi-web-plugin.js", machineSpecific: true }] } },
|
||||
files: { "pi-web-plugin.js": "export default {};" },
|
||||
});
|
||||
|
||||
const service = new PiWebPluginService({ roots: [{ path: join(tempDir, "plugins"), source: "test", scope: "local" }], packageProvider: false });
|
||||
|
||||
const manifest = await service.manifest();
|
||||
expect(manifest.plugins[0]?.module).toMatch(/^\/pi-web-plugins\/updates\/pi-web-plugin\.js\?v=\d+&piWebDockerMode=dev$/u);
|
||||
});
|
||||
|
||||
it("discovers Pi package plugins through an injected package provider", async () => {
|
||||
const packageDir = join(tempDir, "pkg");
|
||||
await writePlugin(packageDir, {
|
||||
@@ -198,3 +221,8 @@ async function writePlugin(root: string, options: { packageJson: unknown; files:
|
||||
await writeFile(filePath, content);
|
||||
}
|
||||
}
|
||||
|
||||
function restoreEnv(key: string, value: string | undefined): void {
|
||||
if (value === undefined) Reflect.deleteProperty(process.env, key);
|
||||
else process.env[key] = value;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ export class PiWebPluginService {
|
||||
private pluginInfo(plugin: PluginRecord, config: PiWebConfig): PiWebPluginInfo {
|
||||
return {
|
||||
id: plugin.id,
|
||||
module: `/pi-web-plugins/${encodeURIComponent(plugin.id)}/${plugin.entryFile}?v=${encodeURIComponent(plugin.version)}`,
|
||||
module: `/pi-web-plugins/${encodeURIComponent(plugin.id)}/${plugin.entryFile}?${pluginModuleQuery(plugin)}`,
|
||||
source: plugin.source,
|
||||
scope: plugin.scope,
|
||||
machineSpecific: plugin.machineSpecific,
|
||||
@@ -187,6 +187,35 @@ function bundledPluginRoot(packageRoot: string): string {
|
||||
return join(packageRoot, "dist", "pi-web-plugins");
|
||||
}
|
||||
|
||||
function pluginModuleQuery(plugin: PluginRecord): string {
|
||||
const params = new URLSearchParams({ v: plugin.version });
|
||||
const dockerMode = plugin.id === "updates" ? dockerModeFromEnv() : undefined;
|
||||
if (dockerMode !== undefined) params.set("piWebDockerMode", dockerMode);
|
||||
return params.toString();
|
||||
}
|
||||
|
||||
function dockerModeFromEnv(): "runtime" | "dev" | undefined {
|
||||
if (!isTruthyEnv("PI_WEB_DOCKER_RUNTIME")) return undefined;
|
||||
const mode = process.env["PI_WEB_DOCKER_MODE"];
|
||||
if (mode === "runtime" || mode === "dev") return mode;
|
||||
if (firstNonEmptyEnv("PI_WEB_DOCKER_DEV_REPO_ROOT") !== undefined) return "dev";
|
||||
if (firstNonEmptyEnv("PI_WEB_DOCKER_INSTALL_DIR") !== undefined) return "runtime";
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function firstNonEmptyEnv(...keys: string[]): string | undefined {
|
||||
for (const key of keys) {
|
||||
const value = process.env[key];
|
||||
if (value !== undefined && value !== "") return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isTruthyEnv(key: string): boolean {
|
||||
const value = process.env[key];
|
||||
return value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
||||
}
|
||||
|
||||
function sourceCheckoutPluginRoots(cwd: string): LocalPluginRoot[] {
|
||||
const pluginsRoot = join(cwd, "plugins");
|
||||
if (!existsSync(join(cwd, "src", "server", "index.ts")) || !existsSync(pluginsRoot)) return [];
|
||||
|
||||
Reference in New Issue
Block a user