email-builder-utils 1.1.22 → 1.1.23

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.
@@ -26,6 +26,10 @@ interface IProps {
26
26
  altText: string;
27
27
  cellWidths: number[];
28
28
  responsive?: boolean;
29
+ videoUrl?: string;
30
+ youtubeVideoUrl?: string;
31
+ thumbnailUrl?: string;
32
+ shape?: string;
29
33
  }
30
34
  interface IStyle {
31
35
  [key: string]: any;
@@ -1 +1 @@
1
- {"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../../src/types/Template.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,IAAI,YAAY;IAChB,KAAK,UAAU;IACf,QAAQ,WAAW;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,KAAK,UAAU;CAChB;AAED,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,WAAW,gBAAgB;CAC5B;AAED,UAAU,MAAM;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,MAAM;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH"}
1
+ {"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../../src/types/Template.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,IAAI,YAAY;IAChB,KAAK,UAAU;IACf,QAAQ,WAAW;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,KAAK,UAAU;CAChB;AAED,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,WAAW,gBAAgB;CAC5B;AAED,UAAU,MAAM;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH"}
@@ -8,6 +8,10 @@ interface BlockJsonProps {
8
8
  altText: string;
9
9
  imageUrl: string;
10
10
  responsive?: boolean;
11
+ videoUrl?: string;
12
+ youtubeVideoUrl?: string;
13
+ thumbnailUrl?: string;
14
+ shape?: string;
11
15
  }
12
16
  interface IBlockData {
13
17
  type: BlockType;
@@ -1 +1 @@
1
- {"version":3,"file":"jsonToHTML.d.ts","sourceRoot":"","sources":["../../src/utils/jsonToHTML.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAUrC,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,cAAc,CAAC;QACtB,KAAK,EAAE,GAAG,CAAC;QACX,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;KAC7B,CAAC;CACH;AAYD,eAAO,MAAM,gBAAgB,kDAAkD,CAAC;AA2DhF,wBAAsB,aAAa,CACjC,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,MAAM,mBAsBtB;AA2ZD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,mBA0I5E;AA0JD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,UAAU,mBAgJ5D"}
1
+ {"version":3,"file":"jsonToHTML.d.ts","sourceRoot":"","sources":["../../src/utils/jsonToHTML.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAUrC,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,cAAc,CAAC;QACtB,KAAK,EAAE,GAAG,CAAC;QACX,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;KAC7B,CAAC;CACH;AAOD,eAAO,MAAM,gBAAgB,kDAAkD,CAAC;AAiDhF,wBAAsB,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,mBAqB9F;AA2UD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,mBAmI5E;AAqJD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,UAAU,mBAuI5D"}
@@ -7,12 +7,7 @@ exports.convertShapeBlock = convertShapeBlock;
7
7
  const jimp_1 = require("jimp");
8
8
  const types_1 = require("../types");
9
9
  const common_1 = require("./common");
10
- const addPxToAttributes = [
11
- "fontSize",
12
- "lineHeight",
13
- "borderRadius",
14
- "borderWidth",
15
- ];
10
+ const addPxToAttributes = ["fontSize", "lineHeight", "borderRadius", "borderWidth"];
16
11
  const addPxOrPerToAttributes = ["width", "height"];
17
12
  const allPxAttributes = [...addPxToAttributes, ...addPxOrPerToAttributes];
18
13
  exports.tableCommonStyle = "border-collapse:collapse; table-layout:fixed;";
@@ -43,8 +38,7 @@ function buildStyles(style, { pxChanges, perChanges }) {
43
38
  return;
44
39
  if (value === undefined || value === null || value === "")
45
40
  return;
46
- if ((key === "padding" || key === "buttonPadding") &&
47
- typeof value === "object") {
41
+ if ((key === "padding" || key === "buttonPadding") && typeof value === "object") {
48
42
  const padding = value;
49
43
  value = `${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px`;
50
44
  }
@@ -140,15 +134,11 @@ function convertTextBlock(blockData) {
140
134
  perChanges: [],
141
135
  pxChanges: allPxAttributes,
142
136
  });
143
- const sanitizedText = (props.text ?? "")
144
- .replaceAll(/<p>/g, "<div>")
145
- .replaceAll(/<\/p>/g, "</div>");
137
+ const sanitizedText = (props.text ?? "").replaceAll(/<p>/g, "<div>").replaceAll(/<\/p>/g, "</div>");
146
138
  const navigateToUrl = props.navigateToUrl || "";
147
139
  const convertedTextBox = `<div style="display: inline-block; max-width: 100%; box-sizing: border-box; ${convertedTextStyle}">${sanitizedText.replaceAll(/\n/g, "<br>")}</div>`;
148
140
  const textContent = appendOutlookSupport(convertedTextBox, styles);
149
- return navigateToUrl
150
- ? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="color:inherit; text-decoration:none; cursor:pointer;">${textContent}</a>`
151
- : textContent;
141
+ return navigateToUrl ? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="color:inherit; text-decoration:none; cursor:pointer;">${textContent}</a>` : textContent;
152
142
  }
153
143
  async function appendOutlookForImage(content, outerContainerWidth, innerContainerWidth, imageUrl, style = {}) {
154
144
  const image = await jimp_1.Jimp.read(imageUrl);
@@ -161,12 +151,8 @@ async function appendOutlookForImage(content, outerContainerWidth, innerContaine
161
151
  const borderColor = style?.borderColor || "transparent";
162
152
  const borderRadius = parseInt(style?.borderRadius) || 0;
163
153
  const useRoundRect = borderRadius > 0;
164
- const arcsize = useRoundRect
165
- ? Math.min(borderRadius / scaledHeight, 1).toFixed(2)
166
- : "";
167
- const borderAttributes = borderWidth > 0
168
- ? `strokeweight="${borderWidth}px" strokecolor="${borderColor}"`
169
- : `stroked="false"`;
154
+ const arcsize = useRoundRect ? Math.min(borderRadius / scaledHeight, 1).toFixed(2) : "";
155
+ const borderAttributes = borderWidth > 0 ? `strokeweight="${borderWidth}px" strokecolor="${borderColor}"` : `stroked="false"`;
170
156
  const outlookImage = `<!--[if mso]>
171
157
  <v:${useRoundRect ? "roundrect" : "rect"} xmlns:v="urn:schemas-microsoft-com:vml"
172
158
  style="width:${scaledWidth}px;height:${scaledHeight}px;"
@@ -209,11 +195,7 @@ async function convertImageBlock(blockData, cellWidthInPx) {
209
195
  pxChanges: addPxToAttributes,
210
196
  });
211
197
  const imageElement = `<img src="${imageUrl}" alt="${altText}" style="${imageTagStyles}; max-width: ${originalWidth}px; max-height: ${originalHeight}px;" />`;
212
- const innerContainerWidth = ((typeof width === "string" ? parseInt(width.replace("%", "")) : width) /
213
- 100) *
214
- (cellWidthInPx -
215
- (style?.padding?.left || 0) -
216
- (style?.padding?.right || 0));
198
+ const innerContainerWidth = ((typeof width === "string" ? parseInt(width.replace("%", "")) : width) / 100) * (cellWidthInPx - (style?.padding?.left || 0) - (style?.padding?.right || 0));
217
199
  const outlookImage = await appendOutlookForImage(imageElement, cellWidthInPx, innerContainerWidth, imageUrl, style);
218
200
  const imageContent = appendOutlookSupport(outlookImage, containerStyles);
219
201
  return navigateToUrl
@@ -222,9 +204,7 @@ async function convertImageBlock(blockData, cellWidthInPx) {
222
204
  }
223
205
  function appendOutlookForButton(content, buttonStyle, navigateToUrl, text) {
224
206
  const { width = 200, height = 44, borderRadius = 0, borderColor = "transparent", borderWidth = 0, buttonColor = "none", buttonPadding = { top: 0, bottom: 0, left: 0, right: 0 }, color = "#000000", fontFamily = "Arial, sans-serif", fontSize = 16, fontWeight = 400, } = buttonStyle;
225
- const borderAttributes = borderWidth > 0
226
- ? `strokeweight="${borderWidth}px" strokecolor="${borderColor}"`
227
- : `stroked="false"`;
207
+ const borderAttributes = borderWidth > 0 ? `strokeweight="${borderWidth}px" strokecolor="${borderColor}"` : `stroked="false"`;
228
208
  return `
229
209
  <!--[if mso]>
230
210
  <v:${borderRadius ? "roundrect" : "rect"} xmlns:v="urn:schemas-microsoft-com:vml" href="${navigateToUrl}"
@@ -371,10 +351,7 @@ async function convertVideoBlock(blockData, cellWidthInPx) {
371
351
  else {
372
352
  percentWidth = "100%";
373
353
  }
374
- const innerContainerWidth = (parseFloat(percentWidth) / 100) *
375
- (cellWidthInPx -
376
- (style?.padding?.left || 0) -
377
- (style?.padding?.right || 0));
354
+ const innerContainerWidth = (parseFloat(percentWidth) / 100) * (cellWidthInPx - (style?.padding?.left || 0) - (style?.padding?.right || 0));
378
355
  const aspectRatio = 16 / 9;
379
356
  const calculatedHeight = innerContainerWidth / aspectRatio;
380
357
  const outerContainerStyles = buildStyles({
@@ -497,8 +474,7 @@ async function appendOutlookForShape(content, outerContainerWidth, innerContaine
497
474
  // pass raw flag so buildVMLShape knows if image already has text baked-in
498
475
  msoHasBakedText: Boolean(opts.msoBakeImageWithText),
499
476
  });
500
- const outlookAlignment = opts.alignment === "center" ? "center" :
501
- opts.alignment === "right" ? "right" : "left";
477
+ const outlookAlignment = opts.alignment === "center" ? "center" : opts.alignment === "right" ? "right" : "left";
502
478
  // Wrap the VML inside a table so Outlook aligns it correctly
503
479
  return `<!--[if mso]>
504
480
  <table align="${outlookAlignment}" border="0" cellpadding="0" cellspacing="0" style="display:inline-block;">
@@ -527,9 +503,7 @@ function buildVMLShape({ shape, widthPx, heightPx, imageUrl, backgroundColor, bo
527
503
  extraAttr = ` arcsize="${computeArcSize(borderRadius, widthPx)}"`;
528
504
  }
529
505
  // image fill (if provided)
530
- const fillMarkup = imageUrl
531
- ? `<v:fill src="${imageUrl}" type="frame" aspect="atleast" />`
532
- : "";
506
+ const fillMarkup = imageUrl ? `<v:fill src="${imageUrl}" type="frame" aspect="atleast" />` : "";
533
507
  // If MSO is given a baked image with text, don't produce a v:textbox overlay text (image already contains text)
534
508
  const includeTextbox = !!text && !msoHasBakedText;
535
509
  // v:textbox: use a table + cell to center the text; avoids many Word quirks
@@ -561,7 +535,7 @@ function buildVMLShape({ shape, widthPx, heightPx, imageUrl, backgroundColor, bo
561
535
  async function convertShapeBlock(blockData) {
562
536
  const { style, props } = blockData.data;
563
537
  const { shape, text, textColor = "#000000", imageUrl } = props || {};
564
- const { width = "100", height = "150", padding = {}, backgroundColor = "#2F80ED", borderRadius, borderWidth = 0, borderStyle = "solid", borderColor = "transparent", customCss, shapeColor, alignment = "left", msoBakeImageWithText } = style || {};
538
+ const { width = "100", height = "150", padding = {}, backgroundColor = "#2F80ED", borderRadius, borderWidth = 0, borderStyle = "solid", borderColor = "transparent", customCss, shapeColor, alignment = "left", msoBakeImageWithText, } = style || {};
565
539
  const borderRadiusMap = {
566
540
  rectangle: "0",
567
541
  rounded: "10px",
@@ -569,12 +543,8 @@ async function convertShapeBlock(blockData) {
569
543
  oval: "50%",
570
544
  };
571
545
  let resolvedBorderRadius = borderRadius || borderRadiusMap[shape] || "0";
572
- let resolvedWidthPx = typeof width === "number"
573
- ? width
574
- : parseInt(width.toString().replace("px", ""), 10) || 100;
575
- let resolvedHeightPx = typeof height === "number"
576
- ? height
577
- : parseInt(height.toString().replace("px", ""), 10) || 150;
546
+ let resolvedWidthPx = typeof width === "number" ? width : parseInt(width.toString().replace("px", ""), 10) || 100;
547
+ let resolvedHeightPx = typeof height === "number" ? height : parseInt(height.toString().replace("px", ""), 10) || 150;
578
548
  // Force circle → square
579
549
  if (shape === "circle") {
580
550
  const side = Math.min(resolvedWidthPx, resolvedHeightPx);
@@ -649,7 +619,7 @@ async function convertShapeBlock(blockData) {
649
619
  textColor,
650
620
  alignment,
651
621
  padding,
652
- msoBakeImageWithText
622
+ msoBakeImageWithText,
653
623
  });
654
624
  // Wrap in container table
655
625
  const containerTable = `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "email-builder-utils",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [