twenty / packages /twenty-shared /src /utils /rich-text-variable-resolver.ts
Jules
Initial clean CRM deployment with prebuilt assets
d9494a5
Raw
History Blame Contribute Delete
1.54 kB
import { isDefined } from '@/utils/validation';
import { evalFromContext } from './evalFromContext';
const VARIABLE_TAG_PATTERN =
/\{"type":"variableTag","attrs":\{"variable":"(\{\{[^{}]+\}\})"\}\}|\{"attrs":\{"variable":"(\{\{[^{}]+\}\})"\},"type":"variableTag"\}/g;
const escapeJsonString = (text: string): string => {
return JSON.stringify(text).slice(1, -1);
};
const buildTextNodesWithLineBreaks = (text: string): string => {
const lines = text.split('\n');
if (lines.length === 1) {
return `{"type":"text","text":"${escapeJsonString(text)}"}`;
}
return lines
.map((line, index) => {
const textNode = `{"type":"text","text":"${escapeJsonString(line)}"}`;
if (index < lines.length - 1) {
return `${textNode},{"type":"hardBreak"}`;
}
return textNode;
})
.join(',');
};
export const resolveRichTextVariables = (
input: string | null | undefined,
context: Record<string, unknown>,
): string | undefined => {
if (!isDefined(input)) {
return undefined;
}
return input.replace(
VARIABLE_TAG_PATTERN,
(_, variableTypeFirst: string, variableAttrsFirst: string) => {
const variable = variableTypeFirst ?? variableAttrsFirst;
const resolvedValue = evalFromContext(variable, context);
const textValue = !isDefined(resolvedValue)
? ''
: typeof resolvedValue === 'object'
? JSON.stringify(resolvedValue)
: String(resolvedValue);
return buildTextNodesWithLineBreaks(textValue);
},
);
};