@useinsider/guido 2.0.0-beta.b889d81 → 2.0.0-beta.c0d8594

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 (47) hide show
  1. package/README.md +2 -0
  2. package/dist/@types/config/schemas.js +3 -1
  3. package/dist/components/Guido.vue.js +1 -1
  4. package/dist/components/Guido.vue2.js +15 -17
  5. package/dist/components/organisms/header/LeftSlot.vue.js +12 -12
  6. package/dist/components/organisms/header/LeftSlot.vue2.js +6 -6
  7. package/dist/composables/useStripo.js +40 -40
  8. package/dist/config/migrator/index.js +9 -8
  9. package/dist/config/migrator/itemsBlockMigrator.js +283 -0
  10. package/dist/extensions/Blocks/Items/block.js +39 -40
  11. package/dist/extensions/Blocks/Items/controls/button/link.js +22 -29
  12. package/dist/extensions/Blocks/Items/controls/cardComposition.js +46 -49
  13. package/dist/extensions/Blocks/Items/controls/image/link.js +23 -30
  14. package/dist/extensions/Blocks/Items/controls/name/trimming.js +13 -15
  15. package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +1 -1
  16. package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +1 -1
  17. package/dist/extensions/Blocks/Items/controls/price/formattedPrice.js +15 -17
  18. package/dist/extensions/Blocks/Items/controls/price/hideDiscount.js +15 -15
  19. package/dist/extensions/Blocks/Items/controls/price/priceOrientation.js +29 -27
  20. package/dist/extensions/Blocks/Items/controls/settingsControl.js +145 -136
  21. package/dist/extensions/Blocks/Items/enums/settingsEnums.js +2 -2
  22. package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +58 -48
  23. package/dist/extensions/Blocks/Items/layouts/vertical.html.js +48 -58
  24. package/dist/extensions/Blocks/Items/settingsPanel.js +4 -4
  25. package/dist/extensions/Blocks/Items/store/items-block.js +2 -2
  26. package/dist/extensions/Blocks/Items/template.js +312 -125
  27. package/dist/extensions/Blocks/Items/utils/nodeConfigUtils.js +172 -0
  28. package/dist/extensions/Blocks/Items/utils/syncAttributesFromConfigBlock.js +17 -44
  29. package/dist/extensions/Blocks/Recommendation/control.js +1 -1
  30. package/dist/extensions/Blocks/common-control.js +64 -53
  31. package/dist/extensions/Blocks/controlFactories.js +55 -45
  32. package/dist/guido.css +1 -1
  33. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +364 -285
  34. package/dist/package.json.js +1 -1
  35. package/dist/services/stripoApi.js +6 -10
  36. package/dist/src/@types/config/schemas.d.ts +4 -0
  37. package/dist/src/composables/useConfig.d.ts +2 -0
  38. package/dist/src/config/migrator/itemsBlockMigrator.d.ts +6 -0
  39. package/dist/src/extensions/Blocks/Items/controls/button/link.d.ts +0 -2
  40. package/dist/src/extensions/Blocks/Items/controls/image/link.d.ts +0 -2
  41. package/dist/src/extensions/Blocks/Items/controls/price/priceOrientation.d.ts +1 -1
  42. package/dist/src/extensions/Blocks/Items/controls/settingsControl.d.ts +0 -4
  43. package/dist/src/extensions/Blocks/Items/template.d.ts +20 -1
  44. package/dist/src/extensions/Blocks/Items/utils/nodeConfigUtils.d.ts +71 -0
  45. package/dist/src/extensions/Blocks/common-control.d.ts +13 -8
  46. package/dist/src/stores/config.d.ts +17 -0
  47. package/package.json +3 -3
package/README.md CHANGED
@@ -110,6 +110,7 @@ const config: GuidoConfigInput = {
110
110
  css?: string,
111
111
  preselectedDynamicContent?: DynamicContent[],
112
112
  selectedUnsubscribePages?: number[],
113
+ forceRecreate?: boolean, // Default: false - Force recreate template in Stripo storage
113
114
  },
114
115
 
115
116
  // Optional: Editor settings
@@ -137,6 +138,7 @@ const config: GuidoConfigInput = {
137
138
  testMessage?: boolean, // Default: true
138
139
  displayConditions?: boolean, // Default: true
139
140
  unsubscribe?: boolean, // Default: true
141
+ modulesDisabled?: boolean, // Default: false - Disable modules panel
140
142
  },
141
143
 
142
144
  // Optional: Block configuration
@@ -71,7 +71,9 @@ const i = {
71
71
  []
72
72
  ),
73
73
  /** Selected unsubscribe page IDs */
74
- selectedUnsubscribePages: e(a(p()), [])
74
+ selectedUnsubscribePages: e(a(p()), []),
75
+ /** Force recreate template in Stripo storage (use true when updating externally modified templates) */
76
+ forceRecreate: e(c(), !1)
75
77
  }), C = o({
76
78
  /** Sender display name */
77
79
  senderName: e(t(), ""),
@@ -12,7 +12,7 @@ var t = function() {
12
12
  n,
13
13
  !1,
14
14
  null,
15
- "282ca4d1"
15
+ "890b5336"
16
16
  );
17
17
  const v = s.exports;
18
18
  export {
@@ -1,4 +1,4 @@
1
- import { defineComponent as x, defineAsyncComponent as P, ref as B, computed as U, watch as N, onMounted as z, onUnmounted as K } from "vue";
1
+ import { defineComponent as B, defineAsyncComponent as P, ref as N, computed as U, watch as R, onMounted as z, onUnmounted as K } from "vue";
2
2
  import { provideGuidoActions as M } from "../composables/useGuidoActions.js";
3
3
  import { usePartner as j } from "../composables/usePartner.js";
4
4
  import { useStripo as q } from "../composables/useStripo.js";
@@ -15,8 +15,8 @@ import { useConfigStore as oe } from "../stores/config.js";
15
15
  import { useDynamicContentStore as te } from "../stores/dynamic-content.js";
16
16
  import { useEditorStore as ne } from "../stores/editor.js";
17
17
  import { usePreviewStore as re } from "../stores/preview.js";
18
- import { useUnsubscribeStore as ce } from "../stores/unsubscribe.js";
19
- const Ee = /* @__PURE__ */ x({
18
+ import { useUnsubscribeStore as se } from "../stores/unsubscribe.js";
19
+ const Ee = /* @__PURE__ */ B({
20
20
  __name: "Guido",
21
21
  props: {
22
22
  config: null
@@ -27,19 +27,19 @@ const Ee = /* @__PURE__ */ x({
27
27
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
28
28
  ), A = P(
29
29
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
30
- ), p = B(), s = te(), u = ce(), n = oe();
30
+ ), p = N(), c = te(), u = se(), n = oe();
31
31
  n.init(l.config);
32
32
  const i = ne(), F = re(), r = U(() => i.hasChanges), { isTestPartner: G } = j(), v = () => {
33
33
  var e;
34
34
  return (e = p.value) == null ? void 0 : e.handleSave(!0);
35
- }, { templateId: a, userId: y, partnerName: h, productType: f, username: b, template: o } = n, c = (o == null ? void 0 : o.html) || "", g = (o == null ? void 0 : o.css) || "", m = (o == null ? void 0 : o.preselectedDynamicContent) || [];
35
+ }, { templateId: a, userId: y, partnerName: h, productType: b, username: f, template: o } = n, s = (o == null ? void 0 : o.html) || "", g = (o == null ? void 0 : o.css) || "", m = (o == null ? void 0 : o.preselectedDynamicContent) || [];
36
36
  i.templateId = a;
37
37
  const { initPlugin: S } = q({
38
38
  emailId: a,
39
39
  userId: y,
40
- username: b,
40
+ username: f,
41
41
  partnerName: h,
42
- productType: f,
42
+ productType: b,
43
43
  preselectedDynamicContentList: m,
44
44
  onReady: () => {
45
45
  console.debug("guido:ready"), t("ready");
@@ -63,28 +63,26 @@ const Ee = /* @__PURE__ */ x({
63
63
  }
64
64
  });
65
65
  const E = (e) => {
66
- console.debug("dynamic-content:close", e), s.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
66
+ console.debug("dynamic-content:close", e), c.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
67
67
  }, k = () => {
68
68
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
69
69
  };
70
- N(() => r.value, () => {
70
+ R(() => r.value, () => {
71
71
  t("on-change", r.value);
72
72
  });
73
73
  const d = (e) => {
74
- const T = e, { attribute: O, position: R } = T.detail;
75
- console.debug("dynamic-content:open", T.detail), t("dynamic-content:open", O, R);
74
+ const T = e, { attribute: O, position: x } = T.detail;
75
+ console.debug("dynamic-content:open", T.detail), t("dynamic-content:open", O, x);
76
76
  };
77
77
  return z(async () => {
78
78
  console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow");
79
79
  try {
80
80
  u.selectedUnsubscribePages = (o == null ? void 0 : o.selectedUnsubscribePages) || [];
81
81
  let e = {
82
- html: c && await W(c),
83
- css: g,
84
- forceRecreate: !0
85
- // TODO: It should be false for old templates. We will communicate with Stripo
82
+ html: s && await W(s),
83
+ css: g
86
84
  };
87
- e.html || (e = await w(), e.html = await W(e.html)), D(e.html) && (e.html = await C(e.html)), await S(e), s.selectedDynamicContentList = m;
85
+ e.html || (e = await w(), e.html = await W(e.html)), D(e.html) && (e.html = await C(e.html)), await S(e), c.selectedDynamicContentList = m;
88
86
  } catch (e) {
89
87
  console.error("Failed to initialize Stripo editor:", e);
90
88
  }
@@ -104,7 +102,7 @@ const Ee = /* @__PURE__ */ x({
104
102
  },
105
103
  hasChanges: r,
106
104
  saveSilent: v
107
- }), { __sfc: !0, PreviewContainer: L, OnboardingWrapper: A, headerWrapperRef: p, dynamicContentStore: s, unsubscribeStore: u, props: l, configStore: n, editorStore: i, previewStore: F, hasChanges: r, isTestPartner: G, saveSilent: v, templateId: a, userId: y, partnerName: h, productType: f, username: b, templateConfig: o, html: c, css: g, preselectedDynamicContentList: m, emit: t, initPlugin: S, getDefaultTemplate: w, cloneTimersOnSave: C, hasTimerBlocks: D, noHeader: H, insertDynamicContent: E, closeDynamicContent: k, handleDynamicContentOpen: d, Toaster: Q, FilterSelectionDrawer: V, HeaderWrapper: X, LoadingWrapper: Y, SaveAsTemplateDrawer: Z, UnsubscribeWrapper: $ };
105
+ }), { __sfc: !0, PreviewContainer: L, OnboardingWrapper: A, headerWrapperRef: p, dynamicContentStore: c, unsubscribeStore: u, props: l, configStore: n, editorStore: i, previewStore: F, hasChanges: r, isTestPartner: G, saveSilent: v, templateId: a, userId: y, partnerName: h, productType: b, username: f, templateConfig: o, html: s, css: g, preselectedDynamicContentList: m, emit: t, initPlugin: S, getDefaultTemplate: w, cloneTimersOnSave: C, hasTimerBlocks: D, noHeader: H, insertDynamicContent: E, closeDynamicContent: k, handleDynamicContentOpen: d, Toaster: Q, FilterSelectionDrawer: V, HeaderWrapper: X, LoadingWrapper: Y, SaveAsTemplateDrawer: Z, UnsubscribeWrapper: $ };
108
106
  }
109
107
  });
110
108
  export {
@@ -1,18 +1,18 @@
1
- import s from "./LeftSlot.vue2.js";
1
+ import o from "./LeftSlot.vue2.js";
2
2
  /* empty css */
3
- import r from "../../../_virtual/_plugin-vue2_normalizer.js";
4
- var n = function() {
5
- var e = this, o = e._self._c, t = e._self._setupProxy;
6
- return o("div", { staticClass: "d-f a-i-c" }, [o(t.InButtonV2, { staticClass: "p-2", attrs: { id: "guido__back-button", "left-icon": "line-arrow-left", styling: "text", type: "secondary", "label-text": t.backButtonLabel }, on: { click: t.handleBackClick } }), t.editorStore.isVersionHistoryOpen ? o(t.RestoreButton, { staticClass: "ml-3" }) : e._e()], 1);
7
- }, a = [], i = /* @__PURE__ */ r(
8
- s,
9
- n,
10
- a,
3
+ import n from "../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var r = function() {
5
+ var e = this, s = e._self._c, t = e._self._setupProxy;
6
+ return s("div", { staticClass: "d-f a-i-c" }, [s(t.InButtonV2, { staticClass: "p-2", attrs: { id: "guido__back-button", "left-icon": "line-arrow-left", styling: "text", type: "secondary", "label-text": t.backButtonLabel, "skeleton-sizing": { width: 150, height: 26 }, "skeleton-status": t.editorStore.loadingStatus }, on: { click: t.handleBackClick } }), t.editorStore.isVersionHistoryOpen ? s(t.RestoreButton, { staticClass: "ml-3" }) : e._e()], 1);
7
+ }, i = [], a = /* @__PURE__ */ n(
8
+ o,
9
+ r,
10
+ i,
11
11
  !1,
12
12
  null,
13
- "06e6f7a7"
13
+ "3bf5c743"
14
14
  );
15
- const p = i.exports;
15
+ const d = a.exports;
16
16
  export {
17
- p as default
17
+ d as default
18
18
  };
@@ -1,4 +1,4 @@
1
- import { defineComponent as u, computed as m } from "vue";
1
+ import { defineComponent as c, computed as m } from "vue";
2
2
  import { useConfig as f } from "../../../composables/useConfig.js";
3
3
  import { useBack as p } from "../../../composables/useGuidoActions.js";
4
4
  import { usePreviewMode as l } from "../../../composables/usePreviewMode.js";
@@ -7,14 +7,14 @@ import { useVersionHistoryApi as k } from "../../../composables/useVersionHistor
7
7
  import { useEditorStore as B } from "../../../stores/editor.js";
8
8
  import { InButtonV2 as b } from "@useinsider/design-system-vue";
9
9
  import _ from "./version-history/RestoreButton.vue.js";
10
- const h = /* @__PURE__ */ u({
10
+ const S = /* @__PURE__ */ c({
11
11
  __name: "LeftSlot",
12
12
  setup(v) {
13
- const o = B(), r = p(), { closeVersionHistory: i } = k(), { closePreviewMode: n } = l(), e = d(), { config: t } = f(), c = m(() => {
13
+ const o = B(), r = p(), { closeVersionHistory: i } = k(), { closePreviewMode: n } = l(), e = d(), { config: t } = f(), u = m(() => {
14
14
  var s, a;
15
15
  return o.isVersionHistoryOpen || o.isPreviewModeOpen ? e("email-editor.back-to-editor") : (a = (s = t.value) == null ? void 0 : s.ui) != null && a.backButtonLabel ? t.value.ui.backButtonLabel : e("email-editor.back-to-design");
16
16
  });
17
- return { __sfc: !0, editorStore: o, handleBack: r, closeVersionHistory: i, closePreviewMode: n, trans: e, config: t, backButtonLabel: c, handleBackClick: () => {
17
+ return { __sfc: !0, editorStore: o, handleBack: r, closeVersionHistory: i, closePreviewMode: n, trans: e, config: t, backButtonLabel: u, handleBackClick: () => {
18
18
  if (o.isVersionHistoryOpen) {
19
19
  i();
20
20
  return;
@@ -23,10 +23,10 @@ const h = /* @__PURE__ */ u({
23
23
  n();
24
24
  return;
25
25
  }
26
- r();
26
+ o.loadingStatus = !0, r();
27
27
  }, InButtonV2: b, RestoreButton: _ };
28
28
  }
29
29
  });
30
30
  export {
31
- h as default
31
+ S as default
32
32
  };
@@ -1,26 +1,26 @@
1
- import { useActionsApi as T } from "./useActionsApi.js";
2
- import { useBlocksConfig as V } from "./useBlocksConfig.js";
3
- import { useConfig as _ } from "./useConfig.js";
4
- import { useCustomInterfaceAppearance as B } from "./useCustomInterfaceAppearance.js";
5
- import { useStripoEventHandler as v } from "./useStripoEventHandler.js";
6
- import { useToaster as A } from "./useToaster.js";
7
- import { displayConditions as F } from "../enums/displayConditions.js";
8
- import { useStripoApi as D } from "../services/stripoApi.js";
9
- import I from "../static/styles/customEditorStyle.css.js";
10
- import { useEditorStore as M } from "../stores/editor.js";
11
- import { dynamicContentToMergeTags as U } from "../utils/genericUtil.js";
12
- import P from "../package.json.js";
13
- const K = (c) => {
14
- const { features: l } = _(), { handleError: u } = A(), { getToken: y, getCustomFonts: S } = D(), { handleEvent: C } = v(), { getStripoBlocksConfig: E } = V(), h = async (i, n = []) => {
15
- var g, f;
16
- const o = M(), { html: r, css: p, forceRecreate: a } = i, { baseBlocks: t, extensions: d } = await E(), m = ((g = l.value) == null ? void 0 : g.displayConditions) ?? !0, b = ((f = l.value) == null ? void 0 : f.modulesDisabled) ?? !1;
1
+ import { useActionsApi as _ } from "./useActionsApi.js";
2
+ import { useBlocksConfig as B } from "./useBlocksConfig.js";
3
+ import { useConfig as v } from "./useConfig.js";
4
+ import { useCustomInterfaceAppearance as A } from "./useCustomInterfaceAppearance.js";
5
+ import { useStripoEventHandler as F } from "./useStripoEventHandler.js";
6
+ import { useToaster as D } from "./useToaster.js";
7
+ import { displayConditions as I } from "../enums/displayConditions.js";
8
+ import { useStripoApi as M } from "../services/stripoApi.js";
9
+ import U from "../static/styles/customEditorStyle.css.js";
10
+ import { useEditorStore as P } from "../stores/editor.js";
11
+ import { dynamicContentToMergeTags as R } from "../utils/genericUtil.js";
12
+ import H from "../package.json.js";
13
+ const W = (c) => {
14
+ const { features: l, template: y } = v(), { handleError: u } = D(), { getToken: C, getCustomFonts: S } = M(), { handleEvent: E } = F(), { getStripoBlocksConfig: h } = B(), w = async (i, n = []) => {
15
+ var m, g, f;
16
+ const o = P(), { html: r, css: p } = i, { baseBlocks: s, extensions: t } = await h(), a = ((m = l.value) == null ? void 0 : m.displayConditions) ?? !0, k = ((g = l.value) == null ? void 0 : g.modulesDisabled) ?? !1, T = ((f = y.value) == null ? void 0 : f.forceRecreate) ?? !1;
17
17
  window.UIEditor.initEditor(
18
18
  document.querySelector("#guido-editor"),
19
19
  {
20
20
  metadata: c,
21
21
  html: r,
22
22
  css: p,
23
- forceRecreate: a,
23
+ forceRecreate: T,
24
24
  locale: "en",
25
25
  undoButtonSelector: "#guido__undo-button",
26
26
  redoButtonSelector: "#guido__redo-button",
@@ -30,19 +30,19 @@ const K = (c) => {
30
30
  customAppearanceMergetags: !0,
31
31
  customAppearanceMergetagsBorderColor: "#f1f3fe",
32
32
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
33
- customViewStyles: I,
34
- conditionsEnabled: m,
35
- customConditionsEnabled: m,
36
- conditionCategories: F,
33
+ customViewStyles: U,
34
+ conditionsEnabled: a,
35
+ customConditionsEnabled: a,
36
+ conditionCategories: I,
37
37
  enableXSSSecurity: !0,
38
- modulesDisabled: b,
38
+ modulesDisabled: k,
39
39
  messageSettingsEnabled: !0,
40
40
  displayGmailAnnotations: !0,
41
41
  displayHiddenPreheader: !1,
42
42
  displayTitle: !1,
43
43
  displayUTM: !1,
44
44
  selectElementAfterDrop: !0,
45
- ...t ? { baseBlocks: t } : {},
45
+ ...s ? { baseBlocks: s } : {},
46
46
  editorFonts: {
47
47
  showDefaultStandardFonts: !0,
48
48
  showDefaultNotStandardFonts: !0,
@@ -50,21 +50,21 @@ const K = (c) => {
50
50
  },
51
51
  mergeTags: [
52
52
  {
53
- entries: U(c.preselectedDynamicContentList)
53
+ entries: R(c.preselectedDynamicContentList)
54
54
  }
55
55
  ],
56
56
  async onTokenRefreshRequest(e) {
57
57
  try {
58
- const s = await y();
59
- e(s);
60
- } catch (s) {
61
- u(s, "Failed to refresh token");
58
+ const d = await C();
59
+ e(d);
60
+ } catch (d) {
61
+ u(d, "Failed to refresh token");
62
62
  }
63
63
  },
64
64
  onTemplateLoaded() {
65
65
  try {
66
- const { importCss: e } = B(), { activateCustomViewStyles: s, updateTimerInClonedTemplate: k } = T();
67
- e(), s(), k(), c.onReady(), o.isStripoInitialized = !0, o.loadingStatus = !1, setTimeout(() => {
66
+ const { importCss: e } = A(), { activateCustomViewStyles: d, updateTimerInClonedTemplate: V } = _();
67
+ e(), d(), V(), c.onReady(), o.isStripoInitialized = !0, o.loadingStatus = !1, setTimeout(() => {
68
68
  o.hasChanges = !1;
69
69
  }, 1e3);
70
70
  } catch (e) {
@@ -83,35 +83,35 @@ const K = (c) => {
83
83
  onDataChanged() {
84
84
  o.hasChanges = !0;
85
85
  },
86
- onEvent: C,
86
+ onEvent: E,
87
87
  ignoreClickOutsideSelectors: [
88
88
  "#guido-dynamic-content-modal",
89
89
  ".in-on-board-wrapper",
90
90
  ".in-drawer__container"
91
91
  ],
92
- extensions: d
92
+ extensions: t
93
93
  }
94
94
  );
95
- }, w = (i) => new Promise((n, o) => {
96
- var d;
95
+ }, b = (i) => new Promise((n, o) => {
96
+ var a;
97
97
  if (document.getElementById("UiEditorScript")) {
98
98
  i(), n();
99
99
  return;
100
100
  }
101
- const r = P.guido, a = `https://email-static.useinsider.com/guido/${(d = r == null ? void 0 : r.stripo) == null ? void 0 : d.version}/UIEditor.js`, t = document.createElement("script");
102
- t.id = "UiEditorScript", t.type = "module", t.src = a, t.onload = () => {
101
+ const r = H.guido, s = `https://email-static.useinsider.com/guido/${(a = r == null ? void 0 : r.stripo) == null ? void 0 : a.version}/UIEditor.js`, t = document.createElement("script");
102
+ t.id = "UiEditorScript", t.type = "module", t.src = s, t.onload = () => {
103
103
  i(), n();
104
104
  }, t.onerror = () => {
105
- o(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
105
+ o(new Error(`Failed to load Stripo UIEditor script from S3: ${s}`));
106
106
  }, document.body.appendChild(t);
107
107
  });
108
108
  return { initPlugin: async (i) => {
109
- await w(async () => {
109
+ await b(async () => {
110
110
  const n = await S();
111
- await h(i, n);
111
+ await w(i, n);
112
112
  });
113
113
  } };
114
114
  };
115
115
  export {
116
- K as useStripo
116
+ W as useStripo
117
117
  };
@@ -1,12 +1,13 @@
1
- import { migrateCheckbox as m } from "./checkboxMigrator.js";
1
+ import { migrateCheckbox as t } from "./checkboxMigrator.js";
2
2
  import { migrateCouponBlock as o } from "./couponBlockMigrator.js";
3
- import { migrateRadioButton as i } from "./radioButtonMigrator.js";
4
- import { migrateRecommendation as e } from "./recommendationMigrator.js";
5
- import { migrateUnsubscribe as a } from "./unsubscribeMigrator.js";
6
- const s = async (t) => {
7
- let r = t;
8
- return r = m(r), r = i(r), r = await a(r), r = o(r), r = e(r), r;
3
+ import { migrateItemsBlock as i } from "./itemsBlockMigrator.js";
4
+ import { migrateRadioButton as e } from "./radioButtonMigrator.js";
5
+ import { migrateRecommendation as a } from "./recommendationMigrator.js";
6
+ import { migrateUnsubscribe as g } from "./unsubscribeMigrator.js";
7
+ const u = async (r) => {
8
+ let m = r;
9
+ return m = t(m), m = e(m), m = await g(m), m = o(m), m = a(m), m = i(m), m;
9
10
  };
10
11
  export {
11
- s as migrate
12
+ u as migrate
12
13
  };
@@ -0,0 +1,283 @@
1
+ var B = Object.defineProperty;
2
+ var q = (o, t, r) => t in o ? B(o, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : o[t] = r;
3
+ var A = (o, t, r) => q(o, typeof t != "symbol" ? t + "" : t, r);
4
+ import { productPairs as L } from "../../extensions/Blocks/Items/enums/productEnums.js";
5
+ import { ItemInCartOptions as I, DefaultConfigValues as m, SETTINGS_ENUMS as l } from "../../extensions/Blocks/Items/enums/settingsEnums.js";
6
+ import { getDefaultTemplate as K } from "../../extensions/Blocks/Items/template.js";
7
+ const V = {
8
+ ins_apr_img: {
9
+ pairsKey: "imageSrc",
10
+ defaultKey: "DEFAULT",
11
+ isArray: !0
12
+ },
13
+ ins_apr_name: {
14
+ pairsKey: "name",
15
+ defaultKey: "DEFAULT",
16
+ isArray: !0
17
+ },
18
+ ins_apr_url: {
19
+ pairsKey: "button",
20
+ defaultKey: "DEFAULT_HREF",
21
+ isArray: !1
22
+ },
23
+ ins_apr_formattedprice: {
24
+ pairsKey: "price",
25
+ defaultKey: "DEFAULT_PRICE_FORMATTED",
26
+ isArray: !1
27
+ },
28
+ ins_apr_productcurrency: {
29
+ pairsKey: "price",
30
+ defaultKey: "DEFAULT_CURRENCY",
31
+ isArray: !1
32
+ },
33
+ ins_apr_quantity: {
34
+ pairsKey: "quantity",
35
+ defaultKey: "DEFAULT",
36
+ isArray: !1
37
+ },
38
+ ins_apr_price: {
39
+ pairsKey: "price",
40
+ defaultKey: "DEFAULT_PRICE",
41
+ isArray: !1
42
+ },
43
+ ins_apr_originalprice: {
44
+ pairsKey: "originalPrice",
45
+ defaultKey: "DEFAULT_PRICE",
46
+ isArray: !1
47
+ },
48
+ ins_apr_originalformattedprice: {
49
+ pairsKey: "originalPrice",
50
+ defaultKey: "DEFAULT_PRICE_FORMATTED",
51
+ isArray: !1
52
+ }
53
+ };
54
+ function U() {
55
+ return String(Date.now() + Math.floor(Math.random() * 1e3));
56
+ }
57
+ function F(o) {
58
+ return o ? {
59
+ CartItems: l.ITEMS_TYPE.CART_ITEMS,
60
+ BrowsedItems: l.ITEMS_TYPE.BROWSED_ITEMS,
61
+ PurchasedItems: l.ITEMS_TYPE.PURCHASED_ITEMS,
62
+ CART_ITEMS: l.ITEMS_TYPE.CART_ITEMS,
63
+ BROWSED_ITEMS: l.ITEMS_TYPE.BROWSED_ITEMS,
64
+ PURCHASED_ITEMS: l.ITEMS_TYPE.PURCHASED_ITEMS
65
+ }[o] || l.ITEMS_TYPE.CART_ITEMS : l.ITEMS_TYPE.CART_ITEMS;
66
+ }
67
+ function D(o) {
68
+ const t = (e, a) => e == null ? a : e === "1" || e === "true", r = (e, a) => e || a, c = o["data-type"] || o["data-source"], n = F(c);
69
+ let i = o["data-cart_items_select_control_value"] || m.cartItemsSelectControlValue;
70
+ if (i && !i.includes("{{") && /^\d+$/.test(i)) {
71
+ const e = parseInt(i) - 1, a = I[n];
72
+ a && a[e] && (i = a[e].value);
73
+ }
74
+ return {
75
+ initialized: !0,
76
+ blockInstanceId: r(o["data-block-instance-id"], U()),
77
+ source: n,
78
+ type: n,
79
+ itemsSelectValue: i,
80
+ orientation: o["data-card_orientation_control_value"] || l.ORIENTATION.VERTICAL,
81
+ nameTrimming: t(o["data-product_name_trimming"], !0),
82
+ nameControlEnabled: t(o["data-product_name_control_enabled"], !0),
83
+ priceHideDiscount: t(o["data-product_price_hide_discount"], !1),
84
+ priceFormatted: t(o["data-product_price_formatted"], !0),
85
+ priceCurrencySymbol: r(
86
+ o["data-product_price_currency_symbol"],
87
+ m.productPriceCurrencySymbolControlValue
88
+ ),
89
+ priceCurrencyLocation: r(
90
+ o["data-product_price_currency_location"],
91
+ m.productPriceCurrencyLocationControlValue
92
+ ),
93
+ priceControlOpened: t(o["data-product_price_control_opened"], !0),
94
+ priceOrientation: o["data-product_original_price_control_orientation"] || "horizontal",
95
+ quantityControlEnabled: t(o["data-product_quantity_control_enabled"], !0),
96
+ buttonLink: r(o["data-product_button_link"], m.productButtonLinkControlValue),
97
+ imageLink: r(o["data-product_image_link"], m.productImageLinkControlValue),
98
+ buttonLabel: r(o["data-product_button_control_label"], "Buy"),
99
+ imageVisible: t(o["data-product_image_visible"], !0),
100
+ nameVisible: t(o["data-product_name_visible"], !0),
101
+ quantityVisible: t(o["data-product_quantity_visible"], !0),
102
+ priceVisible: t(o["data-product_price_visible"], !0),
103
+ originalPriceVisible: t(o["data-product_original_price_control_enabled"], !0),
104
+ buttonVisible: t(o["data-product_button_visible"], !0)
105
+ };
106
+ }
107
+ class w {
108
+ constructor() {
109
+ A(this, "parser");
110
+ A(this, "DATA_TYPE", "CART_ITEMS");
111
+ this.parser = new DOMParser();
112
+ }
113
+ migrate(t) {
114
+ try {
115
+ let r = this.removeJinjaConditionals(t);
116
+ r = this.replaceTemplateVariables(r);
117
+ const c = this.parser.parseFromString(r, "text/html"), n = c.querySelectorAll("td.esd-cart-items-block");
118
+ return n.length === 0 ? (console.warn('ItemsBlockMigrator: No blocks found with selector "td.esd-cart-items-block"'), r) : (n.forEach((i) => {
119
+ const e = this.extractConfiguration(i), a = K({
120
+ orientation: e.orientation,
121
+ itemsType: e.itemsType,
122
+ itemId: e.itemId,
123
+ currencySymbol: e.currencySymbol,
124
+ currencyLocation: e.currencyLocation,
125
+ formattedPrice: e.formattedPrice,
126
+ configBlockAttributes: e.configBlockAttributes,
127
+ migrate: !0,
128
+ nameStyles: e.nameStyles,
129
+ buttonStyles: e.buttonStyles,
130
+ priceStyles: e.priceStyles,
131
+ originalPriceStyles: e.originalPriceStyles,
132
+ quantityStyles: e.quantityStyles,
133
+ nodeConfig: D(e.configBlockAttributes)
134
+ }), u = this.parser.parseFromString(
135
+ `<table><tbody><tr>${a}</tr></tbody></table>`,
136
+ "text/html"
137
+ ).querySelector("td");
138
+ if (u && i.parentNode) {
139
+ const s = D(e.configBlockAttributes);
140
+ u.setAttribute("esd-ext-config", JSON.stringify(s));
141
+ const p = u.querySelector("esd-config-block");
142
+ p && p.remove(), i.parentNode.replaceChild(u, i);
143
+ }
144
+ }), c.documentElement.outerHTML);
145
+ } catch (r) {
146
+ return console.error("ItemsBlockMigrator failed:", r), t;
147
+ }
148
+ }
149
+ /**
150
+ * Extracts configuration from legacy HTML block
151
+ * Parses data attributes and structure to determine:
152
+ * - orientation, itemsType, itemNumber, currency settings, esd-config-block attributes
153
+ * - UI styles from product elements (name, price, button, quantity, etc.)
154
+ */
155
+ extractConfiguration(t) {
156
+ var E, C, P;
157
+ const r = ((E = t.querySelector("[data-type]")) == null ? void 0 : E.getAttribute("data-type")) || "CART_ITEMS", c = ((C = t.querySelector("[data-number]")) == null ? void 0 : C.getAttribute("data-number")) || "1", n = parseInt(c) - 1, i = I[r], e = ((P = i == null ? void 0 : i[n]) == null ? void 0 : P.value) || i[0].value, a = t.querySelector('[product-attr="price"]'), _ = (a == null ? void 0 : a.getAttribute("data-currency_symbol")) || void 0, s = ((a == null ? void 0 : a.getAttribute("data-curency")) || "before") === "after" ? "1" : "0", p = (a == null ? void 0 : a.getAttribute("data-formated")) !== "false", y = this.extractConfigBlockAttributes(t, r), f = y["data-product_original_price_control_orientation"] === "vertical" ? "vertical" : "horizontal", d = t.querySelector('a[product-attr="name"]'), v = (d == null ? void 0 : d.getAttribute("style")) || void 0, b = t.querySelector('a[product-attr="button"]'), M = (b == null ? void 0 : b.getAttribute("style")) || void 0, h = (a == null ? void 0 : a.getAttribute("style")) || void 0, S = t.querySelector('[product-attr="originalPrice"]'), R = (S == null ? void 0 : S.getAttribute("style")) || void 0, T = t.querySelector('[product-attr="quantity"]'), k = (T == null ? void 0 : T.getAttribute("style")) || void 0;
158
+ return {
159
+ orientation: f,
160
+ itemsType: r,
161
+ itemId: e,
162
+ currencySymbol: _,
163
+ currencyLocation: s,
164
+ formattedPrice: p,
165
+ configBlockAttributes: y,
166
+ nameStyles: v,
167
+ buttonStyles: M,
168
+ priceStyles: h,
169
+ originalPriceStyles: R,
170
+ quantityStyles: k
171
+ };
172
+ }
173
+ /**
174
+ * Extracts all data-* attributes from the esd-config-block element
175
+ * Returns a key-value mapping of all configuration attributes
176
+ * @param block - The block element containing the esd-config-block
177
+ * @param itemsType - The type of items (CART_ITEMS, BROWSED_ITEMS, PURCHASED_ITEMS)
178
+ */
179
+ extractConfigBlockAttributes(t, r) {
180
+ const c = t.querySelector("esd-config-block"), n = {};
181
+ if (!c)
182
+ return this.getDefaultConfigBlockAttributes();
183
+ if (Array.from(c.attributes).forEach((e) => {
184
+ e.name.startsWith("data-") && (n[e.name] = e.value);
185
+ }), n["data-cart_items_select_control_value"]) {
186
+ const e = n["data-cart_items_select_control_value"];
187
+ if (/^\d+$/.test(e)) {
188
+ const a = parseInt(e) - 1, _ = I[r];
189
+ _ && _[a] && (n["data-cart_items_select_control_value"] = _[a].value);
190
+ }
191
+ }
192
+ if (n["data-product_price_control_curency"]) {
193
+ const e = n["data-product_price_control_curency"];
194
+ e === "before" ? n["data-product_price_control_curency"] = "0" : e === "after" && (n["data-product_price_control_curency"] = "1");
195
+ }
196
+ (!n["data-product_price_currency_symbol"] || n["data-product_price_currency_symbol"].trim() === "") && (n["data-product_price_currency_symbol"] = "USD");
197
+ const i = { ...this.getDefaultConfigBlockAttributes(), ...n };
198
+ return i["data-type"] = r, i["data-source"] = r, i;
199
+ }
200
+ /**
201
+ * Returns default esd-config-block attributes based on the old template structure
202
+ * These serve as fallbacks when attributes are missing
203
+ */
204
+ getDefaultConfigBlockAttributes() {
205
+ return {
206
+ "data-type": "CART_ITEMS",
207
+ "data-product_image_control_opened": "false",
208
+ "data-product_image_control_image-width": "250",
209
+ "data-product_image_control_image-height": "250",
210
+ "data-product_image_control_align_button": "true",
211
+ "data-product_image_control_padding_mobile": "true",
212
+ "data-product_name_control_opened": "false",
213
+ "data-product_quantity_control_opened": "true",
214
+ // DONE
215
+ "data-product_quantity_control_enabled": "false",
216
+ "data-product_name_control_font_font_size": "20",
217
+ "data-product_price_control_opened": "false",
218
+ "data-product_price_control_font_font_size": "20",
219
+ "data-product_price_control_color": "#060606",
220
+ "data-product_price_control_curency": "0",
221
+ "data-product_price_currency_symbol": "USD",
222
+ "data-product_original_price_control_opened": "false",
223
+ "data-product_original_price_control_font_font_size": "19",
224
+ "data-product_original_price_control_align_align_desktop": "center",
225
+ "data-product_original_price_control_orientation": "vertical",
226
+ "data-product_button_control_opened": "true",
227
+ "data-product_button_control_label": "Comprar",
228
+ // DONE
229
+ "data-product_button_control_font_font_size": "17",
230
+ "data-product_button_control_color": "#ffffff",
231
+ "data-product_button_control_background": "#010101",
232
+ "data-product_button_control_atw": "false",
233
+ "data-product_original_price_control_enabled": "false"
234
+ };
235
+ }
236
+ /**
237
+ * Removes Jinja2 conditional statements from HTML
238
+ * - Removes {% if ins_apr_total_product_kind > N %}
239
+ * - Removes {% if ins_apr_price_N != ins_apr_originalprice_N %}
240
+ * - Removes {% endif %}
241
+ */
242
+ removeJinjaConditionals(t) {
243
+ let r = t.replace(/\{%\s*if\s+ins_apr_total_product_kind\s*(&gt;|>)\s*\d+\s*%\}/g, "");
244
+ return r = r.replace(/\{%\s*if\s+ins_apr_price_\d+\s*(!&#61;|!=)\s*ins_apr_originalprice_\d+\s*%\}/g, ""), r = r.replace(/\{%\s*endif\s*%\}/g, ""), r = r.replace(/\n\s*\n\s*\n/g, `
245
+
246
+ `), r;
247
+ }
248
+ /**
249
+ * Replaces template variables with default values from productPairs
250
+ *
251
+ * Examples:
252
+ * - {{ins_apr_img_1}} → https://s3.../ins_apr_img_1.jpeg (array-based, uses index 0)
253
+ * - {{ins_apr_name_2}} → 'Set of Sprite Yoga Straps' (array-based, uses index 1)
254
+ * - {{ins_apr_formattedprice_1}} → '1,100.00' (single value, ignores index)
255
+ * - {{ins_apr_url_3}} → '#!' (single value, ignores index)
256
+ */
257
+ replaceTemplateVariables(t) {
258
+ const { PAIRS_FOR_EXTENSION: r } = L;
259
+ return t.replace(/{{([^}]+)}}/g, (c, n) => {
260
+ const i = n.match(/^(ins_apr_[a-z]+)_(\d+)$/);
261
+ if (!i)
262
+ return c;
263
+ const [, e, a] = i, _ = V[e];
264
+ if (!_)
265
+ return console.warn(`Unknown variable mapping for: ${e}`), c;
266
+ const { pairsKey: u, defaultKey: s, isArray: p } = _, y = r[u][this.DATA_TYPE];
267
+ if (!y)
268
+ return console.warn(`No data found for: ${u}.${this.DATA_TYPE}`), c;
269
+ if (p) {
270
+ const f = parseInt(a) - 1, d = y[s];
271
+ return Array.isArray(d) && d[f] ? d[f] : (console.warn(`Array value not found: ${u}.${this.DATA_TYPE}.${s}[${f}]`), c);
272
+ }
273
+ const g = y[s];
274
+ return g !== void 0 ? String(g) : (console.warn(`Default value not found: ${u}.${this.DATA_TYPE}.${s}`), c);
275
+ });
276
+ }
277
+ }
278
+ function $(o) {
279
+ return new w().migrate(o);
280
+ }
281
+ export {
282
+ $ as migrateItemsBlock
283
+ };