mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 09:30:59 +00:00
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import Handlebars from 'handlebars';
|
|
|
|
/** One numbered clause of a dynamic article, with optional nested bullets. */
|
|
export interface RenderedClause {
|
|
text: string;
|
|
bullets: string[];
|
|
}
|
|
|
|
/** A dynamic article ready for the Handlebars template. */
|
|
export interface RenderedArticle {
|
|
number: number;
|
|
title: string;
|
|
/** Set (instead of clauses) when the body is a single plain paragraph. */
|
|
paragraph?: string;
|
|
clauses: RenderedClause[];
|
|
}
|
|
|
|
/**
|
|
* Parse a template article body into clauses. Format: one clause per line;
|
|
* lines prefixed with "- " become bullets nested under the preceding clause.
|
|
* A body that reduces to a single clause without bullets renders as a plain
|
|
* paragraph rather than a numbered list of one.
|
|
*/
|
|
export function parseArticleBody(body: string): Pick<RenderedArticle, 'paragraph' | 'clauses'> {
|
|
const lines = (body ?? '')
|
|
.split('\n')
|
|
.map((line) => line.trim())
|
|
.filter((line) => line.length > 0);
|
|
|
|
const clauses: RenderedClause[] = [];
|
|
for (const line of lines) {
|
|
if (line.startsWith('- ')) {
|
|
const bullet = line.slice(2).trim();
|
|
if (clauses.length === 0) {
|
|
clauses.push({ text: bullet, bullets: [] });
|
|
} else {
|
|
clauses[clauses.length - 1].bullets.push(bullet);
|
|
}
|
|
} else {
|
|
clauses.push({ text: line, bullets: [] });
|
|
}
|
|
}
|
|
|
|
if (clauses.length === 1 && clauses[0].bullets.length === 0) {
|
|
return { paragraph: clauses[0].text, clauses: [] };
|
|
}
|
|
return { clauses };
|
|
}
|
|
|
|
/**
|
|
* Interpolate Handlebars placeholders ({{client.companyName}}, {{contractDate}},
|
|
* …) inside admin-authored template text against the contract view model.
|
|
* Malformed placeholders must never break document generation — fall back to
|
|
* the raw text.
|
|
*/
|
|
export function interpolateTemplateText(text: string, context: unknown): string {
|
|
if (!text || !text.includes('{{')) return text ?? '';
|
|
try {
|
|
return Handlebars.compile(text)(context);
|
|
} catch {
|
|
return text;
|
|
}
|
|
}
|