-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(root): refactor control compilation #7590
base: next
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
import { Liquid } from 'liquidjs'; | ||
|
||
export const parseLiquid = async (value: string, variables: object): Promise<string> => { | ||
export async function parseLiquid<T>(value: T, variables: object): Promise<T> { | ||
const valueStringified = JSON.stringify(value); | ||
const renderedString = await parseLiquidString(valueStringified, variables); | ||
|
||
return JSON.parse(renderedString); | ||
} | ||
|
||
export async function parseLiquidString(value: string, variables: object): Promise<string> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A small question, is it possible some how to reuse the same liquid instance from the framework SDK? The reason I'm asking is because we might want to add custom liquid filters to the system, and in this case we will have to duplicate them twice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point, i thought about it as well, we need to find a good way to export it from @novu/framework. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can export it from |
||
const client = new Liquid({ | ||
outputEscape: (output) => { | ||
return stringifyDataStructureWithSingleQuotes(output); | ||
|
@@ -10,7 +17,7 @@ export const parseLiquid = async (value: string, variables: object): Promise<str | |
const template = client.parse(value); | ||
|
||
return await client.render(template, variables); | ||
}; | ||
} | ||
|
||
const stringifyDataStructureWithSingleQuotes = (value: unknown, spaces: number = 0): string => { | ||
if (Array.isArray(value) || (typeof value === 'object' && value !== null)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Main purpose of this PR:
Previously, the framework would parse controls once before execution, and then parse them again during execution.
With this update, controls are parsed only once, improving efficiency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the
compileControls
flag required for this improvement?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is driven by two main reasons:
From the beginning, we relied on
maily.variable.type
, but there came a point when we considered decoupling frommaily.variable.type
and switching tomaily.text.type
using the simple text with{{...}}
syntax. This approach would allow us to manage variables independently using Liquid, a change I support because it grants us greater control and simplifies our codebase.Why is this important? If we do not control the content rendering process and the framework renders the controls before we execute the "render" step, it could lead to bugs like the one mentioned. Taking control of the rendering process helps prevent such issues.