Archived
Move the Updates plugin's pure decision logic (recommended/additional commands, panel visibility, installation labels, version formatting) into a sibling updatesLogic.ts module so it can be unit tested directly, matching the workspace-tasks multi-file plugin layout. The plugin file is now thin rendering glue that imports those helpers. Add unit tests for the extracted logic and render smoke tests that exercise the panel through its public contribution API, including that Run actions wire to the terminal with the "pi.plugin": "updates" metadata. No behavior change; the beta label stays.
75 lines
3.2 KiB
TypeScript
75 lines
3.2 KiB
TypeScript
import type { PiWebInstallationInfo, PiWebStatusMessage, PiWebStatusResponse, PluginRuntimeState } from "@jmfederico/pi-web/plugin-api";
|
|
|
|
export interface CommandEntry {
|
|
label: string;
|
|
command: string;
|
|
}
|
|
|
|
// The single command users should run when they do not want to think: if an
|
|
// update is available, `commands.update` already chains the update and a full
|
|
// restart; otherwise, when anything is stale, a full restart is enough.
|
|
export function recommendedCommand(status: PiWebStatusResponse): CommandEntry | undefined {
|
|
const { commands, release, components } = status;
|
|
if (release.updateAvailable && typeof commands.update === "string" && commands.update !== "") {
|
|
return { label: "Update & restart everything", command: commands.update };
|
|
}
|
|
const restartNeeded = components.web.stale || components.sessiond.stale || !components.sessiond.available;
|
|
if (restartNeeded && typeof commands.restart === "string" && commands.restart !== "") {
|
|
return { label: "Restart everything", command: commands.restart };
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function additionalCommands(status: PiWebStatusResponse, recommended: CommandEntry | undefined): CommandEntry[] {
|
|
return [
|
|
["Update", status.commands.update],
|
|
["Restart all", status.commands.restart],
|
|
["Restart Web/UI", status.commands.restartWeb],
|
|
["Restart session daemon", status.commands.restartSessiond],
|
|
["Status", status.commands.status],
|
|
]
|
|
.filter((entry): entry is [string, string] => typeof entry[1] === "string" && entry[1] !== "")
|
|
.filter(([, command]) => command !== recommended?.command)
|
|
.map(([label, command]) => ({ label, command }));
|
|
}
|
|
|
|
export function messagesFor(state: PluginRuntimeState | undefined): PiWebStatusMessage[] {
|
|
return state?.piWebStatus?.messages ?? [];
|
|
}
|
|
|
|
export function statusFor(state: PluginRuntimeState | undefined): PiWebStatusResponse | undefined {
|
|
return state?.piWebStatus;
|
|
}
|
|
|
|
export function messageCount(state: PluginRuntimeState | undefined): number {
|
|
return messagesFor(state).length;
|
|
}
|
|
|
|
export function isLocalOrUnknownInstallation(installation: PiWebInstallationInfo | undefined): boolean {
|
|
return installation === undefined || installation.kind === "local" || installation.kind === "unknown";
|
|
}
|
|
|
|
export function shouldShowUpdatesPanel(state: PluginRuntimeState | undefined): boolean {
|
|
const status = statusFor(state);
|
|
if (messageCount(state) > 0) return true;
|
|
if (status === undefined) return false;
|
|
return isLocalOrUnknownInstallation(status.components.web.installation)
|
|
|| isLocalOrUnknownInstallation(status.components.sessiond.installation);
|
|
}
|
|
|
|
export function formatVersion(version: string | undefined): string {
|
|
return version === undefined || version === "" ? "unknown" : version;
|
|
}
|
|
|
|
export function installationLabel(installation: PiWebInstallationInfo | undefined): string {
|
|
if (installation === undefined) return "installation unknown";
|
|
if (installation.kind === "pi-package") {
|
|
const scope = installation.scope === undefined ? "" : ` · ${installation.scope}`;
|
|
const source = installation.source ?? "Pi package";
|
|
return `${source}${scope}`;
|
|
}
|
|
if (installation.kind === "npm-global") return "global npm package";
|
|
if (installation.kind === "local") return "local checkout";
|
|
return "installation unknown";
|
|
}
|