/** * Stand-in SIMPLIFICADO para o `renderToHtml()`/`renderEditorContent.js` * do legado (eden.md §2.2) — aquele renderer conhece toda a árvore * Tiptap (paragraph/heading/table/mergeField/conditional/...) e escapa * HTML nó a nó. Esta leva de backend não tem o editor visual real ainda * (`editor_content` é aceito como JSONB genérico, não validado), então * em vez de reimplementar aquele renderer pela metade, este módulo faz * só o mínimo necessário para `document_template_versions.html_content` * nunca ficar dessincronizado do `editor_content` salvo: * * - se `editor_content` tiver uma propriedade de nível raiz * `plainText` (string), ela é usada como o texto do documento; * - caso contrário, um placeholder determinístico é usado. * * NÃO deve ser confundido com o merge-engine (merge-engine.ts), que roda * DEPOIS, sobre o texto aqui extraído, para resolver `{{variavel}}`. */ export const EDITOR_CONTENT_PLACEHOLDER_TEXT = "[Conteúdo gerado pelo editor visual — renderização completa pendente de implementação]"; function escapeHtml(value: string): string { return value .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /** * Returns `editor_content.plainText` when present as a root-level string * property, or `null` otherwise. Never throws on a malformed/unexpected * shape — this leva doesn't validate the Tiptap tree at all (that's the * visual editor's job once it exists). */ export function extractPlainText(editorContent: unknown): string | null { if ( editorContent !== null && typeof editorContent === "object" && "plainText" in (editorContent as Record) && typeof (editorContent as Record).plainText === "string" ) { return (editorContent as { plainText: string }).plainText; } return null; } /** * `extractPlainText` with the deterministic placeholder as fallback — * this is the actual text fed to the merge engine at generation time * (documents.service.ts), never `null`/empty on that path. */ export function resolveSourceText(editorContent: unknown): string { const plainText = extractPlainText(editorContent); return plainText && plainText.length > 0 ? plainText : EDITOR_CONTENT_PLACEHOLDER_TEXT; } /** Recomputes `document_template_versions.html_content` (eden.md §1.2 step 2). */ export function renderEditorContentToHtml(editorContent: unknown): string { return `

${escapeHtml(resolveSourceText(editorContent))}

`; }