mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
refactor bridge plugin into virtual module
This commit is contained in:
@@ -1,46 +1,42 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const {
|
||||
installObsidianPlugin,
|
||||
isObsidianPluginInstalled,
|
||||
} = require("./plugin-system/obsidian-plugin");
|
||||
|
||||
const BRIDGE_PLUGIN_ID = "ignis-bridge";
|
||||
const BRIDGE_PLUGIN_DIR = path.join(__dirname, "..", "..", "..", "packages", "bridge");
|
||||
|
||||
// .ignis metadata helpers
|
||||
// Old vaults still have bridge in .obsidian/plugins from before it became virtual.
|
||||
async function migratePluginFromVault(vaultPath, vaultName, pluginId) {
|
||||
let didWork = false;
|
||||
|
||||
async function getIgnisMeta(vaultPath) {
|
||||
const metaFile = path.join(vaultPath, ".ignis", "meta.json");
|
||||
const pluginDir = path.join(vaultPath, ".obsidian", "plugins", pluginId);
|
||||
|
||||
if (await fs.promises.stat(pluginDir).catch(() => null)) {
|
||||
await fs.promises.rm(pluginDir, { recursive: true, force: true });
|
||||
didWork = true;
|
||||
}
|
||||
|
||||
const cpFile = path.join(vaultPath, ".obsidian", "community-plugins.json");
|
||||
|
||||
try {
|
||||
const content = await fs.promises.readFile(metaFile, "utf-8");
|
||||
return JSON.parse(content);
|
||||
} catch {
|
||||
return {};
|
||||
const list = JSON.parse(await fs.promises.readFile(cpFile, "utf-8"));
|
||||
|
||||
if (Array.isArray(list)) {
|
||||
const filtered = list.filter((id) => id !== pluginId);
|
||||
|
||||
if (filtered.length !== list.length) {
|
||||
await fs.promises.writeFile(cpFile, JSON.stringify(filtered));
|
||||
didWork = true;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (didWork) {
|
||||
console.log(`[ignis] Migrated ${pluginId} out of vault: ${vaultName}`);
|
||||
}
|
||||
|
||||
return didWork;
|
||||
}
|
||||
|
||||
async function setIgnisMeta(vaultPath, data) {
|
||||
const ignisDir = path.join(vaultPath, ".ignis");
|
||||
const metaFile = path.join(ignisDir, "meta.json");
|
||||
|
||||
await fs.promises.mkdir(ignisDir, { recursive: true });
|
||||
await fs.promises.writeFile(metaFile, JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
||||
// Bridge plugin install/check
|
||||
|
||||
async function isBridgePluginInstalled(vaultPath) {
|
||||
return isObsidianPluginInstalled(BRIDGE_PLUGIN_ID, vaultPath);
|
||||
}
|
||||
|
||||
async function installBridgePlugin(vaultPath) {
|
||||
const result = await installObsidianPlugin(BRIDGE_PLUGIN_DIR, vaultPath);
|
||||
return result.installed;
|
||||
}
|
||||
|
||||
async function updateBridgePluginInAllVaults(vaultRoot) {
|
||||
async function migratePluginsFromAllVaults(vaultRoot, pluginIds) {
|
||||
if (!(await fs.promises.stat(vaultRoot).catch(() => null))) {
|
||||
return;
|
||||
}
|
||||
@@ -53,18 +49,14 @@ async function updateBridgePluginInAllVaults(vaultRoot) {
|
||||
}
|
||||
|
||||
const vaultPath = path.join(vaultRoot, entry.name);
|
||||
const installed = await installBridgePlugin(vaultPath);
|
||||
|
||||
if (installed) {
|
||||
console.log(`[ignis] Installed bridge plugin in vault: ${entry.name}`);
|
||||
for (const pluginId of pluginIds) {
|
||||
await migratePluginFromVault(vaultPath, entry.name, pluginId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
installBridgePlugin,
|
||||
updateBridgePluginInAllVaults,
|
||||
isBridgePluginInstalled,
|
||||
getIgnisMeta,
|
||||
setIgnisMeta,
|
||||
BRIDGE_PLUGIN_ID,
|
||||
migratePluginsFromAllVaults,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Vault provisioning for demo sessions.
|
||||
//
|
||||
// Copies the template into a session-prefixed dir, installs the bridge plugin, and registers the vault on the session.
|
||||
// Copies the template into a session-prefixed dir and registers the vault on the session.
|
||||
// Re-provisions if disk was wiped under an existing session.
|
||||
|
||||
const fs = require("fs");
|
||||
@@ -8,7 +8,6 @@ const fsp = fs.promises;
|
||||
const path = require("path");
|
||||
|
||||
const config = require("../config");
|
||||
const { installBridgePlugin } = require("../bridge-plugin");
|
||||
const bootstrapRoutes = require("../routes/bootstrap");
|
||||
|
||||
const { sessions, makeStorageName } = require("./demo-sessions");
|
||||
@@ -96,9 +95,6 @@ async function provisionVault(sessionId, userVaultName) {
|
||||
// Copy template (default: Welcome.md, Getting Started.md, .obsidian/*).
|
||||
await fsp.cp(config.demoTemplateDir, vaultPath, { recursive: true });
|
||||
|
||||
// Install bridge plugin
|
||||
await installBridgePlugin(vaultPath);
|
||||
|
||||
config.refreshVaults();
|
||||
bootstrapRoutes.invalidateVault(storageName);
|
||||
|
||||
|
||||
@@ -9,7 +9,10 @@ const {
|
||||
watcher,
|
||||
writeCoalescer,
|
||||
} = require("@ignis/server-core");
|
||||
const { updateBridgePluginInAllVaults } = require("./bridge-plugin");
|
||||
const {
|
||||
BRIDGE_PLUGIN_ID,
|
||||
migratePluginsFromAllVaults,
|
||||
} = require("./bridge-plugin");
|
||||
const { initPlugins, shutdownPlugins } = require("./plugin-system/manager");
|
||||
const pluginRoutes = require("./routes/plugins");
|
||||
writeCoalescer.configure({ writeCoalesceMs: config.writeCoalesceMs });
|
||||
@@ -170,7 +173,7 @@ const server = app.listen(config.port, async () => {
|
||||
console.log(`[ignis] Vault root: ${config.vaultRoot}`);
|
||||
console.log(`[ignis] Vaults: ${Object.keys(config.vaults).join(", ")}`);
|
||||
|
||||
await updateBridgePluginInAllVaults(config.vaultRoot);
|
||||
await migratePluginsFromAllVaults(config.vaultRoot, [BRIDGE_PLUGIN_ID]);
|
||||
await initPlugins({ app, config, wss, watcher });
|
||||
bootstrapRoutes
|
||||
.warmUp()
|
||||
|
||||
16
apps/ignis-server/server/routes/bootstrap.js
vendored
16
apps/ignis-server/server/routes/bootstrap.js
vendored
@@ -9,7 +9,6 @@ const fsp = fs.promises;
|
||||
const path = require("path");
|
||||
const zlib = require("zlib");
|
||||
const config = require("../config");
|
||||
const { isBridgePluginInstalled, getIgnisMeta } = require("../bridge-plugin");
|
||||
const { getDiscoveredPlugins } = require("../plugin-system/manager");
|
||||
|
||||
const router = express.Router();
|
||||
@@ -76,20 +75,13 @@ async function walkTree(rootPath) {
|
||||
return { tree, dirMtimes };
|
||||
}
|
||||
|
||||
async function buildVaultInfo(vaultId, vaultPath) {
|
||||
const pluginInstalled = await isBridgePluginInstalled(vaultPath);
|
||||
const ignisMeta = await getIgnisMeta(vaultPath);
|
||||
|
||||
function buildVaultInfo(vaultId, vaultPath) {
|
||||
return {
|
||||
id: vaultId,
|
||||
name: vaultId,
|
||||
path: vaultPath,
|
||||
platform: process.platform,
|
||||
version: config.obsidianVersion,
|
||||
ignisPlugin: {
|
||||
installed: pluginInstalled,
|
||||
prompted: ignisMeta.pluginPrompted || false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -134,10 +126,8 @@ async function buildEntry(vaultId) {
|
||||
}
|
||||
|
||||
const t0 = Date.now();
|
||||
const [vault, { tree, dirMtimes }] = await Promise.all([
|
||||
buildVaultInfo(vaultId, vaultPath),
|
||||
walkTree(vaultPath),
|
||||
]);
|
||||
const vault = buildVaultInfo(vaultId, vaultPath);
|
||||
const { tree, dirMtimes } = await walkTree(vaultPath);
|
||||
|
||||
const response = {
|
||||
vault,
|
||||
|
||||
@@ -2,12 +2,6 @@ const express = require("express");
|
||||
const fs = require("fs");
|
||||
const config = require("../config");
|
||||
const path = require("path");
|
||||
const {
|
||||
isBridgePluginInstalled,
|
||||
getIgnisMeta,
|
||||
setIgnisMeta,
|
||||
installBridgePlugin,
|
||||
} = require("../bridge-plugin");
|
||||
const bootstrapRoutes = require("./bootstrap");
|
||||
|
||||
const router = express.Router();
|
||||
@@ -34,19 +28,12 @@ router.get("/info", async (req, res) => {
|
||||
return res.status(404).json({ error: "Vault not found", id: vaultId });
|
||||
}
|
||||
|
||||
const pluginInstalled = await isBridgePluginInstalled(vaultPath);
|
||||
const ignisMeta = await getIgnisMeta(vaultPath);
|
||||
|
||||
res.json({
|
||||
id: vaultId,
|
||||
name: vaultId,
|
||||
path: vaultPath,
|
||||
platform: process.platform,
|
||||
version: config.obsidianVersion,
|
||||
ignisPlugin: {
|
||||
installed: pluginInstalled,
|
||||
prompted: ignisMeta.pluginPrompted || false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,8 +53,6 @@ router.post("/create", async (req, res) => {
|
||||
recursive: false,
|
||||
});
|
||||
|
||||
await installBridgePlugin(vaultPath);
|
||||
|
||||
config.refreshVaults();
|
||||
bootstrapRoutes.invalidateVault(name);
|
||||
|
||||
@@ -138,42 +123,4 @@ router.delete("/remove", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// POST /api/vault/install-plugin { vault, dismiss } - install plugin or mark as prompted
|
||||
router.post("/install-plugin", async (req, res) => {
|
||||
const vaultId = req.body?.vault;
|
||||
const dismiss = req.body?.dismiss || false;
|
||||
|
||||
if (!vaultId) {
|
||||
return res.status(400).json({ error: "Missing vault ID" });
|
||||
}
|
||||
|
||||
const vaultPath = config.getVaultPath(vaultId);
|
||||
|
||||
if (!vaultPath) {
|
||||
return res.status(404).json({ error: "Vault not found" });
|
||||
}
|
||||
|
||||
try {
|
||||
const meta = await getIgnisMeta(vaultPath);
|
||||
|
||||
if (dismiss) {
|
||||
// User clicked "Don't Ask Again" or "Not Now"
|
||||
meta.pluginPrompted = true;
|
||||
await setIgnisMeta(vaultPath, meta);
|
||||
|
||||
return res.json({ ok: true, prompted: true });
|
||||
} else {
|
||||
// User wants to install the plugin
|
||||
const installed = await installBridgePlugin(vaultPath);
|
||||
|
||||
meta.pluginPrompted = true;
|
||||
await setIgnisMeta(vaultPath, meta);
|
||||
|
||||
return res.json({ ok: true, installed, prompted: true });
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: e.message, code: e.code });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user