@useinsider/guido 3.7.0-beta.509616e → 3.7.0-beta.61e8940

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 (37) hide show
  1. package/dist/composables/useHtmlValidator.js +104 -98
  2. package/dist/enums/html-validator.js +13 -5
  3. package/dist/enums/toaster.js +1 -1
  4. package/dist/extensions/Blocks/Recommendation/block.js +16 -35
  5. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +9 -9
  6. package/dist/src/enums/html-validator.d.ts +3 -0
  7. package/dist/src/enums/toaster.d.ts +1 -2
  8. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -13
  9. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +2 -3
  10. package/dist/stores/dynamic-content.js +1 -1
  11. package/package.json +1 -1
  12. package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +0 -16
  13. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +0 -9
  14. package/dist/src/composables/useApiExample.d.ts +0 -63
  15. package/dist/src/composables/useRecommendation.test.d.ts +0 -1
  16. package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +0 -1
  17. package/dist/src/config/migrator/recommendation/extractors.test.d.ts +0 -1
  18. package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +0 -1
  19. package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +0 -1
  20. package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +0 -1
  21. package/dist/src/config/migrator/recommendationMigrator.test.d.ts +0 -1
  22. package/dist/src/extensions/Blocks/Recommendation/block.test.d.ts +0 -1
  23. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +0 -1
  24. package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +0 -1
  25. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.test.d.ts +0 -1
  26. package/dist/src/extensions/Blocks/Recommendation/templates/utils.test.d.ts +0 -1
  27. package/dist/src/extensions/Blocks/Recommendation/useRecommendationBlockWarning.d.ts +0 -12
  28. package/dist/src/extensions/Blocks/Recommendation/utils/filterUtil.test.d.ts +0 -1
  29. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +0 -1
  30. package/dist/src/extensions/Blocks/Recommendation/utils/priceFormatter.test.d.ts +0 -1
  31. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +0 -28
  32. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.test.d.ts +0 -1
  33. package/dist/src/stores/config.test.d.ts +0 -1
  34. package/dist/src/utils/ampErrorFilter.test.d.ts +0 -1
  35. package/dist/src/utils/htmlEscape.test.d.ts +0 -1
  36. package/dist/src/utils/templatePreparation.test.d.ts +0 -1
  37. package/dist/src/vitest.setup.d.ts +0 -0
@@ -1,166 +1,172 @@
1
- import { useConfig as _ } from "./useConfig.js";
2
- import { TemplateTypes as H } from "../enums/defaults.js";
3
- import { DISPLAY_CONDITIONS_REGEX as P, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as G, CampaignCouldNotBeSavedKey as M, CanNotMakeAnyChangesForRunningKey as $ } from "../enums/html-validator.js";
1
+ import { useConfig as V } from "./useConfig.js";
2
+ import { TemplateTypes as M } from "../enums/defaults.js";
3
+ import { DISPLAY_CONDITIONS_REGEX as G, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as H, CampaignCouldNotBeSavedKey as P, CanNotMakeAnyChangesForRunningKey as X, DYNAMIC_CONTENT_TAG_REGEX as Y, ALLOWED_DYNAMIC_SYSTEM_TOKENS as $, VALID_DYNAMIC_VARIABLE_REGEX as q } from "../enums/html-validator.js";
4
4
  import { ToasterTypeOptions as c } from "../enums/toaster.js";
5
- import { itemsBlockDynamicVariables as q } from "../extensions/Blocks/Items/enums/productEnums.js";
6
- import { useRecommendationExtensionStore as X } from "../extensions/Blocks/Recommendation/store/recommendation.js";
7
- import { RecommendationRequiredFieldsKey as j } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
8
- import { useRecommendationStore as K } from "../stores/recommendation.js";
9
- import { base64EncodeWithSpecialChars as z } from "../utils/base64.js";
10
- import { useHttp as U } from "./useHttp.js";
11
- import { useToaster as Y } from "./useToaster.js";
12
- import { useTranslations as Z } from "./useTranslations.js";
13
- const J = /recommendation-id="(\d+)"/g;
14
- function Q(a) {
15
- return [...a.matchAll(J)].map((u) => u[1]);
5
+ import { itemsBlockDynamicVariables as K } from "../extensions/Blocks/Items/enums/productEnums.js";
6
+ import { useRecommendationExtensionStore as j } from "../extensions/Blocks/Recommendation/store/recommendation.js";
7
+ import { RecommendationRequiredFieldsKey as z } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
8
+ import { useRecommendationStore as U } from "../stores/recommendation.js";
9
+ import { base64EncodeWithSpecialChars as Z } from "../utils/base64.js";
10
+ import { useHttp as J } from "./useHttp.js";
11
+ import { useToaster as Q } from "./useToaster.js";
12
+ import { useTranslations as ee } from "./useTranslations.js";
13
+ const te = /recommendation-id="(\d+)"/g;
14
+ function se(o) {
15
+ return [...o.matchAll(te)].map((d) => d[1]);
16
16
  }
17
- function ee(a, u) {
18
- return u.some((d) => a.startsWith(`${d}_`));
17
+ function ne(o, d) {
18
+ return d.some((f) => o.startsWith(`${f}_`));
19
19
  }
20
- const ge = () => {
21
- var y, h;
22
- const { showToaster: a } = Y(), { post: u } = U(), { config: d } = _(), r = Z(), g = K(), S = X(), p = ((h = (y = d.value) == null ? void 0 : y.partner) == null ? void 0 : h.messageType) === H.transactional, b = async (e) => {
23
- const t = await u(
20
+ function ie(o) {
21
+ return (o.match(Y) ?? []).filter((f) => {
22
+ const i = f.slice(2, -2), u = i.indexOf("|"), g = (u === -1 ? i : i.slice(0, u)).trim();
23
+ return $.includes(g) ? !1 : q.test(g) ? u !== -1 && i.slice(u + 1).trim() === "" : !0;
24
+ });
25
+ }
26
+ const ve = () => {
27
+ var h, v;
28
+ const { showToaster: o } = Q(), { post: d } = J(), { config: f } = V(), i = ee(), u = U(), g = j(), y = ((v = (h = f.value) == null ? void 0 : h.partner) == null ? void 0 : v.messageType) === M.transactional, A = async (e) => {
29
+ const t = await d(
24
30
  "/newsletter/template-library/check-template-html-body",
25
- { html: z(e) }
31
+ { html: Z(e) }
26
32
  ), { status: n, message: l } = t.data;
27
- return n || a({
33
+ return n || o({
28
34
  type: c.Alert,
29
- message: n === void 0 ? l : r("newsletter.invalid-url-link-for-toaster")
30
- }), r(M), l === r($) && a({
35
+ message: n === void 0 ? l : i("newsletter.invalid-url-link-for-toaster")
36
+ }), i(P), l === i(X) && o({
31
37
  type: c.Alert,
32
- message: r("newsletter.already-in-progress")
38
+ message: i("newsletter.already-in-progress")
33
39
  }), n;
34
- }, w = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), E = (e) => ["if", "endif"].includes(e.toLowerCase()), A = (e, s) => {
40
+ }, S = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), b = (e) => ["if", "endif"].includes(e.toLowerCase()), I = (e, s) => {
35
41
  const t = e.match(/({%(.*?)%})/g);
36
42
  let n = !0;
37
- return t !== null && !p && t.forEach((l) => {
38
- const o = l.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
39
- if (o && o.length > 0) {
40
- const [i] = o;
41
- w(i) && !s.includes(i) && (a({
43
+ return t !== null && !y && t.forEach((l) => {
44
+ const a = l.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
45
+ if (a && a.length > 0) {
46
+ const [r] = a;
47
+ S(r) && !s.includes(r) && (o({
42
48
  type: c.Warning,
43
- message: r("custom-fields.invalid-custom-fields")
49
+ message: i("custom-fields.invalid-custom-fields")
44
50
  }), n = !1);
45
51
  }
46
52
  }), n;
47
- }, k = async (e, s, t) => {
48
- const n = t ? await b(e) : !0;
49
- return A(e, s) && n;
50
- }, x = (e) => e.length > 0 ? !0 : (a({
53
+ }, w = async (e, s, t) => {
54
+ const n = t ? await A(e) : !0;
55
+ return I(e, s) && n;
56
+ }, x = (e) => e.length > 0 ? !0 : (o({
51
57
  type: c.Warning,
52
- message: r("newsletter.html-content-is-empty")
53
- }), !1), I = (e) => {
58
+ message: i("newsletter.html-content-is-empty")
59
+ }), !1), T = (e) => {
54
60
  const s = (e.match(/{/gm) || []).length, t = (e.match(/}/gm) || []).length;
55
- return s > t && a({
61
+ return s > t && o({
56
62
  type: c.Warning,
57
- message: r("custom-fields.missing-closing-braces")
58
- }), s < t && a({
63
+ message: i("custom-fields.missing-closing-braces")
64
+ }), s < t && o({
59
65
  type: c.Warning,
60
- message: r("custom-fields.missing-opening-braces")
66
+ message: i("custom-fields.missing-opening-braces")
61
67
  }), s === t;
62
- }, F = (e) => {
63
- const s = e.match(/{{\s*(\w+\s+((\w+\|\w+)|(\w+)))\s*}}/gm) === null;
64
- return s || a({
68
+ }, k = (e) => {
69
+ const s = ie(e).length === 0;
70
+ return s || o({
65
71
  type: c.Warning,
66
- message: r("custom-fields.invalid-custom-fields")
72
+ message: i("custom-fields.invalid-custom-fields")
67
73
  }), s;
68
- }, T = (e, s) => {
74
+ }, _ = (e, s) => {
69
75
  const t = e.match(/{{([a-zA-Z0-9_\s]*)}}/gm);
70
- if (t && !p) {
71
- const n = new Set(s.map((i) => i.toLowerCase())), l = Q(e), o = [];
72
- if (t.forEach((i) => {
73
- const m = i.slice(2, -2).trim().toLowerCase();
74
- (!n.has(m) || m === "") && !ee(m, l) && o.push(m);
75
- }), o.length > 0) {
76
- const i = `
76
+ if (t && !y) {
77
+ const n = new Set(s.map((r) => r.toLowerCase())), l = se(e), a = [];
78
+ if (t.forEach((r) => {
79
+ const m = r.slice(2, -2).trim().toLowerCase();
80
+ (!n.has(m) || m === "") && !ne(m, l) && a.push(m);
81
+ }), a.length > 0) {
82
+ const r = `
77
83
  <ul>
78
- ${o.map((m) => `<li>${m}</li>`).join("")}
84
+ ${a.map((m) => `<li>${m}</li>`).join("")}
79
85
  </ul>
80
86
  `;
81
- return a({
87
+ return o({
82
88
  type: c.Alert,
83
- message: r("custom-fields.invalid-custom-fields") + i
89
+ message: i("custom-fields.invalid-custom-fields") + r
84
90
  }), !1;
85
91
  }
86
92
  }
87
93
  return !0;
88
- }, R = (e) => {
94
+ }, N = (e) => {
89
95
  const s = e.match(/{%(.*?)%}/g), t = [];
90
96
  let n = !0;
91
97
  if (s && s.forEach((l) => {
92
- const o = l.match(P), i = l.match(G), m = (o == null ? void 0 : o.join("")) || "";
93
- (!o || l !== m) && !i && (a({
98
+ const a = l.match(G), r = l.match(H), m = (a == null ? void 0 : a.join("")) || "";
99
+ (!a || l !== m) && !r && (o({
94
100
  type: c.Alert,
95
- message: r("newsletter.display-conditions-invalid-syntax")
96
- }), n = !1), o && o.forEach((f) => {
97
- f.trim() === "=" && (a({
101
+ message: i("newsletter.display-conditions-invalid-syntax")
102
+ }), n = !1), a && a.forEach((p) => {
103
+ p.trim() === "=" && (o({
98
104
  type: c.Alert,
99
- message: r("custom-conditions.wrong-equality-operators")
105
+ message: i("custom-conditions.wrong-equality-operators")
100
106
  }), n = !1);
101
- const v = f.match(/^[a-zA-Z]*$/g);
102
- v && v.forEach((C) => {
103
- E(C) && t.push(C);
107
+ const C = p.match(/^[a-zA-Z]*$/g);
108
+ C && C.forEach((E) => {
109
+ b(E) && t.push(E);
104
110
  });
105
111
  });
106
112
  }), t.length) {
107
- const l = t.filter((i) => i === "if"), o = t.filter((i) => i === "endif");
108
- l.length !== o.length && (a({
113
+ const l = t.filter((r) => r === "if"), a = t.filter((r) => r === "endif");
114
+ l.length !== a.length && (o({
109
115
  type: c.Alert,
110
- message: r("custom-conditions.missing-if-endif-tag")
116
+ message: i("custom-conditions.missing-if-endif-tag")
111
117
  }), n = !1);
112
118
  }
113
119
  return n;
114
- }, B = (e) => {
120
+ }, R = (e) => {
115
121
  const s = (e.match(/{% /gm) || []).length, t = (e.match(/ %}/gm) || []).length, n = s === t;
116
- return n || a({
122
+ return n || o({
117
123
  type: c.Warning,
118
- message: r("custom-conditions.no-space-after-braces")
124
+ message: i("custom-conditions.no-space-after-braces")
119
125
  }), n;
120
- }, W = (e) => (e.match(/({%(.*?)%})/g) || []).filter((t) => t.includes("if")).map((t) => (t.match(/{{.*}}/gm) || []).length).reduce((t, n) => t + n, 0) > 0 ? (a({
126
+ }, D = (e) => (e.match(/({%(.*?)%})/g) || []).filter((t) => t.includes("if")).map((t) => (t.match(/{{.*}}/gm) || []).length).reduce((t, n) => t + n, 0) > 0 ? (o({
121
127
  type: c.Warning,
122
- message: r("custom-conditions.no-braces-inside-if-tag")
123
- }), !1) : !0, N = () => S.hasInvalidBlock() ? (a({
128
+ message: i("custom-conditions.no-braces-inside-if-tag")
129
+ }), !1) : !0, F = () => g.hasInvalidBlock() ? (o({
124
130
  type: c.Alert,
125
- message: r(j)
126
- }), !1) : !0, O = () => g.recommendationConfigs && Object.values(g.recommendationConfigs).find((s) => s.filters.find((t) => t.value === "")) !== void 0 ? (a({
131
+ message: i(z)
132
+ }), !1) : !0, O = () => u.recommendationConfigs && Object.values(u.recommendationConfigs).find((s) => s.filters.find((t) => t.value === "")) !== void 0 ? (o({
127
133
  type: c.Alert,
128
- message: r("newsletter.fill-all-necessary-fields")
129
- }), !1) : !0, D = (e) => {
134
+ message: i("newsletter.fill-all-necessary-fields")
135
+ }), !1) : !0, B = (e) => {
130
136
  const s = /src="[^"]*\.(svg|pst)"/gm;
131
- return e.match(s) === null ? !0 : (a({
137
+ return e.match(s) === null ? !0 : (o({
132
138
  type: c.Alert,
133
- message: r("newsletter.invalid-image-type")
139
+ message: i("newsletter.invalid-image-type")
134
140
  }), !1);
135
141
  }, L = (e) => {
136
142
  const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
137
- return Array.from(n).find((o) => {
138
- var i;
139
- return !((i = o.id) != null && i.trim());
140
- }) ? (a({
143
+ return Array.from(n).find((a) => {
144
+ var r;
145
+ return !((r = a.id) != null && r.trim());
146
+ }) ? (o({
141
147
  type: c.Alert,
142
- message: r("unsubscribe-templates.select-checkbox-groups")
148
+ message: i("unsubscribe-templates.select-checkbox-groups")
143
149
  }), !1) : !0;
144
- }, V = (e) => {
150
+ }, W = (e) => {
145
151
  const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
146
- return Array.from(n).find((o) => {
147
- var i;
148
- return !((i = o.id) != null && i.trim());
149
- }) ? (a({
152
+ return Array.from(n).find((a) => {
153
+ var r;
154
+ return !((r = a.id) != null && r.trim());
155
+ }) ? (o({
150
156
  type: c.Alert,
151
- message: r("unsubscribe-templates.select-radio-button-groups")
157
+ message: i("unsubscribe-templates.select-radio-button-groups")
152
158
  }), !1) : !0;
153
159
  };
154
160
  return { validateHtml: async (e, s, t = !1) => {
155
- var o, i;
161
+ var a, r;
156
162
  const n = [
157
163
  ...s.map((m) => m.value),
158
- ...q,
159
- ...((i = (o = d.value) == null ? void 0 : o.template) == null ? void 0 : i.customFieldAttributes) ?? []
164
+ ...K,
165
+ ...((r = (a = f.value) == null ? void 0 : a.template) == null ? void 0 : r.customFieldAttributes) ?? []
160
166
  ];
161
- return await k(e, n, t) && x(e) && I(e) && F(e) && T(e, n) && R(e) && B(e) && W(e) && N() && O() && D(e) && L(e) && V(e);
167
+ return await w(e, n, t) && x(e) && T(e) && k(e) && _(e, n) && N(e) && R(e) && D(e) && F() && O() && B(e) && L(e) && W(e);
162
168
  } };
163
169
  };
164
170
  export {
165
- ge as useHtmlValidator
171
+ ve as useHtmlValidator
166
172
  };
@@ -1,7 +1,15 @@
1
- const e = "newsletter.already-in-progress", n = "newsletter.campaign-could-not-be-saved", o = / (==|<=|>=|!=|>|<|in) | (if|elif|endif|else|and|or) |("[\S ]+")|('[\S ]+')|([^”\s\n]+)|(({%)|( %}))/gm, a = /{%( )*now( )(".*")( )*%}/gm;
1
+ const n = "newsletter.already-in-progress", e = "newsletter.campaign-could-not-be-saved", s = / (==|<=|>=|!=|>|<|in) | (if|elif|endif|else|and|or) |("[\S ]+")|('[\S ]+')|([^”\s\n]+)|(({%)|( %}))/gm, o = /{%( )*now( )(".*")( )*%}/gm, i = /\{\{[^{}]+\}\}/g, E = /^[A-Za-z0-9_.]+$/, _ = [
2
+ "ins-unsubscribe-link",
3
+ "ins-global-unsubscribe-link",
4
+ "ins-preferences-unsubscribe-link",
5
+ "@COUPON_CODE"
6
+ ];
2
7
  export {
3
- n as CampaignCouldNotBeSavedKey,
4
- e as CanNotMakeAnyChangesForRunningKey,
5
- a as DISPLAY_CONDITIONS_EXCEPTIONS_REGEX,
6
- o as DISPLAY_CONDITIONS_REGEX
8
+ _ as ALLOWED_DYNAMIC_SYSTEM_TOKENS,
9
+ e as CampaignCouldNotBeSavedKey,
10
+ n as CanNotMakeAnyChangesForRunningKey,
11
+ o as DISPLAY_CONDITIONS_EXCEPTIONS_REGEX,
12
+ s as DISPLAY_CONDITIONS_REGEX,
13
+ i as DYNAMIC_CONTENT_TAG_REGEX,
14
+ E as VALID_DYNAMIC_VARIABLE_REGEX
7
15
  };
@@ -1,4 +1,4 @@
1
- var c = /* @__PURE__ */ ((r) => (r.Success = "success", r.Warning = "warning", r.Alert = "alert", r.Dark = "dark", r))(c || {});
1
+ var c = /* @__PURE__ */ ((r) => (r.Success = "success", r.Warning = "warning", r.Alert = "alert", r))(c || {});
2
2
  export {
3
3
  c as ToasterTypeOptions
4
4
  };
@@ -1,18 +1,17 @@
1
1
  var k = Object.defineProperty;
2
- var B = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
- var d = (a, r, t) => B(a, typeof r != "symbol" ? r + "" : r, t);
4
- import { BlockId as R } from "../../../enums/block.js";
5
- import { getMigrationBannerHtml as y } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as D, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ var y = (a, r, t) => r in a ? k(a, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[r] = t;
3
+ var d = (a, r, t) => y(a, typeof r != "symbol" ? r + "" : r, t);
4
+ import { BlockId as B } from "../../../enums/block.js";
5
+ import { getMigrationBannerHtml as D } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as R, BlockCompositionType as C, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
7
  import { regenerateMobileProductRows as b } from "./controls/main/utils.js";
8
8
  import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as A } from "./controls/mobileLayout/cssRules.js";
9
9
  import { RecommendationConfigService as c } from "./services/configService.js";
10
10
  import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
11
  import { getDefaultTemplate as E } from "./templates/grid/template.js";
12
- import { useRecommendationBlockWarning as M } from "./useRecommendationBlockWarning.js";
13
- const I = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
14
- let _ = !1;
15
- class H extends D {
12
+ const _ = B.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
13
+ let I = !1;
14
+ class q extends R {
16
15
  constructor() {
17
16
  super();
18
17
  /**
@@ -22,7 +21,7 @@ class H extends D {
22
21
  d(this, "_pendingBlockId", null);
23
22
  }
24
23
  getId() {
25
- return I;
24
+ return _;
26
25
  }
27
26
  getIcon() {
28
27
  return "recommendation-icon";
@@ -39,8 +38,8 @@ class H extends D {
39
38
  );
40
39
  }
41
40
  getSettingsPanelTitleHtml() {
42
- return y(
43
- I,
41
+ return D(
42
+ _,
44
43
  this.api.translate("Recommendation Block"),
45
44
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
46
45
  );
@@ -96,7 +95,7 @@ class H extends D {
96
95
  documentModifier: this.api.getDocumentModifier()
97
96
  }));
98
97
  }
99
- s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
98
+ s.patchCurrentBlockConfig({ language: n.language }, { triggerRefetch: !1 });
100
99
  }
101
100
  /**
102
101
  * Called when the document changes or template is loaded
@@ -118,7 +117,7 @@ class H extends D {
118
117
  }
119
118
  this._healLingeringDuplicate(t), c.needsMigration(t) && this._migrateFromLegacy(t);
120
119
  try {
121
- _ || (p(this.api), _ = !0);
120
+ I || (p(this.api), I = !0);
122
121
  const e = c.getConfig(t), i = this._getBlockElement(t);
123
122
  if (i) {
124
123
  const n = !e.mobileLayoutEnabled;
@@ -138,24 +137,6 @@ class H extends D {
138
137
  const e = this._getRecommendationId(t);
139
138
  e && g().removeBlockState(e);
140
139
  }
141
- /**
142
- * Warns (dark advisory toaster) when the design holds more than one live
143
- * recommendation block. Triggered from the user-add paths only (fresh drop
144
- * and duplicate) — never from document-load/migration, so opening a template
145
- * that already has multiple blocks does not fire it. `onCreated` also runs
146
- * for a reco block that arrives inside a saved structure (SD-143028), so this
147
- * covers that case too — no separate `module_dropped` handling is needed.
148
- *
149
- * Counting lives in `useRecommendationBlockWarning`, whose DOM-based logic
150
- * ignores the empty shells deletions leave behind (SD-143028). Wrapped in
151
- * try/catch because the document root may be unavailable during initial load.
152
- */
153
- _warnIfMultipleBlocks() {
154
- try {
155
- M().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
156
- } catch {
157
- }
158
- }
159
140
  /**
160
141
  * Generates the next unique recommendation ID by scanning all existing blocks
161
142
  * in the document and finding the maximum existing ID + 1.
@@ -228,7 +209,7 @@ class H extends D {
228
209
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
229
210
  _handleDuplicate(t, e) {
230
211
  const i = this._reassignDuplicateId(t, e), n = g();
231
- n.cloneBlockState(e, i), n.setCurrentBlock(i), this._warnIfMultipleBlocks();
212
+ n.cloneBlockState(e, i), n.setCurrentBlock(i);
232
213
  }
233
214
  /**
234
215
  * Core id-reassignment for a duplicated block: rewrites the DOM
@@ -310,6 +291,6 @@ class H extends D {
310
291
  }
311
292
  }
312
293
  export {
313
- I as BLOCK_ID,
314
- H as RecommendationBlock
294
+ _ as BLOCK_ID,
295
+ q as RecommendationBlock
315
296
  };
@@ -1,4 +1,4 @@
1
- const o = [
1
+ const u = [
2
2
  {
3
3
  key: "locale",
4
4
  getValue: (e) => e.language,
@@ -9,8 +9,8 @@ const o = [
9
9
  getValue: (e) => e.currencySettings.value,
10
10
  getAvailableOptions: (e) => e.currencyList.map((n) => n.text)
11
11
  }
12
- ], l = "newsletter.recommendation-fill-required-fields";
13
- function u(e, n) {
12
+ ], s = "newsletter.recommendation-fill-required-fields";
13
+ function l(e, n, o = u) {
14
14
  return o.filter((t) => {
15
15
  var a;
16
16
  if (t.condition && !t.condition(e))
@@ -22,12 +22,12 @@ function u(e, n) {
22
22
  return r !== void 0 && !r.includes(i);
23
23
  }).map((t) => t.key);
24
24
  }
25
- function s(e, n) {
26
- return u(e, n).length === 0;
25
+ function c(e, n) {
26
+ return l(e, n).length === 0;
27
27
  }
28
28
  export {
29
- o as REQUIRED_RECOMMENDATION_FIELDS,
30
- l as RecommendationRequiredFieldsKey,
31
- u as getInvalidFields,
32
- s as isConfigValid
29
+ u as REQUIRED_RECOMMENDATION_FIELDS,
30
+ s as RecommendationRequiredFieldsKey,
31
+ l as getInvalidFields,
32
+ c as isConfigValid
33
33
  };
@@ -4,3 +4,6 @@ export declare const CampaignCouldNotBeSavedKey = "newsletter.campaign-could-not
4
4
  export declare const DISPLAY_CONDITIONS_REGEX: RegExp;
5
5
  export declare const DISPLAY_CONDITIONS_EXCEPTIONS_REGEX: RegExp;
6
6
  export declare const REMOVE_CONDITIONS_REGEX: RegExp;
7
+ export declare const DYNAMIC_CONTENT_TAG_REGEX: RegExp;
8
+ export declare const VALID_DYNAMIC_VARIABLE_REGEX: RegExp;
9
+ export declare const ALLOWED_DYNAMIC_SYSTEM_TOKENS: string[];
@@ -1,6 +1,5 @@
1
1
  export declare enum ToasterTypeOptions {
2
2
  Success = "success",
3
3
  Warning = "warning",
4
- Alert = "alert",
5
- Dark = "dark"
4
+ Alert = "alert"
6
5
  }
@@ -55,19 +55,6 @@ export declare class RecommendationBlock extends Block {
55
55
  * @param node - The block node being deleted
56
56
  */
57
57
  onDelete(node: ImmutableHtmlNode): void;
58
- /**
59
- * Warns (dark advisory toaster) when the design holds more than one live
60
- * recommendation block. Triggered from the user-add paths only (fresh drop
61
- * and duplicate) — never from document-load/migration, so opening a template
62
- * that already has multiple blocks does not fire it. `onCreated` also runs
63
- * for a reco block that arrives inside a saved structure (SD-143028), so this
64
- * covers that case too — no separate `module_dropped` handling is needed.
65
- *
66
- * Counting lives in `useRecommendationBlockWarning`, whose DOM-based logic
67
- * ignores the empty shells deletions leave behind (SD-143028). Wrapped in
68
- * try/catch because the document root may be unavailable during initial load.
69
- */
70
- private _warnIfMultipleBlocks;
71
58
  /**
72
59
  * Generates the next unique recommendation ID by scanning all existing blocks
73
60
  * in the document and finding the maximum existing ID + 1.
@@ -8,7 +8,7 @@ export interface ExtensionStoreSlice {
8
8
  languages: Languages;
9
9
  currencyList: Currency[];
10
10
  }
11
- interface RequiredField {
11
+ export interface RequiredField {
12
12
  key: string;
13
13
  getValue: (config: PerBlockConfigs) => string;
14
14
  getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
@@ -16,6 +16,5 @@ interface RequiredField {
16
16
  }
17
17
  export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
18
18
  export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
19
- export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice): string[];
19
+ export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
20
20
  export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;
21
- export {};
@@ -16,7 +16,7 @@ const s = a("guidoDynamicContent", {
16
16
  value: e.value,
17
17
  fallback: e.fallback,
18
18
  format: e.format
19
- })) || []
19
+ }))
20
20
  }
21
21
  });
22
22
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.7.0-beta.509616e",
3
+ "version": "3.7.0-beta.61e8940",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -1,16 +0,0 @@
1
- import { useToaster as r } from "../../../composables/useToaster.js";
2
- import { useTranslations as s } from "../../../composables/useTranslations.js";
3
- import { ToasterTypeOptions as n } from "../../../enums/toaster.js";
4
- import { countLiveRecommendationBlocks as i } from "./utils/recommendationBlockCount.js";
5
- const a = "newsletter.multiple-reco-blocks-warning", f = () => {
6
- const { showToaster: o } = r(), t = s();
7
- return { warnIfMultipleBlocks: (e) => {
8
- i(e) > 1 && o({
9
- type: n.Dark,
10
- message: t(a)
11
- });
12
- } };
13
- };
14
- export {
15
- f as useRecommendationBlockWarning
16
- };
@@ -1,9 +0,0 @@
1
- const r = ".recommendation-block-v2", t = ".recommendation-product-row";
2
- function n(o) {
3
- return Array.from(o.querySelectorAll(r)).filter((e) => e.querySelector(t)).length;
4
- }
5
- export {
6
- r as RECOMMENDATION_BLOCK_SELECTOR,
7
- t as RECOMMENDATION_PRODUCT_ROW_SELECTOR,
8
- n as countLiveRecommendationBlocks
9
- };
@@ -1,63 +0,0 @@
1
- interface User {
2
- id: number;
3
- name: string;
4
- email: string;
5
- }
6
- export declare const useApiExample: () => {
7
- loading: import("vue").ComputedRef<boolean>;
8
- error: import("vue").ComputedRef<{
9
- message: string;
10
- status?: number | undefined;
11
- statusText?: string | undefined;
12
- response?: {
13
- readonly headers: {
14
- append: (name: string, value: string) => void;
15
- delete: (name: string) => void;
16
- get: (name: string) => string | null;
17
- getSetCookie: () => string[];
18
- has: (name: string) => boolean;
19
- set: (name: string, value: string) => void;
20
- forEach: (callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any) => void;
21
- entries: () => IterableIterator<[string, string]>;
22
- keys: () => IterableIterator<string>;
23
- values: () => IterableIterator<string>;
24
- [Symbol.iterator]: () => IterableIterator<[string, string]>;
25
- };
26
- readonly ok: boolean;
27
- readonly redirected: boolean;
28
- readonly status: number;
29
- readonly statusText: string;
30
- readonly type: ResponseType;
31
- readonly url: string;
32
- clone: () => Response;
33
- readonly body: {
34
- readonly locked: boolean;
35
- cancel: (reason?: any) => Promise<void>;
36
- getReader: {
37
- (options: {
38
- mode: "byob";
39
- }): ReadableStreamBYOBReader;
40
- (): ReadableStreamDefaultReader<Uint8Array>;
41
- (options?: ReadableStreamGetReaderOptions): ReadableStreamReader<Uint8Array>;
42
- };
43
- pipeThrough: <T>(transform: ReadableWritablePair<T, Uint8Array>, options?: StreamPipeOptions) => ReadableStream<T>;
44
- pipeTo: (destination: WritableStream<Uint8Array>, options?: StreamPipeOptions) => Promise<void>;
45
- tee: () => [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>];
46
- } | null;
47
- readonly bodyUsed: boolean;
48
- arrayBuffer: () => Promise<ArrayBuffer>;
49
- blob: () => Promise<Blob>;
50
- formData: () => Promise<FormData>;
51
- json: () => Promise<any>;
52
- text: () => Promise<string>;
53
- } | undefined;
54
- } | null>;
55
- hasError: import("vue").ComputedRef<boolean>;
56
- fetchUsers: () => Promise<User[]>;
57
- createUser: (userData: Omit<User, "id">) => Promise<User>;
58
- updateUser: (id: number, userData: Partial<User>) => Promise<User>;
59
- deleteUser: (id: number) => Promise<void>;
60
- uploadFile: (file: File) => Promise<string>;
61
- clearError: () => void;
62
- };
63
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
1
- import type { QueryableRoot } from './utils/recommendationBlockCount';
2
- /**
3
- * Advisory shown when a design ends up with more than one recommendation block,
4
- * since multiple blocks can slow campaign delivery. Driven from the block
5
- * lifecycle (`onCreated` for direct drop / duplicate, counting the editor's
6
- * document root). `onCreated` also fires for a reco block that arrives inside a
7
- * saved structure (SD-143028), so that case is covered without a separate
8
- * `module_dropped` re-check.
9
- */
10
- export declare const useRecommendationBlockWarning: () => {
11
- warnIfMultipleBlocks: (root: QueryableRoot) => void;
12
- };
@@ -1,28 +0,0 @@
1
- /**
2
- * Counts *live* recommendation blocks in a document.
3
- *
4
- * Deleting a recommendation block strips its inner content but leaves an empty
5
- * `.recommendation-block-v2` container shell behind — present in every document
6
- * representation the editor exposes (`getDocumentRoot`, `getDocumentRootHtmlNode`
7
- * and even `getTemplateData`). A raw class count therefore over-reports after a
8
- * delete→add cycle (SD-143028). The product row (`.recommendation-product-row`)
9
- * is present on every live block from drop time (the default template ships
10
- * product rows, both grid and list layouts) and is removed from a deleted
11
- * block's leftover shell, so filtering by it cleanly separates live blocks from
12
- * ghosts without reading any store.
13
- */
14
- export declare const RECOMMENDATION_BLOCK_SELECTOR = ".recommendation-block-v2";
15
- export declare const RECOMMENDATION_PRODUCT_ROW_SELECTOR = ".recommendation-product-row";
16
- interface QueryableNode {
17
- querySelector(selector: string): unknown;
18
- }
19
- export interface QueryableRoot {
20
- querySelectorAll(selector: string): Iterable<QueryableNode>;
21
- }
22
- /**
23
- * Counts the live recommendation blocks reachable from `root`. Works on the
24
- * editor's `ImmutableHtmlNode` document root (the `onCreated` drop / duplicate
25
- * paths) and on any DOM-like root exposing `querySelectorAll`.
26
- */
27
- export declare function countLiveRecommendationBlocks(root: QueryableRoot): number;
28
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
File without changes