@useinsider/guido 3.1.1-beta.6b60896 → 3.1.1-beta.7145c7d

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 (68) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +69 -61
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +91 -81
  5. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +7 -7
  6. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +12 -20
  7. package/dist/components/organisms/header/EditorActions.vue.js +2 -2
  8. package/dist/components/organisms/header/EditorActions.vue2.js +51 -36
  9. package/dist/components/organisms/header/RightSlot.vue.js +10 -10
  10. package/dist/components/organisms/header/RightSlot.vue2.js +16 -13
  11. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +18 -17
  12. package/dist/composables/useHtmlCompiler.js +23 -21
  13. package/dist/composables/usePreviewMode.js +20 -16
  14. package/dist/composables/useSave.js +23 -15
  15. package/dist/composables/useStripo.js +44 -41
  16. package/dist/composables/validators/useLiquidValidator.js +42 -0
  17. package/dist/config/compiler/liquidCompilerRules.js +15 -0
  18. package/dist/config/compiler/recommendationCompilerRules.js +158 -44
  19. package/dist/config/compiler/utils/recommendationCompilerUtils.js +37 -36
  20. package/dist/config/migrator/checkboxMigrator.js +5 -3
  21. package/dist/config/migrator/radioButtonMigrator.js +14 -12
  22. package/dist/enums/extensions/recommendationBlock.js +14 -11
  23. package/dist/extensions/Blocks/CouponBlock/template.js +24 -13
  24. package/dist/extensions/Blocks/Recommendation/block.js +1 -1
  25. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +27 -11
  26. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +185 -172
  27. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +95 -93
  28. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +75 -73
  29. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +7 -5
  30. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +30 -29
  31. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -7
  32. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +3 -1
  33. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +20 -20
  34. package/dist/extensions/Blocks/Recommendation/templates/utils.js +57 -50
  35. package/dist/extensions/Blocks/Recommendation/utils/tagName.js +6 -6
  36. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +16 -17
  37. package/dist/extensions/DynamicContent/dynamic-content.js +17 -12
  38. package/dist/guido.css +1 -1
  39. package/dist/services/recommendationApi.js +15 -15
  40. package/dist/services/templateLibraryApi.js +48 -46
  41. package/dist/src/@types/config/index.d.ts +1 -1
  42. package/dist/src/@types/config/schemas.d.ts +20 -0
  43. package/dist/src/@types/config/types.d.ts +3 -1
  44. package/dist/src/@types/generic.d.ts +0 -1
  45. package/dist/src/@types/save-as-template.d.ts +1 -0
  46. package/dist/src/composables/useConfig.d.ts +8 -0
  47. package/dist/src/composables/validators/useLiquidValidator.d.ts +3 -0
  48. package/dist/src/config/compiler/liquidCompilerRules.d.ts +2 -0
  49. package/dist/src/enums/extensions/recommendationBlock.d.ts +3 -0
  50. package/dist/src/extensions/Blocks/CouponBlock/template.d.ts +2 -0
  51. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  52. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +5 -0
  53. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +5 -0
  54. package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
  55. package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -3
  56. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +20 -3
  57. package/dist/src/services/templateLibraryApi.d.ts +1 -1
  58. package/dist/src/stores/config.d.ts +72 -0
  59. package/dist/src/stores/preview.d.ts +3 -0
  60. package/dist/src/utils/genericUtil.d.ts +1 -1
  61. package/dist/src/utils/htmlCompiler.d.ts +2 -1
  62. package/dist/static/styles/base.css.js +7 -2
  63. package/dist/stores/preview.js +4 -3
  64. package/dist/utils/genericUtil.js +42 -20
  65. package/dist/utils/htmlCompiler.js +48 -41
  66. package/dist/utils/templatePreparation.js +35 -26
  67. package/dist/utils/tooltipUtils.js +4 -5
  68. package/package.json +3 -2
@@ -1,55 +1,60 @@
1
- import { ATTR_PRODUCT_IMAGE as m, ATTR_PRODUCT_NAME as p, ATTR_PRODUCT_OLD_PRICE as T, ATTR_PRODUCT_PRICE as u, ATTR_PRODUCT_OMNIBUS_PRICE as _, ATTR_PRODUCT_OMNIBUS_DISCOUNT as b, ATTR_PRODUCT_BUTTON as g, ATTR_CUSTOM_PREFIX as d } from "../constants/selectors.js";
2
- function R(t) {
1
+ import { ATTR_PRODUCT_IMAGE as m, ATTR_PRODUCT_NAME as b, ATTR_PRODUCT_OLD_PRICE as T, ATTR_PRODUCT_PRICE as _, ATTR_PRODUCT_OMNIBUS_PRICE as g, ATTR_PRODUCT_OMNIBUS_DISCOUNT as C, ATTR_PRODUCT_BUTTON as f, ATTR_CUSTOM_PREFIX as u } from "../constants/selectors.js";
2
+ function U(t) {
3
3
  return t.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
4
4
  }
5
- const O = Symbol("customCellHtml");
6
- function f(t, e) {
7
- const n = t[O];
8
- if (!n)
5
+ function R(t, e) {
6
+ const n = Object.values(e).find((r) => r.attributeName === t);
7
+ return (n == null ? void 0 : n.type) === "defaultAttribute";
8
+ }
9
+ function y(t, e) {
10
+ return R(t, e) ? t : `product_attribute.${t}`;
11
+ }
12
+ const P = Symbol("customCellHtml");
13
+ function S(t, e, n = {}) {
14
+ const r = t[P];
15
+ if (!r)
9
16
  return { ...t };
10
- const r = { ...t };
11
- return e.filter((o) => o.startsWith(d) && !r[o]).forEach((o) => {
12
- const s = o.substring(d.length), l = R(s);
13
- r[o] = (i) => {
14
- var a;
15
- const c = (a = i.product_attributes) == null ? void 0 : a[s];
16
- return n(
17
- s,
18
- c != null ? String(c) : l
19
- );
17
+ const l = { ...t };
18
+ return e.filter((o) => o.startsWith(u) && !l[o]).forEach((o) => {
19
+ const s = o.substring(u.length), a = U(s), D = y(s, n), O = R(s, n);
20
+ l[o] = (d) => {
21
+ var p;
22
+ const i = O ? d[s] : (p = d.product_attributes) == null ? void 0 : p[s];
23
+ let c = a;
24
+ return typeof i == "string" ? c = i : typeof i == "number" && (c = String(i)), r(D, c);
20
25
  };
21
- }), r;
26
+ }), l;
22
27
  }
23
- const h = {
28
+ const L = {
24
29
  TITLE: "You May Also Like!"
25
- }, I = [
30
+ }, M = [
26
31
  m,
27
- p,
32
+ b,
28
33
  T,
29
- u,
30
34
  _,
31
- b,
32
- g
33
- ], P = {
35
+ g,
36
+ C,
37
+ f
38
+ ], $ = {
34
39
  [m]: !0,
35
- [p]: !0,
36
- [u]: !0,
40
+ [b]: !0,
41
+ [_]: !0,
37
42
  [T]: !0,
38
- [_]: !1,
39
- [b]: !1,
40
- [g]: !0
41
- }, U = `
43
+ [g]: !1,
44
+ [C]: !1,
45
+ [f]: !0
46
+ }, h = `
42
47
  <tr>
43
48
  <td class="spacer" style="height: 10px;"></td>
44
49
  </tr>
45
- `, C = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
46
- function E(t) {
47
- return !t || typeof t != "string" || t.trim() === "" ? C : t.startsWith("http://") ? t.replace("http://", "https://") : t;
50
+ `, A = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
51
+ function w(t) {
52
+ return !t || typeof t != "string" || t.trim() === "" ? A : t.startsWith("http://") ? t.replace("http://", "https://") : t;
48
53
  }
49
- function D(t) {
54
+ function I(t) {
50
55
  return {
51
56
  name: "Product Name",
52
- image_url: C,
57
+ image_url: A,
53
58
  price: { USD: 18 },
54
59
  original_price: { USD: 20 },
55
60
  discount: { USD: 2 },
@@ -61,13 +66,13 @@ function D(t) {
61
66
  category: []
62
67
  };
63
68
  }
64
- function S(t = 6) {
69
+ function N(t = 6) {
65
70
  return Array.from(
66
71
  { length: t },
67
- (e, n) => D(String(n + 1))
72
+ (e, n) => I(String(n + 1))
68
73
  );
69
74
  }
70
- function y(t = "grid", e) {
75
+ function k(t = "grid", e) {
71
76
  const n = t === "list" ? `
72
77
  data-layout="list"` : "", r = e ? ` ${e}` : "";
73
78
  return `
@@ -105,7 +110,7 @@ function y(t = "grid", e) {
105
110
  </table>
106
111
  </td>
107
112
  </tr>
108
- ${U}
113
+ ${h}
109
114
  <tr>
110
115
  <td>
111
116
  <table
@@ -144,15 +149,17 @@ function y(t = "grid", e) {
144
149
  `;
145
150
  }
146
151
  export {
147
- O as CUSTOM_CELL_HTML,
148
- h as DEFAULTS,
149
- I as DEFAULT_CARD_COMPOSITION,
150
- P as DEFAULT_CARD_VISIBILITY,
151
- C as PLACEHOLDER_IMAGE,
152
- f as buildElementRenderer,
153
- y as createBlockTemplate,
154
- S as getDefaultProducts,
155
- E as sanitizeImageUrl,
156
- U as spacer,
157
- R as toDisplayName
152
+ P as CUSTOM_CELL_HTML,
153
+ L as DEFAULTS,
154
+ M as DEFAULT_CARD_COMPOSITION,
155
+ $ as DEFAULT_CARD_VISIBILITY,
156
+ A as PLACEHOLDER_IMAGE,
157
+ S as buildElementRenderer,
158
+ k as createBlockTemplate,
159
+ N as getDefaultProducts,
160
+ R as isDefaultAttribute,
161
+ y as resolveProductAttrValue,
162
+ w as sanitizeImageUrl,
163
+ h as spacer,
164
+ U as toDisplayName
158
165
  };
@@ -1,10 +1,10 @@
1
1
  function a(t) {
2
2
  return typeof t == "object" && t !== null && "tagName" in t && typeof t.tagName == "string";
3
3
  }
4
- function r(t) {
4
+ function n(t) {
5
5
  return typeof t == "object" && t !== null && "getTagName" in t && typeof t.getTagName == "function";
6
6
  }
7
- function n(t) {
7
+ function r(t) {
8
8
  return typeof t == "object" && t !== null && "getStyle" in t && typeof t.getStyle == "function";
9
9
  }
10
10
  function u(t) {
@@ -14,13 +14,13 @@ function g(t) {
14
14
  return typeof t == "object" && t !== null && "tagName" in t && t.tagName === "TD";
15
15
  }
16
16
  function p(t, e) {
17
- return !t || !n(t) ? null : t.getStyle(e);
17
+ return !t || !r(t) ? null : t.getStyle(e);
18
18
  }
19
19
  function N(t) {
20
- return !t || !u(t) ? null : t.parent();
20
+ return !t || !u(t) ? null : t.parent() ?? null;
21
21
  }
22
22
  function l(t, e = "UNKNOWN") {
23
- return t ? a(t) ? t.tagName.toUpperCase() : r(t) ? t.getTagName().toUpperCase() : e : e;
23
+ return t ? a(t) ? t.tagName.toUpperCase() : n(t) ? t.getTagName().toUpperCase() : e : e;
24
24
  }
25
25
  const f = /* @__PURE__ */ new Set(["TD", "BLOCK_IMAGE", "BLOCK_BUTTON"]);
26
26
  function i(t) {
@@ -36,7 +36,7 @@ function s(t) {
36
36
  export {
37
37
  s as getTableDisplayValue,
38
38
  l as getTagName,
39
- n as hasGetStyle,
39
+ r as hasGetStyle,
40
40
  u as hasParent,
41
41
  c as isTableCellNode,
42
42
  i as isTableCellTag,
@@ -1,35 +1,34 @@
1
- import { SettingsPanelRegistry as e, SettingsPanelTab as N, SettingsTab as t, TextControls as O } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ import { SettingsPanelRegistry as e, SettingsPanelTab as O, SettingsTab as t, TextControls as N } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { UNSUBSCRIBE_BLOCK_ID as I } from "./block.js";
3
3
  import { UNSUBSCRIBE_CONTROL_ID as _ } from "./control.js";
4
- class R extends e {
4
+ class o extends e {
5
5
  registerBlockControls(T) {
6
6
  T[I] = [
7
- new N(
7
+ new O(
8
8
  t.SETTINGS,
9
9
  [
10
10
  _,
11
- O.FORMAT,
12
- O.ALIGN,
13
- O.LINE_HEIGHT,
14
- O.DIRECTION,
15
- O.INTERNAL_INDENTS,
16
- O.HIDDEN_NODE
11
+ N.FORMAT,
12
+ N.ALIGN,
13
+ N.LINE_HEIGHT,
14
+ N.DIRECTION,
15
+ N.INTERNAL_INDENTS,
16
+ N.HIDDEN_NODE
17
17
  ]
18
18
  ),
19
- new N(
19
+ new O(
20
20
  t.STYLES,
21
21
  [
22
- O.TEXT_BLOCK_BACKGROUND_COLOR,
23
- O.FONT_FAMILY,
24
- O.FONT_SIZE,
25
- O.FONT_COLOR,
26
- O.FONT_BACKGROUND_COLOR,
27
- O.LINKS_COLOR
22
+ N.TEXT_BLOCK_BACKGROUND_COLOR,
23
+ N.FONT_FAMILY,
24
+ N.FONT_SIZE,
25
+ N.FONT_COLOR,
26
+ N.FONT_BACKGROUND_COLOR
28
27
  ]
29
28
  )
30
29
  ];
31
30
  }
32
31
  }
33
32
  export {
34
- R as SettingsPanel
33
+ o as SettingsPanel
35
34
  };
@@ -1,16 +1,17 @@
1
1
  var c = Object.defineProperty;
2
2
  var g = (o, s, t) => s in o ? c(o, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[s] = t;
3
3
  var r = (o, s, t) => g(o, typeof s != "symbol" ? s + "" : s, t);
4
- import { mergeTagToDynamicContent as d, dynamicContentToMergeTags as m } from "../../utils/genericUtil.js";
5
- import { UIElement as u, UIElementType as a, UEAttr as h, UIElementTagRegistry as T } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
- import { ExternalMergeTagsLibrary as y } from "./dynamic-content-modal.js";
7
- const l = "external-dynamic-content-ui-element", C = "button-add-dynamic-content";
8
- class p extends T {
4
+ import { useConfig as d } from "../../composables/useConfig.js";
5
+ import { mergeTagToDynamicContent as m, dynamicContentToMergeTags as u } from "../../utils/genericUtil.js";
6
+ import { UIElement as h, UIElementType as a, UEAttr as T, UIElementTagRegistry as y } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
+ import { ExternalMergeTagsLibrary as C } from "./dynamic-content-modal.js";
8
+ const l = "external-dynamic-content-ui-element", L = "button-add-dynamic-content";
9
+ class w extends y {
9
10
  registerUiElements(s) {
10
11
  s[a.MERGETAGS] = l;
11
12
  }
12
13
  }
13
- class b extends u {
14
+ class f extends h {
14
15
  constructor() {
15
16
  super(...arguments);
16
17
  r(this, "mergeTagsButton", null);
@@ -43,7 +44,7 @@ class b extends u {
43
44
  onAttributeUpdated(t, e) {
44
45
  if (t !== "mergeTag" || !(e != null && e.value))
45
46
  return;
46
- const n = d(e), i = this._getLastClickedPosition();
47
+ const n = m(e), i = this._getLastClickedPosition();
47
48
  this.lastClickedElement = null, this.lastClickedFrame = null, this._openDynamicContentLibrary(n, i);
48
49
  }
49
50
  openMergeTagLibrary() {
@@ -55,10 +56,14 @@ class b extends u {
55
56
  * Dispatches event with dynamic content data and position
56
57
  */
57
58
  _openDynamicContentLibrary(t, e) {
58
- this.mergeTagsLibrary || (this.mergeTagsLibrary = new y()), this.mergeTagsLibrary.openMergeTagsLibrary(
59
+ this.mergeTagsLibrary || (this.mergeTagsLibrary = new C()), this.mergeTagsLibrary.openMergeTagsLibrary(
59
60
  t,
60
61
  (n) => {
61
- n.text && n.value ? this.api.triggerValueChange(m([n])[0]) : this.api.triggerValueChange(null);
62
+ if (n.text && n.value) {
63
+ const { isFeatureEnabled: i } = d();
64
+ this.api.triggerValueChange(u([n], i("liquidSyntax"))[0]);
65
+ } else
66
+ this.api.triggerValueChange(null);
62
67
  },
63
68
  e
64
69
  );
@@ -142,7 +147,7 @@ class b extends u {
142
147
  <${a.BUTTON}
143
148
  id="guido__btn-add-dynamic-content"
144
149
  class="btn btn-primary"
145
- ${h.BUTTON.name}="${C}">
150
+ ${T.BUTTON.name}="${L}">
146
151
  <${a.ICON} src="plus" class="icon icon-button color-primary">
147
152
  </${a.ICON}>
148
153
  ${this.api.translate("Add Dynamic Content")}
@@ -151,6 +156,6 @@ class b extends u {
151
156
  }
152
157
  }
153
158
  export {
154
- p as DynamicContentTagRegistry,
155
- b as DynamicContentUiElementExtension
159
+ w as DynamicContentTagRegistry,
160
+ f as DynamicContentUiElementExtension
156
161
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-3b53a736],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-079d2bf7] .in-progress-wrapper__progress p span:last-child{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.editor-actions[data-v-acff76a8]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-a26d7792]{position:relative;width:100%;height:calc(100vh - 128px)}.guido-editor__container[data-v-a26d7792]{width:100%;height:calc(100vh - 128px)}.guido-editor__no-header[data-v-a26d7792]{height:calc(100vh - 75px)}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-df672485]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-df672485]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-df672485]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-df672485]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-df672485]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-29b9af29] .vueperslides__bullets,[data-v-dd1a237a] .vueperslides__bullets{pointer-events:none!important}[data-v-dd1a237a] .vueperslides__parallax-wrapper{height:110px!important}[data-v-d073b1dc] .vueperslides__bullets{pointer-events:none!important}[data-v-d073b1dc] .vueperslides__parallax-wrapper{height:110px!important}
1
+ .gap-16[data-v-3b53a736],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.editor-actions[data-v-4e2a4adb]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-25780af6]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-25780af6]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-25780af6]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-df672485]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-df672485]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-df672485]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-df672485]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-df672485]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-29b9af29] .vueperslides__bullets,[data-v-dd1a237a] .vueperslides__bullets{pointer-events:none!important}[data-v-dd1a237a] .vueperslides__parallax-wrapper{height:110px!important}[data-v-d073b1dc] .vueperslides__bullets{pointer-events:none!important}[data-v-d073b1dc] .vueperslides__parallax-wrapper{height:110px!important}
@@ -1,34 +1,34 @@
1
- import { useHttp as c } from "../composables/useHttp.js";
2
- import { URLS as m } from "../enums/extensions/recommendationBlock.js";
3
- const f = () => {
4
- const { get: o } = c();
1
+ import { useHttp as a } from "../composables/useHttp.js";
2
+ import { QUERY_PARAMS as d, URLS as h } from "../enums/extensions/recommendationBlock.js";
3
+ const y = () => {
4
+ const { get: r } = a(), { get: s } = a({ headers: {} }), m = "6KcLM9TwheVB1mgK";
5
5
  return {
6
6
  fetchRecommendationCreateData: async () => {
7
7
  try {
8
- return (await o("/newsletter/recommendations/create-data")).data;
8
+ return (await r("/newsletter/recommendations/create-data")).data;
9
9
  } catch (e) {
10
10
  throw console.error("fetchUserModalState error:", e), e;
11
11
  }
12
12
  },
13
13
  fetchRecommendationFilters: async () => {
14
14
  try {
15
- const { data: e } = await o("/stripo/email-recommendation-attributes");
15
+ const { data: e } = await r("/stripo/email-recommendation-attributes");
16
16
  return e;
17
17
  } catch (e) {
18
18
  throw console.error("fetchRecommendationFilters error:", e), e;
19
19
  }
20
20
  },
21
- fetchRecommendationProducts: async (e, a) => {
21
+ fetchRecommendationProducts: async (e, i) => {
22
22
  var n;
23
23
  try {
24
- const t = decodeURIComponent(new URLSearchParams(Object.entries(a)).toString());
25
- console.debug("🏁 Recommendation API Query:", t);
26
- const { get: s } = c({
27
- headers: {}
28
- }), r = await s(
29
- `${m.RECOMMENDATION_API_URL}/v2/${e}?${t}`
24
+ const t = new URLSearchParams(Object.entries(i));
25
+ t.set(d.CLIENT_ID, m);
26
+ const c = decodeURIComponent(t.toString());
27
+ console.debug("🏁 Recommendation API Query:", c);
28
+ const o = await s(
29
+ `${h.RECOMMENDATION_API_URL}/v2/${e}?${c}`
30
30
  );
31
- return ((n = r == null ? void 0 : r.data) == null ? void 0 : n.data) ?? [];
31
+ return ((n = o == null ? void 0 : o.data) == null ? void 0 : n.data) ?? [];
32
32
  } catch (t) {
33
33
  throw console.error("fetchRecommendationProducts error:", t), t;
34
34
  }
@@ -36,5 +36,5 @@ const f = () => {
36
36
  };
37
37
  };
38
38
  export {
39
- f as useRecommendationApi
39
+ y as useRecommendationApi
40
40
  };
@@ -1,14 +1,15 @@
1
- import { useConfig as T } from "../composables/useConfig.js";
2
- import { useHttp as f } from "../composables/useHttp.js";
3
- import { useToaster as w } from "../composables/useToaster.js";
4
- import { useTranslations as b } from "../composables/useTranslations.js";
5
- import { EditorType as h } from "../enums/defaults.js";
6
- import { useRecommendationExtensionStore as C } from "../extensions/Blocks/Recommendation/store/recommendation.js";
7
- import { useSaveAsTemplateStore as v } from "../stores/save-as-template.js";
8
- import { base64EncodeWithSpecialChars as a } from "../utils/base64.js";
9
- import { useTemplatePreparation as S } from "../utils/templatePreparation.js";
10
- const R = () => {
11
- const { get: n, post: c } = f(), { handleError: o, showToaster: i } = w(), { config: l } = T(), p = b();
1
+ import { useConfig as w } from "../composables/useConfig.js";
2
+ import { useHttp as b } from "../composables/useHttp.js";
3
+ import { useToaster as h } from "../composables/useToaster.js";
4
+ import { useTranslations as C } from "../composables/useTranslations.js";
5
+ import { useLiquidValidator as S } from "../composables/validators/useLiquidValidator.js";
6
+ import { EditorType as v } from "../enums/defaults.js";
7
+ import { useRecommendationExtensionStore as N } from "../extensions/Blocks/Recommendation/store/recommendation.js";
8
+ import { useSaveAsTemplateStore as x } from "../stores/save-as-template.js";
9
+ import { base64EncodeWithSpecialChars as r } from "../utils/base64.js";
10
+ import { useTemplatePreparation as A } from "../utils/templatePreparation.js";
11
+ const $ = () => {
12
+ const { get: n, post: m } = b(), { handleError: o, showToaster: l } = h(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: g } = S(), u = C();
12
13
  return {
13
14
  getCategories: async () => {
14
15
  try {
@@ -26,7 +27,7 @@ const R = () => {
26
27
  },
27
28
  createCategory: async (e) => {
28
29
  try {
29
- const { data: { id: t } } = await c(
30
+ const { data: { id: t } } = await m(
30
31
  "/newsletter/template-library/create-category",
31
32
  { name: e }
32
33
  );
@@ -36,55 +37,56 @@ const R = () => {
36
37
  }
37
38
  },
38
39
  createTemplate: async () => {
39
- var e, t, g, y;
40
+ var e, t, d, y;
40
41
  try {
41
- const { prepareTemplateDetails: m } = S(), r = v(), s = await m(), u = {
42
- name: r.getTemplateName,
43
- categories: r.getSelectedCategoryIds,
44
- productId: ((t = (e = l.value) == null ? void 0 : e.partner) == null ? void 0 : t.productType) || 0,
45
- editorType: h,
46
- messageType: ((y = (g = l.value) == null ? void 0 : g.partner) == null ? void 0 : y.messageType) || 0,
47
- content: a(s.compiledHtml),
48
- css: a(s.css),
42
+ const { prepareTemplateDetails: i } = A(), s = x(), a = await i();
43
+ if (p("liquidSyntax") && !await g(a.compiledHtml))
44
+ return !1;
45
+ const f = {
46
+ name: s.getTemplateName,
47
+ categories: s.getSelectedCategoryIds,
48
+ productId: ((t = (e = c.value) == null ? void 0 : e.partner) == null ? void 0 : t.productType) || 0,
49
+ editorType: v,
50
+ messageType: ((y = (d = c.value) == null ? void 0 : d.partner) == null ? void 0 : y.messageType) || 0,
51
+ content: r(a.compiledHtml),
52
+ css: r(a.css),
49
53
  unsubscriptionPreferencePageStatus: !1,
50
54
  unsubscriptionPreferencePages: [],
51
- recommendationCampaignUrls: a(
52
- C().recommendationCampaignUrls
55
+ recommendationCampaignUrls: r(
56
+ N().recommendationCampaignUrls
53
57
  ),
54
- recommendationConfigs: a({}),
58
+ recommendationConfigs: r({}),
55
59
  isGuido: !0,
56
- stripoConfig: a({
60
+ // eslint-disable-next-line camelcase
61
+ template_engine: p("liquidSyntax") ? 1 : 0,
62
+ stripoConfig: r({
57
63
  editor: "stripo",
58
- html: s.rawHtml,
59
- css: s.css
64
+ html: a.rawHtml,
65
+ css: a.css
60
66
  })
61
- }, { data: { type: d } } = await c(
67
+ }, { data: { type: T } } = await m(
62
68
  "/newsletter/template-library/create-template",
63
- u
69
+ f
64
70
  );
65
- if (d === "alert") {
66
- i({
67
- message: p(
68
- "newsletter.template-library-save-alert",
69
- { templateName: r.getTemplateName }
70
- ),
71
- type: "alert"
72
- });
73
- return;
74
- }
75
- i({
76
- message: p(
71
+ return T === "alert" ? (l({
72
+ message: u(
73
+ "newsletter.template-library-save-alert",
74
+ { templateName: s.getTemplateName }
75
+ ),
76
+ type: "alert"
77
+ }), !1) : (l({
78
+ message: u(
77
79
  "newsletter.template-library-save-success",
78
- { templateName: r.getTemplateName }
80
+ { templateName: s.getTemplateName }
79
81
  ),
80
82
  type: "success"
81
- });
82
- } catch (m) {
83
- o(m, "Failed to create template");
83
+ }), !0);
84
+ } catch (i) {
85
+ return o(i, "Failed to create template"), !1;
84
86
  }
85
87
  }
86
88
  };
87
89
  };
88
90
  export {
89
- R as useTemplateLibraryApi
91
+ $ as useTemplateLibraryApi
90
92
  };
@@ -8,7 +8,7 @@
8
8
  * - Validation utilities
9
9
  */
10
10
  export { MessageType, ProductType, GuidoConfigSchema, IdentitySchema, PartnerSchema, TemplateSchema, EditorSchema, UISchema, FeaturesSchema, BlocksSchema, CompilerSchema, CallbacksSchema, DynamicContentSchema, EmailHeaderSchema, DefaultBlockTypeSchema, CustomBlockTypeSchema, CompilerRuleSchema, CompilerRuleTypeSchema, ReplaceRuleSchema, RegexRuleSchema, RemoveRuleSchema, CustomRuleSchema, } from './schemas';
11
- export type { GuidoConfig, GuidoConfigInput, IdentityConfig, IdentityConfigInput, PartnerConfig, PartnerConfigInput, TemplateConfig, TemplateConfigInput, EditorConfig, EditorConfigInput, UIConfig, UIConfigInput, FeaturesConfig, FeaturesConfigInput, BlocksConfig, BlocksConfigInput, CompilerConfig, CompilerConfigInput, CallbacksConfig, CallbacksConfigInput, ExternalValidationHandler, EmailHeader, DynamicContent, DefaultBlockType, CustomBlockType, BlockType, FeatureName, CompilerRule, ReplaceRule, RegexRule, RemoveRule, CustomRule, DeepPartial, ConfigOverrides, } from './types';
11
+ export type { GuidoConfig, GuidoConfigInput, IdentityConfig, IdentityConfigInput, PartnerConfig, PartnerConfigInput, FallbackFont, TemplateConfig, TemplateConfigInput, EditorConfig, EditorConfigInput, UIConfig, UIConfigInput, FeaturesConfig, FeaturesConfigInput, BlocksConfig, BlocksConfigInput, CompilerConfig, CompilerConfigInput, CallbacksConfig, CallbacksConfigInput, ExternalValidationHandler, EmailHeader, DynamicContent, DefaultBlockType, CustomBlockType, BlockType, FeatureName, CompilerRule, ReplaceRule, RegexRule, RemoveRule, CustomRule, DeepPartial, ConfigOverrides, } from './types';
12
12
  export { DEFAULT_EMAIL_HEADER, DEFAULT_TEMPLATE, DEFAULT_EDITOR, DEFAULT_UI, DEFAULT_FEATURES, DEFAULT_BLOCKS, DEFAULT_COMPILER, DEFAULT_PRODUCT_TYPE, DEFAULT_MESSAGE_TYPE, DEFAULT_USERNAME, EDITOR_TYPE, TEST_PARTNERS, isTestPartner, } from './defaults';
13
13
  export { validateConfig, parseConfig, parseConfigSafe, getValidationErrors, isValidConfig, validateIdentity, validatePartner, } from './validator';
14
14
  export type { ValidationResult, ValidationError, } from './validator';
@@ -47,6 +47,12 @@ export declare const IdentitySchema: v.ObjectSchema<{
47
47
  /**
48
48
  * Partner configuration - organization and product context
49
49
  */
50
+ export declare const FallbackFontSchema: v.ObjectSchema<{
51
+ /** Fallback font name (e.g., "Georgia") */
52
+ readonly name: v.StringSchema<undefined>;
53
+ /** Fallback font family (e.g., "serif" or "sans-serif") */
54
+ readonly family: v.StringSchema<undefined>;
55
+ }, undefined>;
50
56
  export declare const PartnerSchema: v.ObjectSchema<{
51
57
  /** Partner/organization name (required) */
52
58
  readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "partner.name is required">]>;
@@ -56,6 +62,13 @@ export declare const PartnerSchema: v.ObjectSchema<{
56
62
  readonly messageType: v.OptionalSchema<v.PicklistSchema<[1, 2], undefined>, 1>;
57
63
  /** Display name for the current user */
58
64
  readonly username: v.OptionalSchema<v.StringSchema<undefined>, "Guido User">;
65
+ /** Fallback font settings from partner settings — used to match backend size calculation */
66
+ readonly fallbackFont: v.OptionalSchema<v.ObjectSchema<{
67
+ /** Fallback font name (e.g., "Georgia") */
68
+ readonly name: v.StringSchema<undefined>;
69
+ /** Fallback font family (e.g., "serif" or "sans-serif") */
70
+ readonly family: v.StringSchema<undefined>;
71
+ }, undefined>, undefined>;
59
72
  }, undefined>;
60
73
  /**
61
74
  * Dynamic content item schema
@@ -405,6 +418,13 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
405
418
  readonly messageType: v.OptionalSchema<v.PicklistSchema<[1, 2], undefined>, 1>;
406
419
  /** Display name for the current user */
407
420
  readonly username: v.OptionalSchema<v.StringSchema<undefined>, "Guido User">;
421
+ /** Fallback font settings from partner settings — used to match backend size calculation */
422
+ readonly fallbackFont: v.OptionalSchema<v.ObjectSchema<{
423
+ /** Fallback font name (e.g., "Georgia") */
424
+ readonly name: v.StringSchema<undefined>;
425
+ /** Fallback font family (e.g., "serif" or "sans-serif") */
426
+ readonly family: v.StringSchema<undefined>;
427
+ }, undefined>, undefined>;
408
428
  }, undefined>;
409
429
  /** Template content and presets */
410
430
  readonly template: v.OptionalSchema<v.ObjectSchema<{
@@ -5,7 +5,7 @@
5
5
  * This ensures type definitions are always in sync with validation.
6
6
  * @module @types/config/types
7
7
  */
8
- import type { GuidoConfigSchema, IdentitySchema, PartnerSchema, TemplateSchema, EditorSchema, UISchema, FeaturesSchema, BlocksSchema, CompilerSchema, CallbacksSchema, DynamicContentSchema, EmailHeaderSchema, CompilerRuleSchema, ReplaceRuleSchema, RegexRuleSchema, RemoveRuleSchema, CustomRuleSchema, DefaultBlockTypeSchema, CustomBlockTypeSchema, ExternalValidationHandler } from './schemas';
8
+ import type { GuidoConfigSchema, IdentitySchema, PartnerSchema, TemplateSchema, EditorSchema, UISchema, FeaturesSchema, BlocksSchema, CompilerSchema, CallbacksSchema, DynamicContentSchema, EmailHeaderSchema, CompilerRuleSchema, ReplaceRuleSchema, RegexRuleSchema, RemoveRuleSchema, CustomRuleSchema, DefaultBlockTypeSchema, CustomBlockTypeSchema, FallbackFontSchema, ExternalValidationHandler } from './schemas';
9
9
  import type * as v from 'valibot';
10
10
  /**
11
11
  * Complete validated Guido configuration.
@@ -29,6 +29,8 @@ export type GuidoConfig = v.InferOutput<typeof GuidoConfigSchema>;
29
29
  export type IdentityConfig = v.InferOutput<typeof IdentitySchema>;
30
30
  /** Partner configuration (name, productType, messageType, username) */
31
31
  export type PartnerConfig = v.InferOutput<typeof PartnerSchema>;
32
+ /** Fallback font settings for backend size calculation alignment */
33
+ export type FallbackFont = v.InferOutput<typeof FallbackFontSchema>;
32
34
  /** Template configuration (html, css, dynamic content, unsubscribe pages) */
33
35
  export type TemplateConfig = v.InferOutput<typeof TemplateSchema>;
34
36
  /** Editor configuration (locale, translations, migration date, email header) */
@@ -44,7 +44,6 @@ export interface TooltipOptions {
44
44
  x: number;
45
45
  y: number;
46
46
  };
47
- preventXss?: boolean;
48
47
  }
49
48
  export type TextValueObject = {
50
49
  text: string;
@@ -26,4 +26,5 @@ export interface CreateTemplateRequest {
26
26
  unsubscriptionPreferencePages: number[];
27
27
  unsubscriptionPreferencePageStatus: boolean;
28
28
  isGuido: boolean;
29
+ template_engine: number;
29
30
  }
@@ -17,6 +17,10 @@ export declare const useConfig: () => {
17
17
  productType: 60 | 49 | 97;
18
18
  messageType: 1 | 2;
19
19
  username: string;
20
+ fallbackFont?: {
21
+ name: string;
22
+ family: string;
23
+ } | undefined;
20
24
  };
21
25
  template: {
22
26
  html: string;
@@ -110,6 +114,10 @@ export declare const useConfig: () => {
110
114
  productType: 60 | 49 | 97;
111
115
  messageType: 1 | 2;
112
116
  username: string;
117
+ fallbackFont?: {
118
+ name: string;
119
+ family: string;
120
+ } | undefined;
113
121
  } | null>;
114
122
  template: import("vue").ComputedRef<{
115
123
  html: string;
@@ -0,0 +1,3 @@
1
+ export declare const useLiquidValidator: () => {
2
+ validateLiquidSyntax: (compiledHtml: string) => Promise<boolean>;
3
+ };
@@ -0,0 +1,2 @@
1
+ import type { CompilerRule } from '@@/Types/html-compiler';
2
+ export declare const liquidCompilerRules: CompilerRule[];