Files
site-builder/craft/scripts/sitesmith-catalog/render-entry.ts
T

35 lines
2.1 KiB
TypeScript

// Bundled by scripts/render-sitesmith-response.mjs (esbuild, platform node).
// Turns a Sitesmith JSON response into the HTML the REPO EXPORTER produces:
// the same sanitize -> flatten -> exportBodyHtml path the editor uses.
import { sanitizeAiTree, flattenTreeForCraft } from '../../src/utils/craft-tree';
import { exportBodyHtml, exportComposedPreviewHtml } from '../../src/utils/html-export';
import { DEFAULT_SITE_DESIGN } from '../../src/state/SiteDesignContext';
function stateFor(tree: any): string {
const clean = sanitizeAiTree(tree, new Set(), { n: 0 });
if (!clean) throw new Error('response tree root is not a known component');
const flat = flattenTreeForCraft(clean);
const root = {
type: { resolvedName: 'Container' }, isCanvas: true, props: { tag: 'div', style: {} }, displayName: 'Container',
custom: {}, hidden: false, parent: null, nodes: [flat.rootNodeId], linkedNodes: {},
};
flat.nodes[flat.rootNodeId].parent = 'ROOT';
return JSON.stringify({ ROOT: root, ...flat.nodes });
}
/** Mirrors SiteBuilderHead.php sb_font_awesome_link(): the backend adds this to published pages. */
const FA_LINK = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.3.1/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">';
export function renderResponse(resp: any, designOverrides: Record<string, any> = {}, pageIndex = 0) {
if (resp?.type !== 'replace') throw new Error(`only type=replace responses can be rendered (got ${resp?.type})`);
const design = { ...DEFAULT_SITE_DESIGN, ...designOverrides };
const page = resp.pages[pageIndex];
const pageState = stateFor(page.tree);
const hdr = resp.header ? exportBodyHtml(stateFor(resp.header.tree), 'header').html : '';
const ftr = resp.footer ? exportBodyHtml(stateFor(resp.footer.tree), 'footer').html : '';
const body = exportBodyHtml(pageState).html;
let html = exportComposedPreviewHtml(pageState, hdr + body + ftr, { title: page.name, includeFonts: true, design } as any);
if (/class="[^"]*\bfa-/.test(html) && !html.includes('font-awesome')) html = html.replace('</head>', () => `${FA_LINK}\n</head>`);
return html;
}