@react-email/preview-server 4.1.0-canary.9 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +32 -32
  3. package/.next/build-manifest.json +14 -14
  4. package/.next/diagnostics/framework.json +1 -1
  5. package/.next/next-minimal-server.js.nft.json +1 -1
  6. package/.next/next-server.js.nft.json +1 -1
  7. package/.next/prerender-manifest.json +3 -3
  8. package/.next/required-server-files.json +1 -1
  9. package/.next/server/app/_not-found/page.js +1 -1
  10. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  11. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/favicon.ico/route.js +1 -1
  13. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  14. package/.next/server/app/page.js +1 -1
  15. package/.next/server/app/page.js.nft.json +1 -1
  16. package/.next/server/app/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/preview/[...slug]/page.js +356 -174
  18. package/.next/server/app/preview/[...slug]/page.js.nft.json +1 -1
  19. package/.next/server/app/preview/[...slug]/page_client-reference-manifest.js +1 -1
  20. package/.next/server/chunks/161.js +1 -0
  21. package/.next/server/chunks/277.js +1 -0
  22. package/.next/server/chunks/{879.js → 532.js} +7 -7
  23. package/.next/server/chunks/550.js +6 -0
  24. package/.next/server/chunks/834.js +15 -0
  25. package/.next/server/chunks/851.js +20 -0
  26. package/.next/server/middleware-build-manifest.js +1 -1
  27. package/.next/server/pages/500.html +1 -1
  28. package/.next/server/pages/_app.js +1 -1
  29. package/.next/server/pages/_app.js.nft.json +1 -1
  30. package/.next/server/pages/_document.js +1 -1
  31. package/.next/server/pages/_document.js.nft.json +1 -1
  32. package/.next/server/pages/_error.js +1 -1
  33. package/.next/server/pages/_error.js.nft.json +1 -1
  34. package/.next/server/server-reference-manifest.js +1 -1
  35. package/.next/server/server-reference-manifest.json +1 -1
  36. package/.next/static/{pT9c18D6E8gNsHAfpxTUA → 9kTcwkEeDkXsMQ7fDAu2v}/_buildManifest.js +1 -1
  37. package/.next/static/chunks/343-0aa226f42148dce4.js +1 -0
  38. package/.next/static/chunks/353-5e7d05b120b2e25f.js +1 -0
  39. package/.next/static/chunks/445-576b0c51a037fe4d.js +1 -0
  40. package/.next/static/chunks/483-fd8ad4ef179f4f6e.js +1 -0
  41. package/.next/static/chunks/624-9d1650c8211771cd.js +1 -0
  42. package/.next/static/chunks/755-01456539a6894956.js +1 -0
  43. package/.next/static/chunks/app/_not-found/{page-aee2c5619f94a965.js → page-e9c9ee8e737ce3f8.js} +1 -1
  44. package/.next/static/chunks/app/layout-8dda0c80b5cdbeb7.js +1 -0
  45. package/.next/static/chunks/app/page-ee81303e36f65d71.js +1 -0
  46. package/.next/static/chunks/app/preview/[...slug]/page-e54371fcb72010fe.js +1 -0
  47. package/.next/static/chunks/{04c799b8-f2be86d6e75dbf29.js → e8809b48-6a73b3f51ba71e9c.js} +1 -1
  48. package/.next/static/chunks/{f33a14d2-188715a58266ac15.js → f33a14d2-13f6de3d216cf617.js} +1 -1
  49. package/.next/static/chunks/framework-4f208795521d076c.js +1 -0
  50. package/.next/static/chunks/main-0000d0a5ac74fec0.js +1 -0
  51. package/.next/static/chunks/main-app-5ba7fd8e7a976edb.js +1 -0
  52. package/.next/static/chunks/pages/_app-550e3587fddcaa19.js +1 -0
  53. package/.next/static/chunks/pages/_error-870af0ad63b0e49e.js +1 -0
  54. package/.next/static/chunks/{webpack-c09dcf4c47767be8.js → webpack-fc6f324c4c88f6e3.js} +1 -1
  55. package/.next/static/css/48dcea18d820a298.css +3 -0
  56. package/.next/trace +27 -27
  57. package/CHANGELOG.md +29 -0
  58. package/package.json +6 -4
  59. package/readme.md +35 -0
  60. package/scripts/dev.mts +47 -0
  61. package/scripts/{fill-caniemail-data.mjs → fill-caniemail-data.mts} +0 -5
  62. package/scripts/seed.mts +21 -0
  63. package/scripts/utils/default-seed/auth/account-confirmation.tsx +68 -0
  64. package/scripts/utils/default-seed/auth/forgot-password.tsx +71 -0
  65. package/scripts/utils/default-seed/communications/payment-overdue.tsx +82 -0
  66. package/scripts/utils/default-seed/communications/team-invite.tsx +78 -0
  67. package/scripts/utils/default-seed/communications/webhooks-failed.tsx +89 -0
  68. package/scripts/utils/default-seed/feedback-request.tsx +78 -0
  69. package/scripts/utils/default-seed/marketing/changelog.tsx +98 -0
  70. package/src/actions/email-validation/__snapshots__/check-images.spec.tsx.snap +84 -0
  71. package/src/actions/email-validation/check-images.spec.tsx +1 -80
  72. package/src/app/layout.tsx +2 -2
  73. package/src/app/preview/[...slug]/preview.tsx +1 -1
  74. package/src/components/code-container.tsx +3 -1
  75. package/src/components/code.tsx +60 -59
  76. package/src/components/logo.tsx +68 -63
  77. package/src/components/send.tsx +8 -5
  78. package/src/components/shell.tsx +4 -1
  79. package/src/components/sidebar/file-tree-directory-children.tsx +4 -1
  80. package/src/components/toolbar.tsx +9 -5
  81. package/src/contexts/emails.tsx +2 -2
  82. package/src/contexts/preview.tsx +2 -2
  83. package/src/hooks/use-email-rendering-result.ts +2 -2
  84. package/src/utils/__snapshots__/get-email-component.spec.ts.snap +183 -1
  85. package/src/utils/caniemail/ast/get-used-style-properties.ts +1 -0
  86. package/src/utils/contains-email-template.spec.ts +12 -0
  87. package/src/utils/contains-email-template.ts +26 -9
  88. package/src/utils/get-email-component.spec.ts +3 -0
  89. package/.next/server/chunks/200.js +0 -1
  90. package/.next/server/chunks/3.js +0 -15
  91. package/.next/server/chunks/784.js +0 -6
  92. package/.next/server/chunks/823.js +0 -1
  93. package/.next/server/chunks/915.js +0 -20
  94. package/.next/static/chunks/188-e278e5f1e9c4067e.js +0 -1
  95. package/.next/static/chunks/336-0767fdc0ff1ceaa1.js +0 -1
  96. package/.next/static/chunks/551-d9ce0a77591e6bf7.js +0 -1
  97. package/.next/static/chunks/651-337b0388fdb8c85c.js +0 -1
  98. package/.next/static/chunks/713-6c7607cb54b8278e.js +0 -1
  99. package/.next/static/chunks/834-e77d5196a2631efe.js +0 -1
  100. package/.next/static/chunks/app/layout-4403d8068fbec772.js +0 -1
  101. package/.next/static/chunks/app/page-ddc5b5b5b8d2de0e.js +0 -1
  102. package/.next/static/chunks/app/preview/[...slug]/page-873416b81678fe6b.js +0 -1
  103. package/.next/static/chunks/framework-f71c687711cb40cc.js +0 -1
  104. package/.next/static/chunks/main-697e2f65b52ad05c.js +0 -1
  105. package/.next/static/chunks/main-app-deb9839bdc2bcbd4.js +0 -1
  106. package/.next/static/chunks/pages/_app-2e335329c12ac3e7.js +0 -1
  107. package/.next/static/chunks/pages/_error-73094c2ebe868f44.js +0 -1
  108. package/.next/static/css/692fd92effde156a.css +0 -3
  109. /package/.next/static/{pT9c18D6E8gNsHAfpxTUA → 9kTcwkEeDkXsMQ7fDAu2v}/_ssgManifest.js +0 -0
  110. /package/scripts/{build-preview-server.mjs → build-preview-server.mts} +0 -0
@@ -1,3 +1,185 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`getEmailComponent() > with a demo email template 1`] = `"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html dir="ltr" lang="en"><head><link rel="preload" as="image" href="/static/vercel-logo.png"/><link rel="preload" as="image" href="/static/vercel-user.png"/><link rel="preload" as="image" href="/static/vercel-arrow.png"/><link rel="preload" as="image" href="/static/vercel-team.png"/><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta name="x-apple-disable-message-reformatting"/><!--$--></head><body style="margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;background-color:rgb(255,255,255);padding-left:0.5rem;padding-right:0.5rem;font-family:ui-sans-serif, system-ui, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;, &quot;Noto Color Emoji&quot;"><div style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0" data-skip-in-text="true">Join Alan on Vercel<div> ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏</div></div><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-left:auto;margin-right:auto;margin-top:40px;margin-bottom:40px;max-width:465px;border-radius:0.25rem;border-width:1px;border-color:rgb(234,234,234);border-style:solid;padding:20px"><tbody><tr style="width:100%"><td><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:32px"><tbody><tr><td><img alt="Vercel Logo" height="37" src="/static/vercel-logo.png" style="margin-left:auto;margin-right:auto;margin-top:0px;margin-bottom:0px;display:block;outline:none;border:none;text-decoration:none" width="40"/></td></tr></tbody></table><h1 style="margin-left:0px;margin-right:0px;margin-top:30px;margin-bottom:30px;padding:0px;text-align:center;font-weight:400;font-size:24px;color:rgb(0,0,0)">Join <strong>Enigma</strong> on <strong>Vercel</strong></h1><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">Hello <!-- -->alanturing<!-- -->,</p><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px"><strong>Alan</strong> (<a href="mailto:alan.turing@example.com" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">alan.turing@example.com</a>) has invited you to the <strong>Enigma</strong> team on<!-- --> <strong>Vercel</strong>.</p><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation"><tbody><tr><td><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation"><tbody style="width:100%"><tr style="width:100%"><td align="right" data-id="__react-email-column"><img alt="alanturing&#x27;s profile picture" height="64" src="/static/vercel-user.png" style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none" width="64"/></td><td align="center" data-id="__react-email-column"><img alt="Arrow indicating invitation" height="9" src="/static/vercel-arrow.png" style="display:block;outline:none;border:none;text-decoration:none" width="12"/></td><td align="left" data-id="__react-email-column"><img alt="Enigma team logo" height="64" src="/static/vercel-team.png" style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none" width="64"/></td></tr></tbody></table></td></tr></tbody></table><table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:32px;margin-bottom:32px;text-align:center"><tbody><tr><td><a href="https://vercel.com" style="border-radius:0.25rem;background-color:rgb(0,0,0);padding-left:20px;padding-right:20px;padding-top:12px;padding-bottom:12px;text-align:center;font-weight:600;font-size:12px;color:rgb(255,255,255);text-decoration-line:none;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px" target="_blank"><span><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span><span style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px">Join the team</span><span><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span></a></td></tr></tbody></table><p style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">or copy and paste this URL into your browser:<!-- --> <a href="https://vercel.com" style="color:rgb(37,99,235);text-decoration-line:none" target="_blank">https://vercel.com</a></p><hr style="margin-left:0px;margin-right:0px;margin-top:26px;margin-bottom:26px;width:100%;border-width:1px;border-color:rgb(234,234,234);border-style:solid;border:none;border-top:1px solid #eaeaea"/><p style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin-top:16px;margin-bottom:16px">This invitation was intended for<!-- --> <span style="color:rgb(0,0,0)">alanturing</span>. This invite was sent from <span style="color:rgb(0,0,0)">204.13.186.218</span> <!-- -->located in<!-- --> <span style="color:rgb(0,0,0)">São Paulo, Brazil</span>. If you were not expecting this invitation, you can ignore this email. If you are concerned about your account&#x27;s safety, please reply to this email to get in touch with us.</p></td></tr></tbody></table><!--/$--></body></html>"`;
3
+ exports[`getEmailComponent() > with a demo email template 1`] = `
4
+ "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+ <html dir="ltr" lang="en">
6
+ <head>
7
+ <link rel="preload" as="image" href="/static/vercel-logo.png" />
8
+ <link rel="preload" as="image" href="/static/vercel-user.png" />
9
+ <link rel="preload" as="image" href="/static/vercel-arrow.png" />
10
+ <link rel="preload" as="image" href="/static/vercel-team.png" />
11
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
12
+ <meta name="x-apple-disable-message-reformatting" />
13
+ <!--$-->
14
+ </head>
15
+ <body
16
+ style='margin-left:auto;margin-right:auto;margin-top:auto;margin-bottom:auto;background-color:rgb(255,255,255);padding-left:0.5rem;padding-right:0.5rem;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'>
17
+ <div
18
+ style="display:none;overflow:hidden;line-height:1px;opacity:0;max-height:0;max-width:0"
19
+ data-skip-in-text="true">
20
+ Join Alan on Vercel
21
+ <div>
22
+  ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏ ‌​‍‎‏
23
+ </div>
24
+ </div>
25
+ <table
26
+ align="center"
27
+ width="100%"
28
+ border="0"
29
+ cellpadding="0"
30
+ cellspacing="0"
31
+ role="presentation"
32
+ style="margin-left:auto;margin-right:auto;margin-top:40px;margin-bottom:40px;max-width:465px;border-radius:0.25rem;border-width:1px;border-color:rgb(234,234,234);border-style:solid;padding:20px">
33
+ <tbody>
34
+ <tr style="width:100%">
35
+ <td>
36
+ <table
37
+ align="center"
38
+ width="100%"
39
+ border="0"
40
+ cellpadding="0"
41
+ cellspacing="0"
42
+ role="presentation"
43
+ style="margin-top:32px">
44
+ <tbody>
45
+ <tr>
46
+ <td>
47
+ <img
48
+ alt="Vercel Logo"
49
+ height="37"
50
+ src="/static/vercel-logo.png"
51
+ style="margin-left:auto;margin-right:auto;margin-top:0px;margin-bottom:0px;display:block;outline:none;border:none;text-decoration:none"
52
+ width="40" />
53
+ </td>
54
+ </tr>
55
+ </tbody>
56
+ </table>
57
+ <h1
58
+ style="margin-left:0px;margin-right:0px;margin-top:30px;margin-bottom:30px;padding:0px;text-align:center;font-weight:400;font-size:24px;color:rgb(0,0,0)">
59
+ Join <strong>Enigma</strong> on <strong>Vercel</strong>
60
+ </h1>
61
+ <p
62
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
63
+ Hello
64
+ <!-- -->alanturing<!-- -->,
65
+ </p>
66
+ <p
67
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
68
+ <strong>Alan</strong> (<a
69
+ href="mailto:alan.turing@example.com"
70
+ style="color:rgb(37,99,235);text-decoration-line:none"
71
+ target="_blank"
72
+ >alan.turing@example.com</a
73
+ >) has invited you to the <strong>Enigma</strong> team on<!-- -->
74
+ <strong>Vercel</strong>.
75
+ </p>
76
+ <table
77
+ align="center"
78
+ width="100%"
79
+ border="0"
80
+ cellpadding="0"
81
+ cellspacing="0"
82
+ role="presentation">
83
+ <tbody>
84
+ <tr>
85
+ <td>
86
+ <table
87
+ align="center"
88
+ width="100%"
89
+ border="0"
90
+ cellpadding="0"
91
+ cellspacing="0"
92
+ role="presentation">
93
+ <tbody style="width:100%">
94
+ <tr style="width:100%">
95
+ <td align="right" data-id="__react-email-column">
96
+ <img
97
+ alt="alanturing&#x27;s profile picture"
98
+ height="64"
99
+ src="/static/vercel-user.png"
100
+ style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none"
101
+ width="64" />
102
+ </td>
103
+ <td align="center" data-id="__react-email-column">
104
+ <img
105
+ alt="Arrow indicating invitation"
106
+ height="9"
107
+ src="/static/vercel-arrow.png"
108
+ style="display:block;outline:none;border:none;text-decoration:none"
109
+ width="12" />
110
+ </td>
111
+ <td align="left" data-id="__react-email-column">
112
+ <img
113
+ alt="Enigma team logo"
114
+ height="64"
115
+ src="/static/vercel-team.png"
116
+ style="border-radius:9999px;display:block;outline:none;border:none;text-decoration:none"
117
+ width="64" />
118
+ </td>
119
+ </tr>
120
+ </tbody>
121
+ </table>
122
+ </td>
123
+ </tr>
124
+ </tbody>
125
+ </table>
126
+ <table
127
+ align="center"
128
+ width="100%"
129
+ border="0"
130
+ cellpadding="0"
131
+ cellspacing="0"
132
+ role="presentation"
133
+ style="margin-top:32px;margin-bottom:32px;text-align:center">
134
+ <tbody>
135
+ <tr>
136
+ <td>
137
+ <a
138
+ href="https://vercel.com"
139
+ style="border-radius:0.25rem;background-color:rgb(0,0,0);padding-left:20px;padding-right:20px;padding-top:12px;padding-bottom:12px;text-align:center;font-weight:600;font-size:12px;color:rgb(255,255,255);text-decoration-line:none;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px"
140
+ target="_blank"
141
+ ><span
142
+ ><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span
143
+ ><span
144
+ style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px"
145
+ >Join the team</span
146
+ ><span
147
+ ><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span
148
+ ></a
149
+ >
150
+ </td>
151
+ </tr>
152
+ </tbody>
153
+ </table>
154
+ <p
155
+ style="font-size:14px;color:rgb(0,0,0);line-height:24px;margin-top:16px;margin-bottom:16px">
156
+ or copy and paste this URL into your browser:<!-- -->
157
+ <a
158
+ href="https://vercel.com"
159
+ style="color:rgb(37,99,235);text-decoration-line:none"
160
+ target="_blank"
161
+ >https://vercel.com</a
162
+ >
163
+ </p>
164
+ <hr
165
+ style="margin-left:0px;margin-right:0px;margin-top:26px;margin-bottom:26px;width:100%;border-width:1px;border-color:rgb(234,234,234);border-style:solid;border:none;border-top:1px solid #eaeaea" />
166
+ <p
167
+ style="color:rgb(102,102,102);font-size:12px;line-height:24px;margin-top:16px;margin-bottom:16px">
168
+ This invitation was intended for<!-- -->
169
+ <span style="color:rgb(0,0,0)">alanturing</span>. This invite was
170
+ sent from <span style="color:rgb(0,0,0)">204.13.186.218</span>
171
+ <!-- -->located in<!-- -->
172
+ <span style="color:rgb(0,0,0)">São Paulo, Brazil</span>. If you
173
+ were not expecting this invitation, you can ignore this email. If
174
+ you are concerned about your account&#x27;s safety, please reply
175
+ to this email to get in touch with us.
176
+ </p>
177
+ </td>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+ <!--/$-->
182
+ </body>
183
+ </html>
184
+ "
185
+ `;
@@ -1,3 +1,4 @@
1
+ /** biome-ignore-all lint/nursery/noNestedComponentDefinitions: There are no components here, just visitor functions */
1
2
  import traverse from '@babel/traverse';
2
3
  import type { AST } from '../../../actions/email-validation/check-compatibility';
3
4
  import { generateTailwindCssRules } from '../tailwind/generate-tailwind-rules';
@@ -51,6 +51,13 @@ describe('containsEmailTemplate()', () => {
51
51
  },
52
52
  ],
53
53
  },
54
+ {
55
+ absolutePath: '/fake/path/emails/first/second',
56
+ directoryName: 'first/second',
57
+ relativePath: 'first/second',
58
+ emailFilenames: ['email'],
59
+ subDirectories: [],
60
+ },
54
61
  {
55
62
  absolutePath: '/fake/path/emails/newsletters',
56
63
  directoryName: 'newsletters',
@@ -104,6 +111,11 @@ describe('containsEmailTemplate()', () => {
104
111
  },
105
112
  ],
106
113
  };
114
+
115
+ it('should work with collapsed email directory', () => {
116
+ expect(containsEmailTemplate('first/second/email', directory)).toBe(true);
117
+ });
118
+
107
119
  it('should work with email inside a single sub directory', () => {
108
120
  expect(containsEmailTemplate('welcome/koala-welcome', directory)).toBe(
109
121
  true,
@@ -14,20 +14,37 @@ export const containsEmailTemplate = (
14
14
  relativeEmailPath: string,
15
15
  directory: EmailsDirectory,
16
16
  ) => {
17
- const remainingSegments = relativeEmailPath
17
+ const emailPathSegments = relativeEmailPath
18
18
  .replace(directory.relativePath, '')
19
19
  .split('/')
20
20
  .filter(Boolean);
21
- if (remainingSegments.length === 1) {
22
- const emailFilename = removeFilenameExtension(remainingSegments[0]!);
21
+
22
+ return containsEmailPathSegments(emailPathSegments, directory);
23
+ };
24
+
25
+ const containsEmailPathSegments = (
26
+ relativeEmailSegments: string[],
27
+ directory: EmailsDirectory,
28
+ ) => {
29
+ if (relativeEmailSegments.length === 1) {
30
+ const emailFilename = removeFilenameExtension(relativeEmailSegments[0]!);
23
31
  return directory.emailFilenames.includes(emailFilename);
24
32
  }
25
- const subDirectory = directory.subDirectories.find(
26
- (sub) => sub.directoryName === remainingSegments[0],
27
- );
28
- if (subDirectory === undefined) {
29
- return false;
33
+
34
+ const remainingPath = relativeEmailSegments.join('/');
35
+
36
+ for (const subDirectory of directory.subDirectories) {
37
+ if (remainingPath.startsWith(subDirectory.directoryName)) {
38
+ const matchedSegments = subDirectory.directoryName
39
+ .split('/')
40
+ .filter(Boolean).length;
41
+
42
+ return containsEmailPathSegments(
43
+ relativeEmailSegments.slice(matchedSegments),
44
+ subDirectory,
45
+ );
46
+ }
30
47
  }
31
48
 
32
- return containsEmailTemplate(relativeEmailPath, subDirectory);
49
+ return false;
33
50
  };
@@ -34,6 +34,9 @@ describe('getEmailComponent()', () => {
34
34
  result.emailComponent,
35
35
  result.emailComponent.PreviewProps,
36
36
  ),
37
+ {
38
+ pretty: true,
39
+ },
37
40
  );
38
41
  expect(emailHtml).toMatchSnapshot();
39
42
  }