// lib/cfgReaders.js // Config readers -- one resolution rule (ARCHITECTURE.md 5.4) const { getState } = require("@saltcorn/data/db/state"); const { PLUGIN_NAME, ROLE_PUBLIC } = require("./constants"); const { DEFAULT_LAYOUT_TREE } = require("./layoutTree"); function getActiveThemeId(cfg) { return cfg?.activeThemeId || null; } function getActiveByRole(cfg) { return cfg?.activeByRole || {}; } function activeThemeIdForRole(cfg, roleId) { // role override then global const byRole = getActiveByRole(cfg); return byRole[roleId] != null ? byRole[roleId] : getActiveThemeId(cfg); } function isLayoutMode(cfg) { return !!cfg?.layoutMode; } function activeHashHint(cfg, roleId){ return (cfg && cfg.activeHash) || "0"; } // SYNC resolution of the active layout tree (so wrap() stays synchronous): the // per-role tree, else the default tree, else the built-in default preset. // activate.js persists these into cfg alongside the pointer when layout mode is on. function activeLayoutTree(cfg, roleId) { const byRole = (cfg && cfg.activeLayoutTreeByRole) || {}; const roleTree = roleId != null ? (byRole[roleId] ?? byRole[String(roleId)]) : null; return roleTree || (cfg && cfg.activeLayoutTree) || DEFAULT_LAYOUT_TREE; } // Replicate getLayout's fallback precedence WITHOUT reading the pluginName field the // last-installed fallback omits (state.ts:419-425). A request renders via theme-builder when // layout_by_role[role] names us OR (no layout_by_role entry for that role AND theme-builder is // the last-installed/only registered layout). (folded review fix -- see 5.7/7.6) function requestRendersViaThemeBuilder(req) { const state = getState(); if (!state.layouts[PLUGIN_NAME]) return false; // not registered as a layout (Phase 1) const role = req.user?.role_id ?? ROLE_PUBLIC; const byRole = state.getConfig("layout_by_role", {}) || {}; const mapped = byRole[role] ?? byRole[String(role)]; if (mapped != null) return mapped === PLUGIN_NAME; // role branch is authoritative // no layout_by_role entry for this role -> falls through to per-user / last-installed. // theme-builder is selected by the fallback iff it is the last-installed layout key. const keys = Object.keys(state.layouts); return keys.length > 0 && keys[keys.length - 1] === PLUGIN_NAME; } module.exports = { getActiveThemeId, getActiveByRole, activeThemeIdForRole, isLayoutMode, activeHashHint, activeLayoutTree, requestRendersViaThemeBuilder, };