@useinsider/guido 3.12.0-beta.cfe6433 → 3.12.0-beta.d77b0d2

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 (92) hide show
  1. package/dist/@types/config/schemas.js +9 -4
  2. package/dist/components/Guido.vue.js +6 -6
  3. package/dist/components/Guido.vue2.js +50 -49
  4. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  5. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  6. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  7. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  8. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.js +38 -0
  9. package/dist/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue2.js +271 -0
  10. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.js +18 -0
  11. package/dist/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue2.js +42 -0
  12. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.js +20 -0
  13. package/dist/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue2.js +18 -0
  14. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.js +20 -0
  15. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue2.js +60 -0
  16. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.js +19 -0
  17. package/dist/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue2.js +19 -0
  18. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.js +22 -0
  19. package/dist/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue2.js +29 -0
  20. package/dist/composables/useHtmlValidator.js +68 -60
  21. package/dist/composables/useHttp.js +61 -52
  22. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  23. package/dist/composables/useRecommendation.js +56 -40
  24. package/dist/composables/useRecommendationPreview.js +61 -60
  25. package/dist/composables/useSave.js +22 -22
  26. package/dist/composables/useStrategyFilters.js +16 -0
  27. package/dist/config/migrator/recommendationMigrator.js +7 -4
  28. package/dist/enums/date.js +4 -3
  29. package/dist/enums/extensions/filteringV2.js +1024 -0
  30. package/dist/enums/extensions/recommendationBlock.js +45 -24
  31. package/dist/enums/extensions/strategyDetail.js +149 -0
  32. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  33. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +12 -11
  34. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +141 -123
  36. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +297 -0
  37. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  38. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +16 -2
  39. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +137 -0
  40. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  41. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +549 -165
  42. package/dist/extensions/Blocks/Recommendation/utils/strategyHumanizer.js +97 -0
  43. package/dist/extensions/Blocks/Recommendation/utils/strategyNavigation.js +8 -0
  44. package/dist/extensions/Blocks/Recommendation/utils/strategySummary.js +95 -0
  45. package/dist/extensions/Blocks/Recommendation/utils/strategyUrl.js +43 -0
  46. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +24 -10
  47. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  48. package/dist/extensions/Blocks/common-control.js +37 -35
  49. package/dist/extensions/Blocks/controlFactories.js +125 -75
  50. package/dist/guido.css +1 -1
  51. package/dist/services/recommendationApi.js +127 -33
  52. package/dist/services/stripoApi.js +18 -18
  53. package/dist/src/@types/config/schemas.d.ts +10 -0
  54. package/dist/src/components/organisms/extensions/recommendation/StrategyDetailDrawer.vue.d.ts +2 -0
  55. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/CampaignTable.vue.d.ts +43 -0
  56. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/FilterHumanizer.vue.d.ts +29 -0
  57. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerCondition.vue.d.ts +40 -0
  58. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/HumanizerGroup.vue.d.ts +38 -0
  59. package/dist/src/components/organisms/extensions/recommendation/strategy-detail/InfoDisplayValue.vue.d.ts +51 -0
  60. package/dist/src/composables/useConfig.d.ts +2 -0
  61. package/dist/src/composables/useHtmlValidator.d.ts +2 -0
  62. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  63. package/dist/src/composables/useRecommendation.d.ts +2 -0
  64. package/dist/src/composables/useStrategyFilters.d.ts +24 -0
  65. package/dist/src/enums/extensions/filteringV2.d.ts +72 -0
  66. package/dist/src/enums/extensions/recommendationBlock.d.ts +33 -0
  67. package/dist/src/enums/extensions/strategyDetail.d.ts +90 -0
  68. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  69. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  70. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  71. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +10 -4
  72. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +118 -0
  73. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +958 -1
  74. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +7 -0
  75. package/dist/src/extensions/Blocks/Recommendation/utils/strategyHumanizer.d.ts +50 -0
  76. package/dist/src/extensions/Blocks/Recommendation/utils/strategyNavigation.d.ts +10 -0
  77. package/dist/src/extensions/Blocks/Recommendation/utils/strategySummary.d.ts +34 -0
  78. package/dist/src/extensions/Blocks/Recommendation/utils/strategyUrl.d.ts +51 -0
  79. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +8 -1
  80. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  81. package/dist/src/extensions/Blocks/common-control.d.ts +5 -2
  82. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  83. package/dist/src/mock/api/recommendation-strategies.d.ts +2 -0
  84. package/dist/src/services/recommendationApi.d.ts +9 -1
  85. package/dist/src/stores/config.d.ts +18 -0
  86. package/dist/src/utils/genericUtil.d.ts +9 -0
  87. package/dist/src/utils/urlSchemes.d.ts +6 -0
  88. package/dist/utils/dateUtil.js +23 -10
  89. package/dist/utils/genericUtil.js +10 -1
  90. package/dist/utils/templatePreparation.js +70 -57
  91. package/dist/utils/urlSchemes.js +4 -0
  92. package/package.json +1 -1
@@ -2,7 +2,7 @@ import { useConfig as W } from "./useConfig.js";
2
2
  import { getIgnoredRecommendationBlockIds as G } from "../config/compiler/utils/recommendationIgnoreUtils.js";
3
3
  import { TemplateTypes as H } from "../enums/defaults.js";
4
4
  import { DISPLAY_CONDITIONS_REGEX as P, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as X, CampaignCouldNotBeSavedKey as $, CanNotMakeAnyChangesForRunningKey as Y, DATA_ATTRIBUTE_REGEX as U, DYNAMIC_CONTENT_TAG_REGEX as j, ALLOWED_DYNAMIC_SYSTEM_TOKENS as q, VALID_DYNAMIC_VARIABLE_REGEX as K } from "../enums/html-validator.js";
5
- import { ToasterTypeOptions as c } from "../enums/toaster.js";
5
+ import { ToasterTypeOptions as l } from "../enums/toaster.js";
6
6
  import { itemsBlockDynamicVariables as z } from "../extensions/Blocks/Items/enums/productEnums.js";
7
7
  import { RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES as Z } from "../extensions/Blocks/Recommendation/constants/selectors.js";
8
8
  import { useRecommendationExtensionStore as J } from "../extensions/Blocks/Recommendation/store/recommendation.js";
@@ -57,8 +57,8 @@ function fe(t) {
57
57
  });
58
58
  }
59
59
  const xe = () => {
60
- var b, S;
61
- const { showToaster: t } = re(), { post: m } = se(), { config: f } = W(), o = oe(), d = te(), u = J(), p = ((S = (b = f.value) == null ? void 0 : b.partner) == null ? void 0 : S.messageType) === H.transactional, E = async (e) => {
60
+ var A, T;
61
+ const { showToaster: t } = re(), { post: m } = se(), { config: f } = W(), o = oe(), d = te(), u = J(), p = ((T = (A = f.value) == null ? void 0 : A.partner) == null ? void 0 : T.messageType) === H.transactional, E = async (e) => {
62
62
  if (e.size === 0)
63
63
  return /* @__PURE__ */ new Set();
64
64
  try {
@@ -68,136 +68,144 @@ const xe = () => {
68
68
  }
69
69
  return ue(u.filterList);
70
70
  }, h = async (e) => {
71
- const n = await m(
71
+ const r = (await m(
72
72
  "/newsletter/template-library/check-template-html-body",
73
73
  { html: ne(e) }
74
- ), { status: r, message: a } = n.data;
75
- return r || t({
76
- type: c.Error,
77
- message: r === void 0 ? a : o("newsletter.invalid-url-link-for-toaster")
78
- }), o($), a === o(Y) && t({
79
- type: c.Error,
74
+ )).data ?? {}, { message: c } = r, i = r.status === !0;
75
+ if (!i) {
76
+ const a = o("newsletter.invalid-url-link-for-toaster");
77
+ t({
78
+ type: l.Error,
79
+ // `status: false` is a business rejection and keeps our own copy. Any
80
+ // other shape means the answer was unreadable — show what came back,
81
+ // and fall back to the same copy when nothing did, so the toast is
82
+ // never blank while the save is silently cancelled.
83
+ message: r.status === !1 ? a : c || a
84
+ });
85
+ }
86
+ return o($), c === o(Y) && t({
87
+ type: l.Error,
80
88
  message: o("newsletter.already-in-progress")
81
- }), r;
82
- }, g = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), y = (e) => ["if", "endif"].includes(e.toLowerCase()), T = (e, s) => {
89
+ }), i;
90
+ }, g = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), y = (e) => ["if", "endif"].includes(e.toLowerCase()), R = (e, s) => {
83
91
  const n = e.match(/({%(.*?)%})/g);
84
92
  let r = !0;
85
- return n !== null && !p && n.forEach((a) => {
86
- const i = a.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
93
+ return n !== null && !p && n.forEach((c) => {
94
+ const i = c.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
87
95
  if (i && i.length > 0) {
88
- const [l] = i;
89
- g(l) && !s.includes(l) && (t({
90
- type: c.Warning,
96
+ const [a] = i;
97
+ g(a) && !s.includes(a) && (t({
98
+ type: l.Warning,
91
99
  message: o("custom-fields.invalid-custom-fields")
92
100
  }), r = !1);
93
101
  }
94
102
  }), r;
95
- }, w = async (e, s, n) => {
103
+ }, _ = async (e, s, n) => {
96
104
  const r = n ? await h(e) : !0;
97
- return T(e, s) && r;
98
- }, R = (e) => e.length > 0 ? !0 : (t({
99
- type: c.Warning,
105
+ return R(e, s) && r;
106
+ }, N = (e) => e.length > 0 ? !0 : (t({
107
+ type: l.Warning,
100
108
  message: o("newsletter.html-content-is-empty")
101
- }), !1), _ = (e) => {
109
+ }), !1), x = (e) => {
102
110
  const s = (e.match(/{/gm) || []).length, n = (e.match(/}/gm) || []).length;
103
111
  return s > n && t({
104
- type: c.Warning,
112
+ type: l.Warning,
105
113
  message: o("custom-fields.missing-closing-braces")
106
114
  }), s < n && t({
107
- type: c.Warning,
115
+ type: l.Warning,
108
116
  message: o("custom-fields.missing-opening-braces")
109
117
  }), s === n;
110
- }, N = (e) => {
118
+ }, k = (e) => {
111
119
  const s = fe(e).length === 0;
112
120
  return s || t({
113
- type: c.Warning,
121
+ type: l.Warning,
114
122
  message: o("custom-fields.invalid-custom-fields")
115
123
  }), s;
116
- }, x = (e, s, n, r) => {
124
+ }, O = (e, s, n, r) => {
117
125
  if (p)
118
126
  return !0;
119
- const a = de(
127
+ const c = de(
120
128
  e,
121
129
  s,
122
130
  ae(e),
123
131
  n,
124
132
  r
125
133
  );
126
- if (a.length > 0) {
134
+ if (c.length > 0) {
127
135
  const i = `
128
136
  <ul>
129
- ${a.map((l) => `<li>${l}</li>`).join("")}
137
+ ${c.map((a) => `<li>${a}</li>`).join("")}
130
138
  </ul>
131
139
  `;
132
140
  return t({
133
- type: c.Error,
141
+ type: l.Error,
134
142
  message: o("custom-fields.invalid-custom-fields") + i
135
143
  }), !1;
136
144
  }
137
145
  return !0;
138
- }, O = (e) => {
146
+ }, B = (e) => {
139
147
  const s = e.match(/{%(.*?)%}/g), n = [];
140
148
  let r = !0;
141
- if (s && s.forEach((a) => {
142
- const i = a.match(P), l = a.match(X), v = (i == null ? void 0 : i.join("")) || "";
143
- (!i || a !== v) && !l && (t({
144
- type: c.Error,
149
+ if (s && s.forEach((c) => {
150
+ const i = c.match(P), a = c.match(X), v = (i == null ? void 0 : i.join("")) || "";
151
+ (!i || c !== v) && !a && (t({
152
+ type: l.Error,
145
153
  message: o("newsletter.display-conditions-invalid-syntax")
146
154
  }), r = !1), i && i.forEach((C) => {
147
155
  C.trim() === "=" && (t({
148
- type: c.Error,
156
+ type: l.Error,
149
157
  message: o("custom-conditions.wrong-equality-operators")
150
158
  }), r = !1);
151
159
  const I = C.match(/^[a-zA-Z]*$/g);
152
- I && I.forEach((A) => {
153
- y(A) && n.push(A);
160
+ I && I.forEach((w) => {
161
+ y(w) && n.push(w);
154
162
  });
155
163
  });
156
164
  }), n.length) {
157
- const a = n.filter((l) => l === "if"), i = n.filter((l) => l === "endif");
158
- a.length !== i.length && (t({
159
- type: c.Error,
165
+ const c = n.filter((a) => a === "if"), i = n.filter((a) => a === "endif");
166
+ c.length !== i.length && (t({
167
+ type: l.Error,
160
168
  message: o("custom-conditions.missing-if-endif-tag")
161
169
  }), r = !1);
162
170
  }
163
171
  return r;
164
- }, k = (e) => {
172
+ }, D = (e) => {
165
173
  const s = (e.match(/{% /gm) || []).length, n = (e.match(/ %}/gm) || []).length, r = s === n;
166
174
  return r || t({
167
- type: c.Warning,
175
+ type: l.Warning,
168
176
  message: o("custom-conditions.no-space-after-braces")
169
177
  }), r;
170
- }, B = (e) => (e.match(/({%(.*?)%})/g) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, r) => n + r, 0) > 0 ? (t({
171
- type: c.Warning,
178
+ }, F = (e) => (e.match(/({%(.*?)%})/g) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, r) => n + r, 0) > 0 ? (t({
179
+ type: l.Warning,
172
180
  message: o("custom-conditions.no-braces-inside-if-tag")
173
- }), !1) : !0, D = () => u.hasInvalidBlock() ? (t({
174
- type: c.Error,
181
+ }), !1) : !0, b = () => u.hasInvalidBlock() ? (t({
182
+ type: l.Error,
175
183
  message: o(ee)
176
- }), !1) : !0, F = () => d.recommendationConfigs && Object.values(d.recommendationConfigs).find((s) => s.filters.find((n) => n.value === "")) !== void 0 ? (t({
177
- type: c.Error,
184
+ }), !1) : !0, S = () => d.recommendationConfigs && Object.values(d.recommendationConfigs).find((s) => s.filters.find((n) => n.value === "")) !== void 0 ? (t({
185
+ type: l.Error,
178
186
  message: o("newsletter.fill-all-necessary-fields")
179
187
  }), !1) : !0, L = (e) => {
180
188
  const s = /src="[^"]*\.(svg|pst)"/gm;
181
189
  return e.match(s) === null ? !0 : (t({
182
- type: c.Error,
190
+ type: l.Error,
183
191
  message: o("newsletter.invalid-image-type")
184
192
  }), !1);
185
193
  }, V = (e) => {
186
194
  const r = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
187
195
  return Array.from(r).find((i) => {
188
- var l;
189
- return !((l = i.id) != null && l.trim());
196
+ var a;
197
+ return !((a = i.id) != null && a.trim());
190
198
  }) ? (t({
191
- type: c.Error,
199
+ type: l.Error,
192
200
  message: o("unsubscribe-templates.select-checkbox-groups")
193
201
  }), !1) : !0;
194
202
  }, M = (e) => {
195
203
  const r = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
196
204
  return Array.from(r).find((i) => {
197
- var l;
198
- return !((l = i.id) != null && l.trim());
205
+ var a;
206
+ return !((a = i.id) != null && a.trim());
199
207
  }) ? (t({
200
- type: c.Error,
208
+ type: l.Error,
201
209
  message: o("unsubscribe-templates.select-radio-button-groups")
202
210
  }), !1) : !0;
203
211
  };
@@ -207,9 +215,9 @@ const xe = () => {
207
215
  ...s.map((I) => I.value),
208
216
  ...z,
209
217
  ...((C = (v = f.value) == null ? void 0 : v.template) == null ? void 0 : C.customFieldAttributes) ?? []
210
- ], a = G(e), i = await E(a);
211
- return await w(e, r, n) && R(e) && _(e) && N(e) && x(e, r, a, i) && O(e) && k(e) && B(e) && D() && F() && L(e) && V(e) && M(e);
212
- } };
218
+ ], c = G(e), i = await E(c);
219
+ return await _(e, r, n) && N(e) && x(e) && k(e) && O(e, r, c, i) && B(e) && D(e) && F(e) && b() && S() && L(e) && V(e) && M(e);
220
+ }, validateRecommendationBlocks: b, validateRecommendationFilters: S };
213
221
  };
214
222
  export {
215
223
  ue as buildPartnerAttributeNameSet,
@@ -1,84 +1,93 @@
1
- import { getCsrfToken as H } from "../utils/genericUtil.js";
2
- import { ref as p, computed as T } from "vue";
3
- const k = (b = {}) => {
4
- const h = p(!1), a = p(null), u = p(null), g = T(() => h.value), y = T(() => a.value !== null), v = {
1
+ import { getCsrfToken as S } from "../utils/genericUtil.js";
2
+ import { ref as T, computed as v } from "vue";
3
+ const H = (c) => {
4
+ const a = c.trim();
5
+ if (!a.startsWith("{") && !a.startsWith("["))
6
+ return c;
7
+ try {
8
+ return JSON.parse(a);
9
+ } catch {
10
+ return c;
11
+ }
12
+ }, k = (c = {}) => {
13
+ const a = T(!1), n = T(null), f = T(null), b = v(() => a.value), g = v(() => n.value !== null), y = {
5
14
  baseURL: "",
6
15
  timeout: 1e4,
7
16
  retry: 0,
8
17
  retryDelay: 1e3,
9
18
  headers: {
10
19
  "Content-Type": "application/json",
11
- "X-CSRF-TOKEN": H()
20
+ "X-CSRF-TOKEN": S()
12
21
  },
13
- ...b
14
- }, w = (e, s) => {
15
- if (e.startsWith("http://") || e.startsWith("https://"))
16
- return e;
17
- const t = s || v.baseURL || "";
18
- return t.endsWith("/") && e.startsWith("/") ? `${t}${e.slice(1)}` : t.endsWith("/") || e.startsWith("/") ? `${t}${e}` : `${t}/${e}`;
19
- }, P = (e) => new Promise((s, t) => {
22
+ ...c
23
+ }, w = (t, s) => {
24
+ if (t.startsWith("http://") || t.startsWith("https://"))
25
+ return t;
26
+ const e = s || y.baseURL || "";
27
+ return e.endsWith("/") && t.startsWith("/") ? `${e}${t.slice(1)}` : e.endsWith("/") || t.startsWith("/") ? `${e}${t}` : `${e}/${t}`;
28
+ }, P = (t) => new Promise((s, e) => {
20
29
  setTimeout(() => {
21
- t(new Error("Request timeout"));
22
- }, e);
23
- }), x = (e) => new Promise((s) => {
24
- setTimeout(s, e);
25
- }), i = async (e, s, t, D = {}) => {
26
- a.value = null, h.value = !0, u.value = new AbortController();
27
- const n = { ...v, ...D }, L = w(s, n.baseURL), c = {
28
- method: e,
29
- headers: { ...n.headers },
30
- signal: u.value.signal,
31
- ...n
30
+ e(new Error("Request timeout"));
31
+ }, t);
32
+ }), C = (t) => new Promise((s) => {
33
+ setTimeout(s, t);
34
+ }), l = async (t, s, e, q = {}) => {
35
+ n.value = null, a.value = !0, f.value = new AbortController();
36
+ const i = { ...y, ...q }, D = w(s, i.baseURL), d = {
37
+ method: t,
38
+ headers: { ...i.headers },
39
+ signal: f.value.signal,
40
+ ...i
32
41
  };
33
- t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete c.headers["Content-Type"], c.body = t) : c.body = JSON.stringify(t));
34
- const E = async (m = 0) => {
42
+ e && ["POST", "PUT", "PATCH"].includes(t) && (e instanceof FormData ? (delete d.headers["Content-Type"], d.body = e) : d.body = JSON.stringify(e));
43
+ const E = async (p = 0) => {
35
44
  try {
36
- const o = [fetch(L, c)];
37
- n.timeout && o.push(P(n.timeout));
45
+ const o = [fetch(D, d)];
46
+ i.timeout && o.push(P(i.timeout));
38
47
  const r = await Promise.race(o);
39
48
  if (!r.ok) {
40
- const O = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(O);
41
- throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
49
+ const L = `HTTP Error: ${r.status} ${r.statusText}`, m = new Error(L);
50
+ throw m.status = r.status, m.statusText = r.statusText, m.response = r, m;
42
51
  }
43
- let f;
44
- const l = r.headers.get("content-type");
45
- return l != null && l.includes("application/json") ? f = await r.json() : l != null && l.includes("text/") ? f = await r.text() : f = await r.blob(), {
46
- data: f,
52
+ let h;
53
+ const u = r.headers.get("content-type");
54
+ return u != null && u.includes("application/json") ? h = await r.json() : u != null && u.includes("text/") ? h = H(await r.text()) : h = await r.blob(), {
55
+ data: h,
47
56
  status: r.status,
48
57
  statusText: r.statusText,
49
58
  headers: r.headers
50
59
  };
51
60
  } catch (o) {
52
61
  const r = o instanceof Error && o.name === "AbortError";
53
- if (m < (n.retry || 0) && !r)
54
- return await x(n.retryDelay || 1e3), E(m + 1);
55
- throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
62
+ if (p < (i.retry || 0) && !r)
63
+ return await C(i.retryDelay || 1e3), E(p + 1);
64
+ throw o instanceof Error ? o.name === "AbortError" ? n.value = { message: "Request was cancelled" } : n.value = { message: o.message } : n.value = o, o;
56
65
  }
57
66
  };
58
67
  try {
59
68
  return await E();
60
69
  } finally {
61
- h.value = !1, u.value = null;
70
+ a.value = !1, f.value = null;
62
71
  }
63
- }, C = (e, s) => i("GET", e, void 0, s), $ = (e, s, t) => i("POST", e, s, t), R = (e, s, t) => i("PUT", e, s, t), U = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), W = (e) => {
64
- u.value && u.value.abort(e);
65
- }, q = () => {
66
- a.value = null;
72
+ }, x = (t, s) => l("GET", t, void 0, s), W = (t, s, e) => l("POST", t, s, e), $ = (t, s, e) => l("PUT", t, s, e), R = (t, s, e) => l("PATCH", t, s, e), U = (t, s) => l("DELETE", t, void 0, s), A = (t) => {
73
+ f.value && f.value.abort(t);
74
+ }, O = () => {
75
+ n.value = null;
67
76
  };
68
77
  return {
69
78
  // State
70
- loading: g,
71
- error: T(() => a.value),
72
- hasError: y,
79
+ loading: b,
80
+ error: v(() => n.value),
81
+ hasError: g,
73
82
  // Methods
74
- request: i,
75
- get: C,
76
- post: $,
77
- put: R,
78
- patch: U,
79
- delete: A,
80
- cancel: W,
81
- clearError: q
83
+ request: l,
84
+ get: x,
85
+ post: W,
86
+ put: $,
87
+ patch: R,
88
+ delete: U,
89
+ cancel: A,
90
+ clearError: O
82
91
  };
83
92
  };
84
93
  export {
@@ -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,22 +1,23 @@
1
- import { getRecommendationFeedSourceMaps as I, URLS as R } from "../enums/extensions/recommendationBlock.js";
2
- import { MinDeviceViewport as C, DefaultPadding as b } from "../enums/recommendation.js";
3
- import { useRecommendationExtensionStore as l } from "../extensions/Blocks/Recommendation/store/recommendation.js";
1
+ import { getRecommendationFeedSourceMaps as I, URLS as C } from "../enums/extensions/recommendationBlock.js";
2
+ import { MinDeviceViewport as R, DefaultPadding as b } from "../enums/recommendation.js";
3
+ import { useRecommendationExtensionStore as g } from "../extensions/Blocks/Recommendation/store/recommendation.js";
4
4
  import { generateCompleteFilterQuery as h } from "../extensions/Blocks/Recommendation/utils/filterUtil.js";
5
- import { getPartnerRecommendationParams as y } from "../extensions/Blocks/Recommendation/utils/partnerCustomizations.js";
6
- import { useConfigStore as x } from "../stores/config.js";
7
- const k = () => ({
5
+ import { getPartnerRecommendationParams as S } from "../extensions/Blocks/Recommendation/utils/partnerCustomizations.js";
6
+ import { resolveStrategyUrl as T, buildStrategyUrlValues as x } from "../extensions/Blocks/Recommendation/utils/strategyUrl.js";
7
+ import { useConfigStore as P } from "../stores/config.js";
8
+ const L = () => ({
8
9
  calculateCardWidth: ({
9
- mobileLeftPadding: a,
10
- mobileRightPadding: s,
11
- cardsInRow: c,
12
- unresponsive: o
10
+ mobileLeftPadding: i,
11
+ mobileRightPadding: c,
12
+ cardsInRow: o,
13
+ unresponsive: s
13
14
  }) => {
14
- const r = o ? c : 1, e = a + s + (r - 1) * b;
15
- return (C - e) / r;
15
+ const n = s ? o : 1, e = i + c + (n - 1) * b;
16
+ return (R - e) / n;
16
17
  },
17
- getRecommendationCampaignData: (a) => {
18
- const s = l(), c = Number(a), o = s.blockStates[c];
19
- if (!o)
18
+ getRecommendationCampaignData: (i) => {
19
+ const c = g(), o = Number(i), s = c.blockStates[o];
20
+ if (!s)
20
21
  return {
21
22
  textTrimming: !1,
22
23
  orientation: "vertical",
@@ -29,49 +30,64 @@ const k = () => ({
29
30
  discountBeforeTextValue: "",
30
31
  discountAfterTextValue: ""
31
32
  };
32
- const { recommendationConfigs: r } = o, e = r.orientation === "grid" ? "vertical" : "horizontal";
33
+ const { recommendationConfigs: n } = s, e = n.orientation === "grid" ? "vertical" : "horizontal";
33
34
  return {
34
- textTrimming: r.textTrimming,
35
+ textTrimming: n.textTrimming,
35
36
  orientation: e,
36
37
  mobileLeftPadding: 0,
37
38
  mobileRightPadding: 0,
38
- cardsInRow: r.cardsInRow,
39
- unresponsive: r.unresponsive,
39
+ cardsInRow: n.cardsInRow,
40
+ unresponsive: n.unresponsive,
40
41
  priceBeforeTextValue: "",
41
42
  priceAfterTextValue: "",
42
43
  discountBeforeTextValue: "",
43
44
  discountAfterTextValue: ""
44
45
  };
45
46
  },
46
- buildCampaignUrl: (a, s) => {
47
+ buildCampaignUrl: (i, c) => {
47
48
  var m;
48
- const c = l(), o = x(), r = Number(a);
49
+ const o = g(), s = P(), n = Number(i);
49
50
  let e;
50
- if (s)
51
- e = s;
51
+ if (c)
52
+ e = c;
52
53
  else {
53
- const i = c.blockStates[r];
54
- if (!i)
54
+ const r = o.blockStates[n];
55
+ if (!r)
55
56
  return "";
56
- const { recommendationConfigs: n } = i;
57
+ const { recommendationConfigs: a } = r;
57
58
  e = {
58
- strategy: n.strategy,
59
- language: n.language,
60
- currencyCode: n.currencySettings.value,
61
- size: n.size,
62
- productIds: n.productIds,
63
- filters: n.filters,
64
- shuffleProducts: n.shuffleProducts
59
+ strategy: a.strategy,
60
+ strategyId: a.strategyId,
61
+ language: a.language,
62
+ currencyCode: a.currencySettings.value,
63
+ size: a.size,
64
+ productIds: a.productIds,
65
+ filters: a.filters,
66
+ shuffleProducts: a.shuffleProducts
65
67
  };
66
68
  }
67
- const f = ((m = I().find((i) => i.key === e.strategy)) == null ? void 0 : m.path) || "", t = new URLSearchParams();
68
- t.set("locale", e.language), t.set("currency", e.currencyCode), t.set("partnerName", o.partnerName), t.set("size", e.size), t.set("details", "true"), t.set("campaignId", o.variationId), e.strategy === "manualMerchandising" ? t.set("productId", e.productIds.join(",")) : e.strategy === "similarViewed" && t.set("productId", "{itemId}"), e.strategy === "userBased" && t.set("userId", "{user_id}");
69
- const g = e.filters.filter((i) => i.isValid), d = h(g);
70
- d && t.set("filter", d), e.shuffleProducts && t.set("shuffle", "true"), Object.entries(y(o.partnerName, e.strategy)).forEach(([i, n]) => t.set(i, n));
71
- const p = decodeURIComponent(t.toString()), u = `${R.RECOMMENDATION_API_URL}/v2/${f}?${p}`;
72
- return c.recommendationCampaignUrls[a] = u, u;
69
+ const d = e.strategyId ? o.strategyUrlTemplates[e.strategyId] : "";
70
+ if (d) {
71
+ const r = T(
72
+ d,
73
+ x({
74
+ language: e.language,
75
+ currencyCode: e.currencyCode,
76
+ size: e.size,
77
+ strategyId: e.strategyId
78
+ }),
79
+ "compile"
80
+ );
81
+ return o.recommendationCampaignUrls[i] = r, r;
82
+ }
83
+ const f = ((m = I().find((r) => r.key === e.strategy)) == null ? void 0 : m.path) || "", t = new URLSearchParams();
84
+ t.set("locale", e.language), t.set("currency", e.currencyCode), t.set("partnerName", s.partnerName), t.set("size", e.size), t.set("details", "true"), t.set("campaignId", s.variationId), e.strategy === "manualMerchandising" ? t.set("productId", e.productIds.join(",")) : e.strategy === "similarViewed" && t.set("productId", "{itemId}"), e.strategy === "userBased" && t.set("userId", "{user_id}");
85
+ const p = e.filters.filter((r) => r.isValid), l = h(p);
86
+ l && t.set("filter", l), e.shuffleProducts && t.set("shuffle", "true"), Object.entries(S(s.partnerName, e.strategy)).forEach(([r, a]) => t.set(r, a));
87
+ const y = decodeURIComponent(t.toString()), u = `${C.RECOMMENDATION_API_URL}/v2/${f}?${y}`;
88
+ return o.recommendationCampaignUrls[i] = u, u;
73
89
  }
74
90
  });
75
91
  export {
76
- k as useRecommendation
92
+ L as useRecommendation
77
93
  };