53 lines
2.3 KiB
JavaScript
53 lines
2.3 KiB
JavaScript
// lib/activePointer.js
|
|
// Active-pointer write: persist -> re-register -> propagate -> refresh assets (ARCHITECTURE.md 5.5)
|
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
const { getState } = require("@saltcorn/data/db/state");
|
|
const db = require("@saltcorn/data/db");
|
|
const { PLUGIN_NAME } = require("./constants");
|
|
|
|
// Resolve the install-name row defensively: _sc_plugins.name is the INSTALL name, which
|
|
// is NOT guaranteed to equal plugin_name. Try the canonical name, then fall back to scanning
|
|
// for the row whose module resolves to plugin_name. (folded review fix: read/write name-space split)
|
|
async function findPluginRow() {
|
|
let p = await Plugin.findOne({ name: PLUGIN_NAME });
|
|
if (p) return p;
|
|
const all = await Plugin.find({});
|
|
return all.find((r) => {
|
|
const mod = getState().plugins[PLUGIN_NAME];
|
|
return mod && (getState().plugin_module_names[r.name] === PLUGIN_NAME || r.name === PLUGIN_NAME);
|
|
}) || null;
|
|
}
|
|
|
|
|
|
async function setActivePointer(patch /* {activeThemeId?|activeByRole?|activeHash?} */) {
|
|
const plugin = await findPluginRow();
|
|
if (!plugin) throw new Error("theme-builder plugin row not found");
|
|
plugin.configuration = { ...(plugin.configuration || {}), ...patch };
|
|
await plugin.upsert(); // _sc_plugins (plugin.ts:104-119)
|
|
await Plugin.loadPlugin(plugin); // re-register -> re-run headers(cfg)
|
|
await getState().refresh_views(); // REBUILD assets_by_role (Fix 1)
|
|
getState().processSend({ refresh_plugin_cfg: PLUGIN_NAME, tenant: db.getTenantSchema() });
|
|
return plugin.configuration;
|
|
}
|
|
|
|
|
|
// READ: live merged cfg, no DB hit.
|
|
function getActivePointer() {
|
|
const cfg = getState().plugin_cfgs[PLUGIN_NAME] || {};
|
|
return { activeThemeId: cfg.activeThemeId || null, activeByRole: cfg.activeByRole || {},
|
|
activeHash: cfg.activeHash || "0" };
|
|
}
|
|
|
|
|
|
// Remove every activeByRole entry whose value === id, then persist the scrubbed map.
|
|
async function dropRoleRefs(id) {
|
|
const { activeByRole } = getActivePointer();
|
|
const scrubbed = {};
|
|
for (const role of Object.keys(activeByRole)) {
|
|
if (activeByRole[role] !== id) scrubbed[role] = activeByRole[role];
|
|
}
|
|
return setActivePointer({ activeByRole: scrubbed });
|
|
}
|
|
|
|
|
|
module.exports = { setActivePointer, getActivePointer, findPluginRow, dropRoleRefs };
|