@useinsider/guido 3.12.0 → 3.13.0-beta.4a55a9f

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 (55) hide show
  1. package/README.md +17 -2
  2. package/dist/@types/config/defaults.js +6 -2
  3. package/dist/@types/config/schemas.js +27 -25
  4. package/dist/components/Guido.vue.js +1 -1
  5. package/dist/components/Guido.vue2.js +110 -101
  6. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  7. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  8. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  9. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  10. package/dist/composables/useAllowlist.js +50 -0
  11. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  12. package/dist/composables/useRecommendationPreview.js +61 -60
  13. package/dist/composables/useSave.js +42 -23
  14. package/dist/composables/useStripo.js +72 -69
  15. package/dist/composables/useTranslations.js +7 -5
  16. package/dist/composables/useUserRole.js +12 -0
  17. package/dist/enums/roles.js +4 -0
  18. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  19. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  20. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +12 -12
  21. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +12 -12
  22. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +12 -12
  23. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +12 -12
  24. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  25. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  26. package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +7 -7
  27. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  28. package/dist/extensions/Blocks/controlFactories.js +125 -75
  29. package/dist/guido.css +1 -1
  30. package/dist/services/allowlistApi.js +15 -0
  31. package/dist/services/stripoApi.js +18 -18
  32. package/dist/src/@types/config/schemas.d.ts +10 -0
  33. package/dist/src/components/Guido.vue.d.ts +18 -2
  34. package/dist/src/composables/useAllowlist.d.ts +6 -0
  35. package/dist/src/composables/useConfig.d.ts +2 -0
  36. package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -5
  37. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  38. package/dist/src/composables/useStripo.d.ts +3 -2
  39. package/dist/src/composables/useUserRole.d.ts +3 -0
  40. package/dist/src/enums/roles.d.ts +9 -0
  41. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  42. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  43. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  44. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  45. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  46. package/dist/src/services/allowlistApi.d.ts +4 -0
  47. package/dist/src/stores/config.d.ts +21 -1
  48. package/dist/src/utils/urlSchemes.d.ts +6 -0
  49. package/dist/static/styles/components/base-input.css.js +6 -7
  50. package/dist/stores/config.js +21 -19
  51. package/dist/utils/pairProductVariables.js +44 -43
  52. package/dist/{extensions/Blocks/Recommendation/utils → utils}/preserveTextStyles.js +1 -1
  53. package/dist/utils/urlSchemes.js +4 -0
  54. package/package.json +1 -1
  55. /package/dist/src/{extensions/Blocks/Recommendation/utils → utils}/preserveTextStyles.d.ts +0 -0
@@ -0,0 +1,50 @@
1
+ import { useAllowlistApi as A } from "../services/allowlistApi.js";
2
+ import { base64EncodeWithSpecialChars as p } from "../utils/base64.js";
3
+ import { useTranslations as h } from "./useTranslations.js";
4
+ import { useUserRole as D } from "./useUserRole.js";
5
+ const f = /(?:https?:\/\/|www\.)[^\s"'<>()]+/gi, E = /&quot;\/\//gi, i = {
6
+ MANAGE: "journey-builder.domain-allowlist-warning",
7
+ NON_MANAGE: "settings.allow-list-warning-not-admin-architect",
8
+ ADD_BUTTON: "settings.allow-list-warning-add-button"
9
+ }, w = /* @__PURE__ */ new Set(), O = (n) => `/settings?openAddModal=true&type=domain&values=${p(n)}#security`, M = () => {
10
+ const { checkDomain: n } = A(), { getIsManageUser: l } = D(), a = h(), d = (t, s) => {
11
+ const c = `${t || ""} ${s || ""}`.replace(E, "https://").match(f) || [], e = /* @__PURE__ */ new Set();
12
+ return c.forEach((r) => {
13
+ const g = /^https?:\/\//i.test(r) ? r : `https://${r}`;
14
+ try {
15
+ const { hostname: u } = new URL(g);
16
+ u && e.add(u.replace(/^www\./i, "").toLowerCase());
17
+ } catch {
18
+ }
19
+ }), [...e];
20
+ }, m = async (t) => {
21
+ if (w.has(t))
22
+ return !0;
23
+ try {
24
+ const s = await n(t);
25
+ return s && w.add(t), s;
26
+ } catch (s) {
27
+ return console.error("[GUIDO_ALLOWLIST] isDomainAllowlisted failed", t, s), !0;
28
+ }
29
+ };
30
+ return { getBlockedDomains: async (t, s) => {
31
+ try {
32
+ const o = d(t, s);
33
+ return o.length ? (await Promise.all(
34
+ o.map(async (e) => ({ domain: e, allowlisted: await m(e) }))
35
+ )).filter((e) => !e.allowlisted).map((e) => e.domain) : [];
36
+ } catch (o) {
37
+ return console.error("[GUIDO_ALLOWLIST] getBlockedDomains failed", o), [];
38
+ }
39
+ }, resolveToast: async (t) => await l() ? {
40
+ message: a(i.MANAGE),
41
+ actionButton: {
42
+ text: a(i.ADD_BUTTON),
43
+ onClick: () => window.open(O(t.join(",")), "_blank")
44
+ }
45
+ } : { message: a(i.NON_MANAGE) } };
46
+ };
47
+ export {
48
+ O as buildAllowlistSettingsUrl,
49
+ M as useAllowlist
50
+ };
@@ -1,17 +1,42 @@
1
- const o = ["click", "auxclick", "submit"], c = (t) => {
2
- t.preventDefault(), t.stopPropagation();
3
- }, a = () => ({ blockPreviewInteractions: (r) => {
1
+ import { URLS as o, MERGE_TAGS as a } from "../enums/unsubscribe.js";
2
+ import { UNSUBSCRIBE_LINK_SELECTOR as i } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
3
+ import { BASE_SAFE_URL_SCHEMES as u } from "../utils/urlSchemes.js";
4
+ const E = ["click", "auxclick"], d = [
5
+ ...Object.values(a),
6
+ o.UNSUBSCRIBE_URL,
7
+ o.PREFERENCES_URL
8
+ ], l = (e) => {
9
+ if (e.matches(i))
10
+ return !0;
11
+ const r = e.getAttribute("href") ?? "";
12
+ return d.some((t) => r.includes(t));
13
+ }, S = [...u, "tel:", "sms:"], f = (e) => {
14
+ const r = (e.getAttribute("href") ?? "").trim();
15
+ return r === "" || r.startsWith("#") || r.startsWith("{{") ? !1 : S.includes(e.protocol);
16
+ }, m = (e) => {
17
+ var t, n;
18
+ const r = (n = (t = e.target) == null ? void 0 : t.closest) == null ? void 0 : n.call(t, "a");
19
+ if (r) {
20
+ if (l(r) || !f(r)) {
21
+ e.preventDefault(), e.stopPropagation();
22
+ return;
23
+ }
24
+ r.setAttribute("target", "_blank"), r.setAttribute("rel", "noopener noreferrer");
25
+ }
26
+ }, R = (e) => {
27
+ e.preventDefault(), e.stopPropagation();
28
+ }, s = /* @__PURE__ */ new WeakSet(), c = "guidoPreviewGuarded", g = () => ({ guardPreviewInteractions: (r) => {
4
29
  try {
5
- const e = r.contentDocument;
6
- if (!e)
30
+ const t = r.contentDocument;
31
+ if (!t || s.has(t))
7
32
  return;
8
- o.forEach((n) => {
9
- e.addEventListener(n, c, !0);
10
- });
11
- } catch (e) {
12
- console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", e);
33
+ delete t.documentElement.dataset[c], E.forEach((n) => {
34
+ t.addEventListener(n, m, !0);
35
+ }), t.addEventListener("submit", R, !0), s.add(t), t.documentElement.dataset[c] = "true";
36
+ } catch (t) {
37
+ console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", t);
13
38
  }
14
39
  } });
15
40
  export {
16
- a as usePreviewInteractionGuard
41
+ g as usePreviewInteractionGuard
17
42
  };
@@ -1,111 +1,112 @@
1
- import { BLOCK_ROOT_SELECTOR as S, CURRENCY_ATTR as p, CONTAINER_SELECTOR as O } from "../extensions/Blocks/Recommendation/constants/selectors.js";
2
- import { useRecommendationExtensionStore as h } from "../extensions/Blocks/Recommendation/store/recommendation.js";
3
- import { formatPrice as E } from "../extensions/Blocks/Recommendation/utils/priceFormatter.js";
4
- const f = `${S}[recommendation-id]`, C = ".product-old-price", R = /\{\{(?:reco_)?(\d+_\d+_[a-zA-Z0-9_.]+)\}\}/g, T = new RegExp(
1
+ import { BLOCK_ROOT_SELECTOR as f, CURRENCY_ATTR as A, CONTAINER_SELECTOR as O } from "../extensions/Blocks/Recommendation/constants/selectors.js";
2
+ import { useRecommendationExtensionStore as C } from "../extensions/Blocks/Recommendation/store/recommendation.js";
3
+ import { formatPrice as _ } from "../extensions/Blocks/Recommendation/utils/priceFormatter.js";
4
+ import { BASE_SAFE_URL_SCHEMES as R } from "../utils/urlSchemes.js";
5
+ const S = `${f}[recommendation-id]`, h = ".product-old-price", T = /\{\{(?:reco_)?(\d+_\d+_[a-zA-Z0-9_.]+)\}\}/g, b = new RegExp(
5
6
  "\\{%\\s*if\\s+([\\s\\S]+?)\\s*%\\}([\\s\\S]*?)(?:\\{%\\s*else\\s*%\\}([\\s\\S]*?))?\\{%\\s*endif\\s*%\\}",
6
7
  "g"
7
8
  );
8
- function b(e) {
9
+ function L(e) {
9
10
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10
11
  }
11
- function _(e) {
12
- var s;
13
- const n = (s = e.replace(/[\u0000-\u0020]+/g, "").toLowerCase().match(/^([a-z][a-z0-9+.-]*):/)) == null ? void 0 : s[1];
14
- return n && n !== "http" && n !== "https" && n !== "mailto" ? "" : e;
12
+ function g(e) {
13
+ var c;
14
+ const i = (c = e.replace(/[\u0000-\u0020]+/g, "").toLowerCase().match(/^([a-z][a-z0-9+.-]*):/)) == null ? void 0 : c[1];
15
+ return i && !R.includes(`${i}:`) ? "" : e;
15
16
  }
16
17
  function N(e) {
17
- const t = e.getAttribute(p.CURRENCY) || "USD", n = e.getAttribute(p.DECIMAL_SEPARATOR) || ".", s = e.getAttribute(p.THOUSAND_SEPARATOR) || ",";
18
+ const t = e.getAttribute(A.CURRENCY) || "USD", i = e.getAttribute(A.DECIMAL_SEPARATOR) || ".", c = e.getAttribute(A.THOUSAND_SEPARATOR) || ",";
18
19
  return {
19
20
  code: t,
20
- symbol: e.getAttribute(p.SYMBOL) || t,
21
- alignment: e.getAttribute(p.ALIGNMENT) === "0" ? "before" : "after",
22
- decimalCount: parseInt(e.getAttribute(p.DECIMAL_COUNT) || "2") || 2,
23
- decimalSeparator: n,
24
- thousandSeparator: s
21
+ symbol: e.getAttribute(A.SYMBOL) || t,
22
+ alignment: e.getAttribute(A.ALIGNMENT) === "0" ? "before" : "after",
23
+ decimalCount: parseInt(e.getAttribute(A.DECIMAL_COUNT) || "2") || 2,
24
+ decimalSeparator: i,
25
+ thousandSeparator: c
25
26
  };
26
27
  }
27
- function g(e, t) {
28
+ function E(e, t) {
28
29
  return (e == null ? void 0 : e[t]) ?? Object.values(e ?? {})[0] ?? 0;
29
30
  }
30
- function L(e, t) {
31
- const n = g(e.original_price, t), s = g(e.price, t), o = n > 0 ? Math.round((n - s) / n * 100) : 0;
32
- return o > 0 ? `${o}%` : "0%";
31
+ function $(e, t) {
32
+ const i = E(e.original_price, t), c = E(e.price, t), n = i > 0 ? Math.round((i - c) / i * 100) : 0;
33
+ return n > 0 ? `${n}%` : "0%";
33
34
  }
34
- function P(e, t, n, s, o, a) {
35
- s.forEach((i, c) => {
36
- const r = (m) => `${n}_${c}_${m}`, u = E({ price: g(i.price, o.code), currency: o }), l = E({ price: g(i.original_price, o.code), currency: o }), d = L(i, o.code);
37
- e.set(r("name"), i.name ?? ""), e.set(r("image_url"), _(i.image_url ?? "")), e.set(r("url"), _(i.url ?? "")), e.set(r("item_id"), i.item_id ?? ""), e.set(r("currency"), ""), e.set(r("price"), u), e.set(r("original_price"), l), e.set(r("discount"), d), e.set(r("omnibus_price"), l), e.set(r("omnibus_discount"), d), a && u === l && t.add(`${n}_${c}`), Object.entries(i.product_attributes ?? {}).forEach(([m, A]) => {
38
- e.set(r(`product_attribute.${m}`), String(A)), e.set(r(m), String(A));
35
+ function P(e, t, i, c, n, a) {
36
+ c.forEach((o, s) => {
37
+ const r = (m) => `${i}_${s}_${m}`, u = _({ price: E(o.price, n.code), currency: n }), l = _({ price: E(o.original_price, n.code), currency: n }), d = $(o, n.code);
38
+ e.set(r("name"), o.name ?? ""), e.set(r("image_url"), g(o.image_url ?? "")), e.set(r("url"), g(o.url ?? "")), e.set(r("item_id"), o.item_id ?? ""), e.set(r("currency"), ""), e.set(r("price"), u), e.set(r("original_price"), l), e.set(r("discount"), d), e.set(r("omnibus_price"), l), e.set(r("omnibus_discount"), d), a && u === l && t.add(`${i}_${s}`), Object.entries(o.product_attributes ?? {}).forEach(([m, p]) => {
39
+ e.set(r(`product_attribute.${m}`), String(p)), e.set(r(m), String(p));
39
40
  });
40
41
  });
41
42
  }
42
- function $(e, t) {
43
- const n = e.match(/^(.+?)\s*(!=|==)\s*"([^"]*)"$/);
44
- if (!n)
43
+ function z(e, t) {
44
+ const i = e.match(/^(.+?)\s*(!=|==)\s*"([^"]*)"$/);
45
+ if (!i)
45
46
  return !0;
46
- const [, s, o, a] = n, i = t.get(s.trim()) ?? "";
47
- return o === "!=" ? i !== a : i === a;
47
+ const [, c, n, a] = i, o = t.get(c.trim()) ?? "";
48
+ return n === "!=" ? o !== a : o === a;
48
49
  }
49
- function z(e, t) {
50
+ function w(e, t) {
50
51
  return e.replace(
51
- T,
52
- (n, s, o, a) => s.split(/\s+and\s+/).every((c) => $(c.trim(), t)) ? o : a ?? ""
52
+ b,
53
+ (i, c, n, a) => c.split(/\s+and\s+/).every((s) => z(s.trim(), t)) ? n : a ?? ""
53
54
  );
54
55
  }
55
- function w(e) {
56
+ function D(e) {
56
57
  let t = e;
57
58
  for (; t.children.length === 1; )
58
59
  [t] = t.children;
59
60
  return t;
60
61
  }
61
- function D(e, t) {
62
- var i;
62
+ function I(e, t) {
63
+ var o;
63
64
  if (!t.size)
64
65
  return e;
65
- const n = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), s = new DOMParser().parseFromString(n, "text/html");
66
- s.querySelectorAll(f).forEach((c) => {
67
- const r = Number(c.getAttribute("recommendation-id"));
66
+ const i = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), c = new DOMParser().parseFromString(i, "text/html");
67
+ c.querySelectorAll(S).forEach((s) => {
68
+ const r = Number(s.getAttribute("recommendation-id"));
68
69
  if (!Number.isFinite(r))
69
70
  return;
70
- const u = c.querySelectorAll(O);
71
- (u.length ? Array.from(u) : [c]).forEach((d) => {
72
- d.querySelectorAll(C).forEach((m, A) => {
73
- t.has(`${r}_${A}`) && (w(m).textContent = "");
71
+ const u = s.querySelectorAll(O);
72
+ (u.length ? Array.from(u) : [s]).forEach((d) => {
73
+ d.querySelectorAll(h).forEach((m, p) => {
74
+ t.has(`${r}_${p}`) && (D(m).textContent = "");
74
75
  });
75
76
  });
76
77
  });
77
- const o = (i = e.match(/<!DOCTYPE[^>]*>/i)) == null ? void 0 : i[0];
78
- return ((o ? `${o}
79
- ` : "") + s.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
78
+ const n = (o = e.match(/<!DOCTYPE[^>]*>/i)) == null ? void 0 : o[0];
79
+ return ((n ? `${n}
80
+ ` : "") + c.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
80
81
  }
81
- function I(e) {
82
+ function y(e) {
82
83
  if (!e || !e.includes("recommendation-block-v2"))
83
84
  return e;
84
- const t = h(), n = new DOMParser().parseFromString(e, "text/html"), s = Array.from(n.querySelectorAll(f)), o = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
85
- if (s.forEach((c) => {
85
+ const t = C(), i = new DOMParser().parseFromString(e, "text/html"), c = Array.from(i.querySelectorAll(S)), n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
86
+ if (c.forEach((s) => {
86
87
  var l;
87
- const r = Number(c.getAttribute("recommendation-id"));
88
+ const r = Number(s.getAttribute("recommendation-id"));
88
89
  if (!Number.isFinite(r))
89
90
  return;
90
91
  const u = ((l = t.blockStates[r]) == null ? void 0 : l.recommendationProducts) ?? [];
91
92
  u.length && P(
92
- o,
93
+ n,
93
94
  a,
94
95
  r,
95
96
  u,
96
- N(c),
97
- c.getAttribute("hide-price") === "true"
97
+ N(s),
98
+ s.getAttribute("hide-price") === "true"
98
99
  );
99
- }), !o.size)
100
+ }), !n.size)
100
101
  return e;
101
- let i = D(e, a);
102
- return i = i.replace(
103
- R,
104
- (c, r) => o.has(r) ? b(o.get(r)) : c
105
- ), i = z(i, o), i;
102
+ let o = I(e, a);
103
+ return o = o.replace(
104
+ T,
105
+ (s, r) => n.has(r) ? L(n.get(r)) : s
106
+ ), o = w(o, n), o;
106
107
  }
107
- const q = () => ({ substituteRecommendationPreview: I });
108
+ const q = () => ({ substituteRecommendationPreview: y });
108
109
  export {
109
- I as substituteRecommendationPreview,
110
+ y as substituteRecommendationPreview,
110
111
  q as useRecommendationPreview
111
112
  };
@@ -1,32 +1,51 @@
1
- import { useActionsApi as H } from "./useActionsApi.js";
2
- import { useConfig as y } from "./useConfig.js";
3
- import { useSaveStart as w, useSaveComplete as k } from "./useGuidoActions.js";
1
+ import { useActionsApi as T } from "./useActionsApi.js";
2
+ import { useConfig as k } from "./useConfig.js";
3
+ import { useSaveStart as B, useSaveComplete as E } from "./useGuidoActions.js";
4
4
  import { useSyncModuleExtractor as q } from "./useSyncModuleExtractor.js";
5
- import { useStripoApi as C } from "../services/stripoApi.js";
6
- import { useTemplatePreparation as E } from "../utils/templatePreparation.js";
7
- import { useHtmlValidator as B } from "./useHtmlValidator.js";
8
- import { useCouponBlockValidator as L } from "./validators/useCouponBlockValidator.js";
9
- import { useLiquidValidator as P } from "./validators/useLiquidValidator.js";
10
- import { useUnsubscribeBlockValidator as U } from "./validators/useUnsubscribeBlockValidator.js";
11
- const K = () => {
12
- const o = w(), s = k(), { validateHtml: r } = B(), { validateLiquidSyntax: l } = P(), { validateCouponBlockTags: n } = L(), { validateUnsubscribeBlockUniqueness: d, validateUnsubscribeBlockHasTemplate: c } = U(), { callbacks: i, isFeatureEnabled: u } = y(), { extractSyncModuleData: m } = q(), { setSyncModuleUnsubscriptionPages: p } = C(), { editorSave: v } = H();
13
- return { save: async (f = !1, S = !1) => {
14
- var a;
15
- o();
16
- const { prepareTemplateDetails: V } = E(), t = await V();
17
- if (!n(t.compiledHtml) || !d(t.compiledHtml) || !c(t.compiledHtml))
5
+ import { ToasterTypeOptions as C } from "../enums/toaster.js";
6
+ import { useStripoApi as D } from "../services/stripoApi.js";
7
+ import { useTemplatePreparation as L } from "../utils/templatePreparation.js";
8
+ import { useAllowlist as P } from "./useAllowlist.js";
9
+ import { useHtmlValidator as U } from "./useHtmlValidator.js";
10
+ import { useToaster as A } from "./useToaster.js";
11
+ import { useCouponBlockValidator as M } from "./validators/useCouponBlockValidator.js";
12
+ import { useLiquidValidator as h } from "./validators/useLiquidValidator.js";
13
+ import { useUnsubscribeBlockValidator as F } from "./validators/useUnsubscribeBlockValidator.js";
14
+ const $ = () => {
15
+ const n = B(), l = E(), { validateHtml: c } = U(), { validateLiquidSyntax: d } = h(), { validateCouponBlockTags: m } = M(), { validateUnsubscribeBlockUniqueness: u, validateUnsubscribeBlockHasTemplate: p } = F(), { callbacks: e, isFeatureEnabled: a } = k(), { extractSyncModuleData: f } = q(), { setSyncModuleUnsubscriptionPages: v } = D(), { editorSave: S } = T(), { showToaster: b } = A(), { getBlockedDomains: w, resolveToast: V } = P();
16
+ return { save: async (y = !1, s = !1) => {
17
+ var r;
18
+ n();
19
+ const { prepareTemplateDetails: H } = L(), t = await H();
20
+ if (!m(t.compiledHtml) || !u(t.compiledHtml) || !p(t.compiledHtml))
18
21
  return;
19
- if (u("liquidSyntax")) {
20
- if (!await l(t.compiledHtml))
22
+ if (a("liquidSyntax")) {
23
+ if (!await d(t.compiledHtml))
21
24
  return;
22
- } else if (!await r(t.compiledHtml, t.dynamicContentList, !0))
25
+ } else if (!await c(t.compiledHtml, t.dynamicContentList, !0))
23
26
  return;
24
- if ((a = i.value) != null && a.externalValidation && !await i.value.externalValidation(t) || !await v())
27
+ if ((r = e.value) != null && r.externalValidation && !await e.value.externalValidation(t))
25
28
  return;
26
- const { unsubscribePayload: b, stripoModules: x } = m(t.rawHtml);
27
- return await p(b), t.modules = x, f || s({ ...t, silent: S }), t;
29
+ if (a("allowlistEnabled")) {
30
+ const i = await w(t.compiledHtml, t.css);
31
+ if (i.length) {
32
+ if (!s) {
33
+ const o = await V(i);
34
+ o != null && o.message && b({
35
+ type: C.Warning,
36
+ message: o.message,
37
+ actionButton: o.actionButton
38
+ });
39
+ }
40
+ return;
41
+ }
42
+ }
43
+ if (!await S())
44
+ return;
45
+ const { unsubscribePayload: g, stripoModules: x } = f(t.rawHtml);
46
+ return await v(g), t.modules = x, y || l({ ...t, silent: s }), t;
28
47
  } };
29
48
  };
30
49
  export {
31
- K as useSave
50
+ $ as useSave
32
51
  };
@@ -1,31 +1,44 @@
1
- import { useActionsApi as x } from "./useActionsApi.js";
1
+ import { useActionsApi as L } from "./useActionsApi.js";
2
2
  import { useBlocksConfig as O } from "./useBlocksConfig.js";
3
3
  import { useConfig as q } from "./useConfig.js";
4
4
  import { useCustomInterfaceAppearance as H } from "./useCustomInterfaceAppearance.js";
5
- import { useFullStoryBridge as L } from "./useFullStoryBridge.js";
6
- import { useModuleDynamicContentRepair as N } from "./useModuleDynamicContentRepair.js";
5
+ import { useFullStoryBridge as N } from "./useFullStoryBridge.js";
6
+ import { useModuleDynamicContentRepair as j } from "./useModuleDynamicContentRepair.js";
7
7
  import { useStripoEventHandler as z } from "./useStripoEventHandler.js";
8
8
  import { useStripoNotifications as $ } from "./useStripoNotifications.js";
9
9
  import { useToaster as G } from "./useToaster.js";
10
10
  import { localePatch as J } from "../config/i18n/index.js";
11
- import { en as E } from "../config/i18n/en/index.js";
11
+ import { en as w } from "../config/i18n/en/index.js";
12
12
  import { ToasterTypeOptions as X } from "../enums/toaster.js";
13
- import { useStripoApi as j } from "../services/stripoApi.js";
14
- import K from "../static/styles/customEditorStyle.css.js";
15
- import { useEditorStore as w } from "../stores/editor.js";
16
- import { buildMergeTagEntries as Q, flattenDynamicContentList as W } from "../utils/genericUtil.js";
17
- import Y from "../package.json.js";
18
- const he = (b, l) => {
19
- const { features: c, template: u, isFeatureEnabled: m } = q(), { handleError: p, showToaster: k } = G(), { getToken: T, getCustomFonts: v, getSyncModulesStatus: B } = j(), { handleEvent: F } = z(), { handleModuleAdd: M } = N(), { getStripoBlocksConfig: A } = O(), { getStripoNotifications: V } = $(), _ = async (n, i = [], r = !1) => {
20
- var S, y, h, C;
21
- const e = w(), { html: f, css: a } = n, { baseBlocks: o, extensions: d } = await A(), g = ((S = c.value) == null ? void 0 : S.displayConditions) ?? !0, P = ((y = c.value) == null ? void 0 : y.modulesDisabled) ?? !1, I = ((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1;
13
+ import { useStripoApi as K } from "../services/stripoApi.js";
14
+ import Q from "../static/styles/customEditorStyle.css.js";
15
+ import { useEditorStore as b } from "../stores/editor.js";
16
+ import { buildMergeTagEntries as W, flattenDynamicContentList as Y } from "../utils/genericUtil.js";
17
+ import Z from "../package.json.js";
18
+ let n = null;
19
+ const Ct = () => {
20
+ const { features: c, template: u, isFeatureEnabled: m } = q(), { handleError: p, showToaster: k } = G(), { getToken: T, getCustomFonts: v, getSyncModulesStatus: B } = K(), { handleEvent: F } = z(), { handleModuleAdd: M } = j(), { getStripoBlocksConfig: A } = O(), { getStripoNotifications: V } = $(), f = () => n || (n = new Promise((i, s) => {
21
+ var l;
22
+ if (document.getElementById("UiEditorScript")) {
23
+ i();
24
+ return;
25
+ }
26
+ const o = Z.guido, r = `https://email-static.useinsider.com/guido/${(l = o == null ? void 0 : o.stripo) == null ? void 0 : l.version}/UIEditor.js`, t = document.createElement("script");
27
+ t.id = "UiEditorScript", t.type = "module", t.src = r, t.onload = () => i(), t.onerror = () => {
28
+ t.remove(), s(new Error(`Failed to load Stripo UIEditor script from S3: ${r}`));
29
+ }, document.body.appendChild(t);
30
+ }), n.catch(() => {
31
+ n = null;
32
+ }), n), _ = async (i, s, o, a = [], r = !1) => {
33
+ var y, E, h, C;
34
+ const t = b(), { html: l, css: D } = i, { baseBlocks: g, extensions: R } = await A(), S = ((y = c.value) == null ? void 0 : y.displayConditions) ?? !0, P = ((E = c.value) == null ? void 0 : E.modulesDisabled) ?? !1, U = ((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1;
22
35
  await window.UIEditor.initEditor(
23
36
  document.querySelector("#guido-editor"),
24
37
  {
25
- metadata: b,
26
- html: f,
27
- css: a,
28
- forceRecreate: I,
38
+ metadata: s,
39
+ html: l,
40
+ css: D,
41
+ forceRecreate: U,
29
42
  locale: "en",
30
43
  undoButtonSelector: "#guido__undo-button",
31
44
  redoButtonSelector: "#guido__redo-button",
@@ -35,9 +48,9 @@ const he = (b, l) => {
35
48
  customAppearanceMergetags: !m("liquidSyntax"),
36
49
  customAppearanceMergetagsBorderColor: "#f1f3fe",
37
50
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
38
- customViewStyles: K,
39
- conditionsEnabled: g,
40
- customConditionsEnabled: g,
51
+ customViewStyles: Q,
52
+ conditionsEnabled: S,
53
+ customConditionsEnabled: S,
41
54
  enableXSSSecurity: !0,
42
55
  modulesDisabled: P,
43
56
  syncModulesEnabled: r,
@@ -49,50 +62,50 @@ const he = (b, l) => {
49
62
  selectElementAfterDrop: !0,
50
63
  sameFontSizeForOutlook: !0,
51
64
  allowedScriptSourceDomains: "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com",
52
- ...o ? { baseBlocks: o } : {},
65
+ ...g ? { baseBlocks: g } : {},
53
66
  editorFonts: {
54
67
  showDefaultStandardFonts: !0,
55
68
  showDefaultNotStandardFonts: !0,
56
- customFonts: i
69
+ customFonts: a
57
70
  },
58
71
  mergeTags: [
59
72
  {
60
- entries: Q(
61
- l.preselectedDynamicContentList,
62
- W((C = u.value) == null ? void 0 : C.dynamicContentList),
73
+ entries: W(
74
+ o.preselectedDynamicContentList,
75
+ Y((C = u.value) == null ? void 0 : C.dynamicContentList),
63
76
  m("liquidSyntax")
64
77
  )
65
78
  }
66
79
  ],
67
- async onTokenRefreshRequest(t) {
80
+ async onTokenRefreshRequest(e) {
68
81
  try {
69
- const s = await T();
70
- t(s);
71
- } catch (s) {
72
- p(s, "Failed to refresh token");
82
+ const d = await T();
83
+ e(d);
84
+ } catch (d) {
85
+ p(d, "Failed to refresh token");
73
86
  }
74
87
  },
75
88
  onTemplateLoaded() {
76
89
  try {
77
- const { importCss: t } = H(), { activateCustomViewStyles: s, updateTimerInClonedTemplate: R } = x(), { injectFullStory: U } = L();
78
- t(), s(), U(), R(), l.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
79
- e.hasChanges = !1;
90
+ const { importCss: e } = H(), { activateCustomViewStyles: d, updateTimerInClonedTemplate: I } = L(), { injectFullStory: x } = N();
91
+ e(), d(), x(), I(), o.onReady(), t.isStripoInitialized = !0, t.loadingStatus = !1, setTimeout(() => {
92
+ t.hasChanges = !1;
80
93
  }, 1e3);
81
- } catch (t) {
82
- p(t, "Failed to load custom interface appearance");
94
+ } catch (e) {
95
+ p(e, "Failed to load custom interface appearance");
83
96
  }
84
97
  },
85
- onCodeEditorVisibilityChanged(t) {
86
- e.isCodeEditorOpen = t;
98
+ onCodeEditorVisibilityChanged(e) {
99
+ t.isCodeEditorOpen = e;
87
100
  },
88
- onEditorVisualModeChanged(t) {
89
- e.editorVisualMode = t.toLowerCase();
101
+ onEditorVisualModeChanged(e) {
102
+ t.editorVisualMode = e.toLowerCase();
90
103
  },
91
- onVersionHistoryVisibilityChanged(t) {
92
- e.isVersionHistoryOpen = t;
104
+ onVersionHistoryVisibilityChanged(e) {
105
+ t.isVersionHistoryOpen = e;
93
106
  },
94
107
  onDataChanged() {
95
- e.hasChanges = !0;
108
+ t.hasChanges = !0;
96
109
  },
97
110
  onEvent: F,
98
111
  onModuleAdd: M,
@@ -102,45 +115,35 @@ const he = (b, l) => {
102
115
  ".in-on-board-wrapper",
103
116
  ".in-drawer__container"
104
117
  ],
105
- extensions: d,
118
+ extensions: R,
106
119
  localePatch: J
107
120
  }
108
121
  );
109
- }, D = (n) => new Promise((i, r) => {
110
- var d;
111
- if (document.getElementById("UiEditorScript")) {
112
- Promise.resolve(n()).then(i, r);
113
- return;
114
- }
115
- const e = Y.guido, a = `https://email-static.useinsider.com/guido/${(d = e == null ? void 0 : e.stripo) == null ? void 0 : d.version}/UIEditor.js`, o = document.createElement("script");
116
- o.id = "UiEditorScript", o.type = "module", o.src = a, o.onload = () => {
117
- Promise.resolve(n()).then(i, r);
118
- }, o.onerror = () => {
119
- r(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
120
- }, document.body.appendChild(o);
121
- });
122
- return { initPlugin: async (n) => {
123
- const i = w();
122
+ };
123
+ return { initPlugin: async (i, s, o) => {
124
+ const a = b();
124
125
  try {
125
- await D(async () => {
126
- const [r, e] = await Promise.all([
127
- v(),
128
- B()
129
- ]);
130
- i.syncModulesEnabled = e, await _(n, r, e);
131
- });
126
+ await f();
127
+ const [r, t] = await Promise.all([
128
+ v(),
129
+ B()
130
+ ]);
131
+ a.syncModulesEnabled = t, await _(i, s, o, r, t);
132
132
  } catch {
133
- i.loadingStatus = !1, k({
133
+ a.loadingStatus = !1, k({
134
134
  type: X.Error,
135
- message: E["An error has occurred. Please report the error code to support."],
135
+ message: w["An error has occurred. Please report the error code to support."],
136
136
  actionButton: {
137
- text: E["Reload page"],
137
+ text: w["Reload page"],
138
138
  onClick: () => window.location.reload()
139
139
  }
140
140
  });
141
141
  }
142
+ }, preloadRuntime: () => {
143
+ f().catch(() => {
144
+ });
142
145
  } };
143
146
  };
144
147
  export {
145
- he as useStripo
148
+ Ct as useStripo
146
149
  };
@@ -1,18 +1,20 @@
1
+ import "../@types/config/schemas.js";
2
+ import { DEFAULT_EDITOR } from "../@types/config/defaults.js";
1
3
  import memoize from "../node_modules/lodash-es/memoize.js";
2
4
  import { ref } from "vue";
3
5
  import { useConfig } from "./useConfig.js";
4
6
  const useTranslations = () => {
5
7
  var o, e;
6
- const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || "window.trans.en", translations = ref(eval(translationsPath)), trans = (n, t) => {
7
- const r = translations.value[n];
8
- return r ? t ? Object.entries(t).reduce(
8
+ const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || DEFAULT_EDITOR.translationsPath, translations = ref(eval(translationsPath)), trans = (t, n) => {
9
+ const r = translations.value[t];
10
+ return r ? n ? Object.entries(n).reduce(
9
11
  (s, [i, a]) => s.replace(new RegExp(`{${i}}`, "g"), String(a)),
10
12
  r
11
- ) : r : (console.warn(`Translation key not found: ${n}`), n);
13
+ ) : r : (console.warn(`Translation key not found: ${t}`), t);
12
14
  };
13
15
  return memoize(
14
16
  trans,
15
- (n, t) => !t || Object.keys(t).length === 0 ? n : JSON.stringify({ key: n, params: t })
17
+ (t, n) => !n || Object.keys(n).length === 0 ? t : JSON.stringify({ key: t, params: n })
16
18
  );
17
19
  };
18
20
  export {
@@ -0,0 +1,12 @@
1
+ import { RoleEnums as t } from "../enums/roles.js";
2
+ import { useAllowlistApi as s } from "../services/allowlistApi.js";
3
+ let e = null, l = null;
4
+ const c = () => {
5
+ const { getUserRole: n } = s();
6
+ return { getIsManageUser: async () => e !== null ? e : (l || (l = n().then((r) => (e = r === t.MANAGE_USERS, e)).catch((r) => (console.error("[GUIDO_ALLOWLIST] role fetch failed", r), !1)).finally(() => {
7
+ l = null;
8
+ })), l) };
9
+ };
10
+ export {
11
+ c as useUserRole
12
+ };
@@ -0,0 +1,4 @@
1
+ var e = /* @__PURE__ */ ((r) => (r.MANAGE_USERS = "manage-users", r))(e || {});
2
+ export {
3
+ e as RoleEnums
4
+ };