mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 22:25:24 +00:00
chore: lock the plugin boundary and remove 2.9.0 leftovers
This commit is contained in:
1 parent
6489b62ece
commit
2961297989
399 files changed
+3964
-5627
No files matched your search
@@ -118,6 +118,7 @@ export function createPluginApp(
|
||||
labelKey: key(item.titleKey),
|
||||
kind: item.kind === "tab" ? "tab" : undefined,
|
||||
hideable: item.hideable,
|
||||
simplePreset: item.simplePreset,
|
||||
promotable: item.promotable,
|
||||
rightDockable: item.rightDockable,
|
||||
mobilePrimary: item.mobilePrimary,
|
||||
|
||||
@@ -50,7 +50,6 @@ const loginMethods = createRegistry<LoginMethodDef>();
|
||||
const secondFactors = createRegistry<SecondFactorDef>();
|
||||
|
||||
export const registerSshAuthEditor = sshAuthEditors.register;
|
||||
export const getSshAuthEditor = sshAuthEditors.get;
|
||||
export const useSshAuthEditors = sshAuthEditors.useList;
|
||||
|
||||
export const registerLoginMethod = loginMethods.register;
|
||||
@@ -62,9 +61,3 @@ export const registerSecondFactor = secondFactors.register;
|
||||
export const getSecondFactorUI = secondFactors.get;
|
||||
export const useSecondFactors = secondFactors.useList;
|
||||
export const listSecondFactorUIs = secondFactors.list;
|
||||
|
||||
export function resetAuthRegistries(): void {
|
||||
sshAuthEditors.reset();
|
||||
loginMethods.reset();
|
||||
secondFactors.reset();
|
||||
}
|
||||
@@ -30,7 +30,8 @@ import {
|
||||
} from "@/api/plugins-api";
|
||||
import { getCookie, getUserInfo } from "@/main-axios";
|
||||
import { logActivity } from "@/api/dashboard-api";
|
||||
import { getHostPassword } from "@/api/credentials-api";
|
||||
import { getCredentials, getHostPassword } from "@/api/credentials-api";
|
||||
import { getSSHHosts } from "@/api/ssh-host-management-api";
|
||||
import {
|
||||
getUserPreferences,
|
||||
parseCustomKeybindings,
|
||||
@@ -51,8 +52,8 @@ import { useOptionalHostStatusEntry } from "@/lib/ServerStatusContext";
|
||||
/**
|
||||
* Core permission groups, mirroring RESERVED_PERMISSION_PREFIXES in the SDK
|
||||
* manifest module, which is not imported here because it pulls semver into
|
||||
* the browser bundle. A group that is itself a plugin id (snippets, once)
|
||||
* does not need an entry here: knownPluginIds() below already covers it.
|
||||
* the browser bundle. A plugin's own namespace is covered by knownPluginIds()
|
||||
* below.
|
||||
*/
|
||||
const CORE_PERMISSION_GROUPS = ["hosts", "credentials", "admin"];
|
||||
|
||||
@@ -119,11 +120,6 @@ function loadCurrentUser() {
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
/** Forgets the cached user, on logout. */
|
||||
export function resetBridgeUser(): void {
|
||||
currentUser = null;
|
||||
}
|
||||
|
||||
const SETTINGS_READERS: Record<
|
||||
SettingsScope,
|
||||
(pluginId: string, hostId?: number) => Promise<Record<string, unknown>>
|
||||
@@ -295,6 +291,7 @@ export const pluginHostBridge: PluginHostBridge = {
|
||||
pluginId: option.pluginId,
|
||||
credentialType: option.credentialType,
|
||||
supportsBackground: option.supportsBackground,
|
||||
quickConnect: option.quickConnect === true,
|
||||
})),
|
||||
};
|
||||
},
|
||||
@@ -367,6 +364,20 @@ export const pluginHostBridge: PluginHostBridge = {
|
||||
parseCustomKeybindings((await getUserPreferences()).customKeybindings),
|
||||
setHostAutoTmux: (hostId, autoTmux) => setHostAutoTmux(hostId, autoTmux),
|
||||
getClientPreference: (name) => getCookie(name),
|
||||
listHosts: async () =>
|
||||
(await getSSHHosts({ includeStatus: false })).map(toHostRecord),
|
||||
listCredentials: async () => {
|
||||
const raw = await getCredentials();
|
||||
const list = Array.isArray(raw)
|
||||
? raw
|
||||
: ((raw as { credentials?: unknown[] }).credentials ?? []);
|
||||
return (list as Record<string, unknown>[]).map((c) => ({
|
||||
id: Number(c.id),
|
||||
name: String(c.name ?? ""),
|
||||
username: typeof c.username === "string" ? c.username : undefined,
|
||||
authType: typeof c.authType === "string" ? c.authType : undefined,
|
||||
}));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -40,10 +40,6 @@ export function registerPluginComponent(
|
||||
};
|
||||
}
|
||||
|
||||
export function getPluginComponent(id: string): AnyComponent | undefined {
|
||||
return components.get(id);
|
||||
}
|
||||
|
||||
function subscribe(listener: () => void): () => void {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
@@ -72,9 +68,3 @@ export function PluginComponent({
|
||||
if (!Component) return fallback as ReactNode;
|
||||
return createElement(Component, props);
|
||||
}
|
||||
|
||||
/** Test seam. */
|
||||
export function resetPluginComponents(): void {
|
||||
components.clear();
|
||||
notify();
|
||||
}
|
||||
@@ -26,8 +26,6 @@ export interface RegisteredHomepageWidget {
|
||||
const registry = createRegistry<RegisteredHomepageWidget>();
|
||||
|
||||
export const registerHomepageWidgetType = registry.register;
|
||||
export const unregisterHomepageWidgetType = registry.unregister;
|
||||
export const getHomepageWidgetType = registry.get;
|
||||
export const listHomepageWidgetTypes = registry.list;
|
||||
export const useHomepageWidgetTypes = registry.useList;
|
||||
export const resetHomepageWidgetTypes = registry.reset;
|
||||
@@ -327,7 +327,7 @@ export function syncPlugins(summaries?: PluginSummary[]): Promise<void> {
|
||||
}
|
||||
|
||||
/** Fired by anything that changes plugin state, e.g. the admin toggle. */
|
||||
export const PLUGINS_CHANGED_EVENT = "termix:plugins-changed";
|
||||
const PLUGINS_CHANGED_EVENT = "termix:plugins-changed";
|
||||
|
||||
let lastFocusSync = 0;
|
||||
const FOCUS_SYNC_INTERVAL_MS = 30_000;
|
||||
|
||||
@@ -38,7 +38,7 @@ function commit(next: StoreState): void {
|
||||
for (const listener of listeners) listener();
|
||||
}
|
||||
|
||||
export function subscribePluginStore(listener: () => void): () => void {
|
||||
function subscribePluginStore(listener: () => void): () => void {
|
||||
listeners.add(listener);
|
||||
return () => {
|
||||
listeners.delete(listener);
|
||||
|
||||
@@ -75,7 +75,7 @@ class PluginErrorBoundary extends Component<BoundaryProps, { error: boolean }> {
|
||||
}
|
||||
}
|
||||
|
||||
export function PluginScope({
|
||||
function PluginScope({
|
||||
pluginId,
|
||||
children,
|
||||
}: {
|
||||
|
||||
@@ -159,3 +159,40 @@ export {
|
||||
testNotificationChannel,
|
||||
type NotificationChannel,
|
||||
} from "@/api/notification-channels-api";
|
||||
|
||||
// Keyboard hints, the connection log panel and a named console logger.
|
||||
export { Kbd, KbdKey, KbdSeparator } from "@/components/kbd";
|
||||
export { ConnectionLogPanel } from "@/components/connection/ConnectionLogPanel";
|
||||
export type { LogEntry } from "@/types/connection-log";
|
||||
export { createFrontendLogger, type LogContext } from "@/lib/frontend-logger";
|
||||
|
||||
// One budget for background work across the whole app (preloads, prefetches).
|
||||
export {
|
||||
getAdaptiveResourceBudget,
|
||||
markAdaptiveResourceUsed,
|
||||
runAdaptiveBackgroundTask,
|
||||
} from "@/lib/adaptive-resource-budget";
|
||||
|
||||
// The id this browser sends as X-Termix-Device-ID.
|
||||
export { getDeviceId } from "@/lib/device-id";
|
||||
|
||||
// A host that is never saved, for connecting to an address straight away.
|
||||
export {
|
||||
createQuickConnectHost,
|
||||
isQuickConnectHost,
|
||||
} from "@/sidebar/quick-connect-host";
|
||||
|
||||
// The desktop app's local file bridge (window.electronAPI.localFs and
|
||||
// localTransfer), for plugins that browse or transfer local files.
|
||||
export type {
|
||||
LocalCollectedFile,
|
||||
LocalDirectoryListing,
|
||||
LocalFileEntry,
|
||||
LocalFsHomeInfo,
|
||||
LocalFsResult,
|
||||
LocalTransferOrigin,
|
||||
LocalTransferProgress,
|
||||
LocalTrashResult,
|
||||
LocalWalkFile,
|
||||
LocalWalkResult,
|
||||
} from "@/types/electron";
|
||||
@@ -59,10 +59,6 @@ export function useShellHosts(): { hosts: Host[]; loaded: boolean } {
|
||||
);
|
||||
}
|
||||
|
||||
export function getShellHosts(): Host[] {
|
||||
return hosts;
|
||||
}
|
||||
|
||||
export function notifyTabsChanged(): void {
|
||||
for (const listener of changeListeners) listener();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
import type { ReactElement } from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import type { PluginManifest } from "@termix/plugin-sdk/frontend";
|
||||
import type {
|
||||
HostActionContribution,
|
||||
PluginManifest,
|
||||
} from "@termix/plugin-sdk/frontend";
|
||||
import type {
|
||||
FrontendPluginModule,
|
||||
RenderWithAppOptions,
|
||||
@@ -27,7 +30,7 @@ import {
|
||||
} from "@/shell/tab-registry";
|
||||
import { getPanel, listPanels } from "@/shell/panel-registry";
|
||||
import { listRegisteredRailItems } from "@/sidebar/rail-items";
|
||||
import { listHostActions } from "@/sidebar/host-contributions";
|
||||
import { hostActionsFor, listHostActions } from "@/sidebar/host-contributions";
|
||||
import { listHostProtocols } from "@/sidebar/host-protocols";
|
||||
import {
|
||||
getHostEditorSection,
|
||||
@@ -214,6 +217,10 @@ export async function renderPlugin(
|
||||
id: action.id,
|
||||
tabType: action.tabType,
|
||||
})),
|
||||
hostActionsFor: (host) =>
|
||||
mine(
|
||||
hostActionsFor(listHostActions(), host as Host),
|
||||
) as unknown as HostActionContribution[],
|
||||
hostProtocols: () =>
|
||||
mine(listHostProtocols()).map((protocol) => protocol.id),
|
||||
hostEditorSections: () =>
|
||||
|
||||
Reference in new issue
Block a user