mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
v26.10.3 (#1692)
* feat: shell controller, TabStage, layout and theme plugins with repair view * feat: move the classic layout into its own bundled plugin * feat: move color themes into a bundled themes plugin * fix: plugin tests and type checks work with a linked sdk * fix: home tab, layout switch and missing layout fallbacks for looks * chore: add classic layout and themes to the readme * chore: drop example plugin links from the plugin guide * feat: plugin filters by type, paged browse, hide plugins needing newer termix * feat: move desktop, status, import, audit and branding features into plugins * feat: host lock api so a plugin can load hosts from a config file (#1581) * chore: add hosts config to the plugin table * feat: login policy hook for plugins and optional https redirect (#1584) * chore: add login security to the plugin table * feat: api key socket tickets so a master can open remote sessions (#1654) * feat: sync moves to a plugin, desktop gets multiple accounts (#1580, #1654) * chore: add sync to the plugin table * feat: move the sync screens and wizard out of core into the plugin (#1580) * fix: add a neutral linked desktop hook for plugins (#1580) * fix: show the linked account's name and admin flag in the app (#1580) * feat: ssh transport providers, core ssh relay and plugin folders api * feat: support FIDO2 security keys through ssh agent * feat: add companion panels beside host tabs * feat: mTLS client certificates for desktop server links * feat: native web view for plugins in the desktop app * fix: detect the desktop link window by Electron's default user agent Fixes #1675 * fix: changelog for desktop link fix * fix: keep text primary keys in the plugin data export * fix: ship sharp binaries for Windows arm64 builds * feat: client cert on the sync link types (sdk 1.0.18) * chore: update translations * feat: themed title bar for the desktop app (#1690) * chore: changelog for the themed title bar * fix: draw the title bar in the sidebar color * feat: per host layout for the terminal panel bar * chore: sdk 1.0.19 for the panel bar layout * chore: bundle all 43 plugins for 26.10.3 * chore: update translations --------- Co-authored-by: SirHephaistos <60616553+SirHephaistos@users.noreply.github.com> Co-authored-by: Giovanny Aranda <garanda21@gmail.com>
This commit is contained in:
577 files changed
+76479
-101831
No files matched your search
@@ -1,4 +1,5 @@
|
||||
// Serves a plugin's built frontend: its bundle, stylesheet and locales.
|
||||
// Serves a plugin's built frontend: its bundle, stylesheet, locales and the
|
||||
// CSS files its themes declare.
|
||||
//
|
||||
// Unauthenticated on purpose, the same as /assets: import() cannot carry the
|
||||
// bearer header, and nothing here is secret. It only ever serves files from
|
||||
@@ -28,6 +29,22 @@ export interface PluginFrontendInfo {
|
||||
assetVersion: string | null;
|
||||
/** Language codes with a locale file, "en" plus xx_YY names. */
|
||||
locales: string[];
|
||||
/** Changes whenever a theme's CSS does, for its ?v= link. */
|
||||
themeVersion: string | null;
|
||||
}
|
||||
|
||||
/** Where a theme's CSS is served: /plugin-assets/<id>/_themes/<theme>.css. */
|
||||
export const THEME_ASSET_PREFIX = "_themes/";
|
||||
|
||||
/** The declared CSS file of each of the plugin's themes, by theme id. */
|
||||
function themeFiles(plugin: AssetPlugin): Map<string, string> {
|
||||
const files = new Map<string, string>();
|
||||
const manifest = plugin.manifest as PluginManifest;
|
||||
for (const theme of manifest.contributes?.themes ?? []) {
|
||||
const file = path.resolve(plugin.dir, theme.css);
|
||||
if (isInside(plugin.dir, file)) files.set(theme.id, file);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
function frontendEntry(
|
||||
@@ -72,9 +89,16 @@ export function describePluginFrontend(
|
||||
css: false,
|
||||
assetVersion: null,
|
||||
locales: [],
|
||||
themeVersion: null,
|
||||
};
|
||||
if (!plugin) return none;
|
||||
|
||||
const themes = [...themeFiles(plugin).values()].filter(fileExists);
|
||||
const themeVersion =
|
||||
themes.length > 0
|
||||
? contentVersion(themes.sort(), plugin.manifest.version)
|
||||
: null;
|
||||
|
||||
const locales: string[] = [];
|
||||
const localeFiles: string[] = [];
|
||||
const dir = localesDir(plugin);
|
||||
@@ -96,7 +120,8 @@ export function describePluginFrontend(
|
||||
}
|
||||
|
||||
const entry = frontendEntry(plugin);
|
||||
if (!entry || !fileExists(entry.file)) return { ...none, locales };
|
||||
if (!entry || !fileExists(entry.file))
|
||||
return { ...none, locales, themeVersion };
|
||||
|
||||
const cssFile = path.join(entry.dir, "frontend.css");
|
||||
const css = fileExists(cssFile);
|
||||
@@ -111,6 +136,7 @@ export function describePluginFrontend(
|
||||
css,
|
||||
assetVersion,
|
||||
locales: locales.sort(),
|
||||
themeVersion,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -158,7 +184,14 @@ export function resolvePluginAsset(
|
||||
|
||||
let root: string | null;
|
||||
let rest: string;
|
||||
if (clean.startsWith("locales/")) {
|
||||
if (clean.startsWith(THEME_ASSET_PREFIX)) {
|
||||
// Only a declared theme file, which the loader checked on load.
|
||||
const themeId = clean.slice(THEME_ASSET_PREFIX.length, -".css".length);
|
||||
const file = themeFiles(plugin).get(themeId);
|
||||
if (!file || !clean.endsWith(".css")) return null;
|
||||
root = path.dirname(file);
|
||||
rest = path.basename(file);
|
||||
} else if (clean.startsWith("locales/")) {
|
||||
root = localesDir(plugin);
|
||||
rest = clean.slice("locales/".length);
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user