Skip to content
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

fix(api-service): fix & simplify email liquid parsing #7519

Conversation

ChmaraX
Copy link
Contributor

@ChmaraX ChmaraX commented Jan 15, 2025

What changed? Why was the change needed?

Screenshots

Expand for optional sections

Related enterprise PR

Special notes for your reviewer

Copy link

netlify bot commented Jan 15, 2025

Deploy Preview for dev-web-novu ready!

Name Link
🔨 Latest commit 8caea26
🔍 Latest deploy log https://app.netlify.com/sites/dev-web-novu/deploys/6787d35d746e8a00084ee1e0
😎 Deploy Preview https://deploy-preview-7519.dashboard.novu-staging.co
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Comment on lines +162 to +166
try {
iterableArray = JSON.parse(iterableArrayString.replace(/'/g, '"'));
} catch (error) {
throw new Error(`Failed to parse iterable value for "${iterablePath}": ${error.message}`);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

safeguard since we are calling JSON.parse() on something that is output from liquid, which parses something that user provides etc

const iterablePath = node.attrs[MailyAttrsEnum.EACH_KEY];
const nodeContent = node.content || [];
const expandedContent: TipTapNode[] = [];

const iterableArray = this.getValueByPath(variables, iterablePath);
const iterableArrayString = await parseLiquid(iterablePath, variables);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Liquid engine to extract the array from payload instead of finding it manually.

Copy link

netlify bot commented Jan 15, 2025

Deploy Preview for dashboard-v2-novu-staging ready!

Name Link
🔨 Latest commit 8caea26
🔍 Latest deploy log https://app.netlify.com/sites/dashboard-v2-novu-staging/deploys/6787d35db1b4280008d1af85
😎 Deploy Preview https://deploy-preview-7519.dashboard-v2.novu-staging.co
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@@ -31,47 +31,6 @@ export const forSnippet = {
},
],
},
{
Copy link
Contributor Author

@ChmaraX ChmaraX Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing logic that tested nested for loops - we dont want to support that

@@ -64,7 +67,7 @@ export class BuildPayloadSchema {

for (const [key, value] of Object.entries(controlValue)) {
if (isStringTipTapNode(value)) {
processedValue[key] = transformMailyContentToLiquid(JSON.parse(value));
processedValue[key] = this.hydrateEmailSchemaUseCase.execute({ emailEditor: value });
Copy link
Contributor Author

@ChmaraX ChmaraX Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized HydrateEmailSchemaUseCase (I dont understand the naming) does the same as transformMailyContentToLiquid

I think at some point we should merge the HydrateEmailSchemaUseCase and ExpandEmailEditorSchema to single usecase - there is no reason to transform Maily JSON to Liquid in multiple usecases like Maily -> Hydrate -> Expand -> ParseByLiquid, where each usecases does a little bit of transformation. They can't be used standalone anyway.

It would be better to have one usecase which gets Maily JSON and outputs HTML parsed by Liquid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree 100%

Comment on lines +130 to +160
function wrapInLiquidOutput(
variableName: string,
fallback?: string,
forLoopVariable?: string,
): string {
const sanitizedVariableName = sanitizeVariableName(variableName);
const sanitizedForLoopVariable =
forLoopVariable && sanitizeVariableName(forLoopVariable);

/*
* Handle loop variable replacement
* payload.comments.name => payload.comments[0].name
*/
const processedName =
sanitizedForLoopVariable &&
sanitizedVariableName.startsWith(sanitizedForLoopVariable)
? sanitizedVariableName.replace(
sanitizedForLoopVariable,
`${sanitizedForLoopVariable}[${MAILY_ITERABLE_MARK}]`,
)
: sanitizedVariableName;

// Build liquid output syntax
const fallbackSuffix = fallback ? ` | default: '${fallback}'` : '';

return `{{ ${processedName}${fallbackSuffix} }}`;
}

function sanitizeVariableName(variableName: string): string {
return variableName.replace(/{{|}}/g, '').trim();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks complicated but I only added payload.comments.name => {{ payload.comments[0].name }}, the "0" is important for us down the line and this is the simplest place to put the transformation for now.

@ChmaraX ChmaraX changed the title fix(api): fix & simplify email liquid parsing fix(api-service): fix & simplify email liquid parsing Jan 15, 2025
@@ -64,7 +67,7 @@ export class BuildPayloadSchema {

for (const [key, value] of Object.entries(controlValue)) {
if (isStringTipTapNode(value)) {
processedValue[key] = transformMailyContentToLiquid(JSON.parse(value));
processedValue[key] = this.hydrateEmailSchemaUseCase.execute({ emailEditor: value });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree 100%

@ChmaraX ChmaraX merged commit 16358ce into next Jan 15, 2025
37 of 39 checks passed
@ChmaraX ChmaraX deleted the nv-5182-NV-5194-apiemail-for-use-liquid-for-loop-syntax-parsing-directly branch January 15, 2025 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants