35 lines
2.1 KiB
TypeScript
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;
|
|
}
|