From f5ae3a30e8896d8d594d71b03d4b2a45b2775064 Mon Sep 17 00:00:00 2001 From: Kevin Brown Date: Mon, 20 Apr 2026 23:20:00 +0300 Subject: [PATCH] Fix function bundle to include MJML source files --- .../email/__tests__/templateCompiler.spec.ts | 17 +++++++++++++ src/actions/utils/email/templateCompiler.ts | 25 ++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/actions/utils/email/__tests__/templateCompiler.spec.ts b/src/actions/utils/email/__tests__/templateCompiler.spec.ts index 8ae61bed..0f2c8524 100644 --- a/src/actions/utils/email/__tests__/templateCompiler.spec.ts +++ b/src/actions/utils/email/__tests__/templateCompiler.spec.ts @@ -37,6 +37,11 @@ const importedExampleTemplate = createImportedEmailTemplate( exampleTemplateContent ) +const importedBundleSafeTemplate = createImportedEmailTemplate( + 'src/actions/utils/email/__fixtures__/missing-from-runtime-bundle.mjml', + exampleTemplateContent +) + describe('compileEmailTemplate', () => { it('compiles the moved contact message template from its imported source', async () => { const result = await compileEmailTemplate(contactMessageTemplate, { @@ -111,6 +116,18 @@ describe('compileEmailTemplate', () => { expect(result.text).toContain('Urgent message body') }) + it('compiles imported template content when the source file is absent at runtime', async () => { + const result = await compileEmailTemplate(importedBundleSafeTemplate, { + htmlMessage: 'Urgent message body', + items: ['Coffee Beans'], + name: 'Alex', + }) + + expect(result.html).toContain('Hello, Alex!') + expect(result.html).toContain('Coffee Beans') + expect(result.text).toContain('Urgent message body') + }) + it('throws ActionsFunctionError when MJML compilation reports errors', async () => { await expect(compileEmailTemplate(invalidTemplate)).rejects.toMatchObject({ appCode: 'EMAIL_TEMPLATE_COMPILE_FAILED', diff --git a/src/actions/utils/email/templateCompiler.ts b/src/actions/utils/email/templateCompiler.ts index 44bfe4af..b3f4c1f5 100644 --- a/src/actions/utils/email/templateCompiler.ts +++ b/src/actions/utils/email/templateCompiler.ts @@ -1,3 +1,4 @@ +import { existsSync } from 'node:fs' import { isAbsolute, relative, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { convert } from 'html-to-text' @@ -218,6 +219,22 @@ export const createEmailTemplate = ( } } +const createMjmlRenderOptions = (absolutePath: string): { + filePath?: string + keepComments: boolean +} => { + if (!existsSync(absolutePath)) { + return { + keepComments: false, + } + } + + return { + filePath: absolutePath, + keepComments: false, + } +} + const createPlainText = (html: string): string => convert(html, { wordwrap: 130, @@ -249,10 +266,10 @@ export async function compileEmailTemplate( const mjml2html = ( 'default' in mjmlModule ? mjmlModule.default : mjmlModule ) as MjmlRenderer - const { html, errors } = await mjml2html(mjmlWithData, { - filePath: absolutePath, - keepComments: false, - }) + const { html, errors } = await mjml2html( + mjmlWithData, + createMjmlRenderOptions(absolutePath) + ) if (errors.length > 0) { throw new ActionsFunctionError({