mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
feat: shared list kit, settings search, rail order and ui consistency fixes
This commit is contained in:
1 parent
3ed5775ed5
commit
58c3434e58
68 files changed
+2078
-512
No files matched your search
@@ -5,6 +5,10 @@
|
||||
* dist/backend/backend/plugins -> dist/plugins, which is where this writes.
|
||||
* Each .tmxplug is downloaded (or read from a path), checked against its
|
||||
* pinned sha256 and unpacked.
|
||||
*
|
||||
* For development, `--local <dir>` (or TERMIX_LOCAL_PLUGINS) points at a
|
||||
* folder of plugin repos like ../Termix-Plugins. Any plugin built there (has
|
||||
* dist/) is copied in place of its pin, so local plugin changes show up.
|
||||
*/
|
||||
|
||||
const fs = require("node:fs");
|
||||
@@ -13,6 +17,8 @@ const {
|
||||
loadBundledPlugins,
|
||||
fetchArtifact,
|
||||
extractArtifact,
|
||||
findLocalPluginBuilds,
|
||||
copyLocalBuild,
|
||||
} = require("./lib/bundled-plugins.cjs");
|
||||
|
||||
const root = path.resolve(__dirname, "..");
|
||||
@@ -20,11 +26,22 @@ const destination = path.join(root, "dist", "plugins");
|
||||
|
||||
async function main() {
|
||||
const plugins = loadBundledPlugins(root);
|
||||
const flag = process.argv.indexOf("--local");
|
||||
const localArg =
|
||||
flag !== -1 ? process.argv[flag + 1] : process.env.TERMIX_LOCAL_PLUGINS;
|
||||
const localDir = localArg ? path.resolve(root, localArg) : null;
|
||||
const local = findLocalPluginBuilds(localDir);
|
||||
|
||||
fs.rmSync(destination, { recursive: true, force: true });
|
||||
fs.mkdirSync(destination, { recursive: true });
|
||||
|
||||
for (const plugin of plugins) {
|
||||
const repo = local.get(plugin.id);
|
||||
if (repo) {
|
||||
copyLocalBuild(repo, path.join(destination, plugin.id));
|
||||
console.log(`copied local build of ${plugin.id}`);
|
||||
continue;
|
||||
}
|
||||
const buffer = await fetchArtifact(plugin, root);
|
||||
await extractArtifact(buffer, path.join(destination, plugin.id), plugin.id);
|
||||
console.log(`unpacked ${plugin.id}`);
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
fetchArtifact,
|
||||
extractArtifact,
|
||||
pinsFromIndex,
|
||||
findLocalPluginBuilds,
|
||||
copyLocalBuild,
|
||||
} from "./lib/bundled-plugins.cjs";
|
||||
|
||||
const cleanups: Array<() => void> = [];
|
||||
@@ -192,3 +194,39 @@ describe("pinsFromIndex", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("local plugin builds", () => {
|
||||
it("finds built repos by manifest id and skips unbuilt ones", () => {
|
||||
const dir = tempDir();
|
||||
const built = path.join(dir, "Plugin-Files");
|
||||
fs.mkdirSync(path.join(built, "dist"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(built, "manifest.json"),
|
||||
JSON.stringify({ id: "file-manager" }),
|
||||
);
|
||||
const unbuilt = path.join(dir, "Plugin-Other");
|
||||
fs.mkdirSync(unbuilt);
|
||||
fs.writeFileSync(
|
||||
path.join(unbuilt, "manifest.json"),
|
||||
JSON.stringify({ id: "other" }),
|
||||
);
|
||||
|
||||
const builds = findLocalPluginBuilds(dir);
|
||||
expect([...builds.keys()]).toEqual(["file-manager"]);
|
||||
expect(findLocalPluginBuilds(null).size).toBe(0);
|
||||
});
|
||||
|
||||
it("copies only the files a bundled plugin needs", () => {
|
||||
const repo = tempDir();
|
||||
fs.mkdirSync(path.join(repo, "dist"));
|
||||
fs.writeFileSync(path.join(repo, "dist", "frontend.js"), "x");
|
||||
fs.writeFileSync(path.join(repo, "manifest.json"), "{}");
|
||||
fs.mkdirSync(path.join(repo, "src"));
|
||||
|
||||
const out = path.join(tempDir(), "file-manager");
|
||||
copyLocalBuild(repo, out);
|
||||
expect(fs.existsSync(path.join(out, "dist", "frontend.js"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(out, "manifest.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(out, "src"))).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -20,6 +20,7 @@ const TSCONFIG = path.join(ROOT, "tsconfig.app.json");
|
||||
|
||||
const ALLOWED = [
|
||||
"ActionSlot",
|
||||
"AddButton",
|
||||
"Alert",
|
||||
"AlertDescription",
|
||||
"AlertDialog",
|
||||
@@ -100,6 +101,7 @@ const ALLOWED = [
|
||||
"FakeSwitch",
|
||||
"Field",
|
||||
"FieldPair",
|
||||
"FormFooter",
|
||||
"FullScreenAppPhase",
|
||||
"FullScreenAppWrapper",
|
||||
"GridCardCatalogEntry",
|
||||
@@ -124,6 +126,11 @@ const ALLOWED = [
|
||||
"Label",
|
||||
"LineChart",
|
||||
"LineChartSeries",
|
||||
"ListBadge",
|
||||
"ListRow",
|
||||
"ListRowAction",
|
||||
"ListRowFolder",
|
||||
"ListRowTone",
|
||||
"LogContext",
|
||||
"LogEntry",
|
||||
"MFAPromptMode",
|
||||
@@ -140,6 +147,7 @@ const ALLOWED = [
|
||||
"PROMPT_DESTRUCTIVE_BUTTON",
|
||||
"PROMPT_PRIMARY_BUTTON",
|
||||
"PanelDensity",
|
||||
"PanelList",
|
||||
"PanelSearch",
|
||||
"PanelShell",
|
||||
"PanelViewMode",
|
||||
|
||||
@@ -172,7 +172,51 @@ function pinsFromIndex(index, ids) {
|
||||
});
|
||||
}
|
||||
|
||||
const LOCAL_FILES = [
|
||||
"manifest.json",
|
||||
"dist",
|
||||
"locales",
|
||||
"migrations",
|
||||
"README.md",
|
||||
"CHANGELOG.json",
|
||||
];
|
||||
|
||||
/**
|
||||
* Built plugin repos under dir (each with manifest.json and dist/), by id.
|
||||
* Used in development to stage local plugin builds instead of the pins.
|
||||
*/
|
||||
function findLocalPluginBuilds(dir) {
|
||||
const builds = new Map();
|
||||
if (!dir || !fs.existsSync(dir)) return builds;
|
||||
for (const name of fs.readdirSync(dir)) {
|
||||
const repo = path.join(dir, name);
|
||||
const manifestPath = path.join(repo, "manifest.json");
|
||||
if (!fs.existsSync(manifestPath)) continue;
|
||||
if (!fs.existsSync(path.join(repo, "dist"))) continue;
|
||||
try {
|
||||
const { id } = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
||||
if (typeof id === "string" && ID.test(id)) builds.set(id, repo);
|
||||
} catch {
|
||||
// not a plugin repo
|
||||
}
|
||||
}
|
||||
return builds;
|
||||
}
|
||||
|
||||
/** Copies a local plugin build into the staging folder. */
|
||||
function copyLocalBuild(repo, destination) {
|
||||
fs.mkdirSync(destination, { recursive: true });
|
||||
for (const entry of LOCAL_FILES) {
|
||||
const from = path.join(repo, entry);
|
||||
if (fs.existsSync(from)) {
|
||||
fs.cpSync(from, path.join(destination, entry), { recursive: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findLocalPluginBuilds,
|
||||
copyLocalBuild,
|
||||
parseBundledPlugins,
|
||||
pinsFromIndex,
|
||||
loadBundledPlugins,
|
||||
|
||||
Reference in new issue
Block a user