@useinsider/guido 3.6.0-beta.6c3407e → 3.6.0-beta.70bbf9f

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 (40) hide show
  1. package/dist/composables/useHtmlValidator.js +165 -118
  2. package/dist/config/compiler/utils/recommendationCompilerUtils.js +28 -27
  3. package/dist/config/compiler/utils/recommendationIgnoreUtils.js +15 -0
  4. package/dist/config/migrator/recommendation/extractors.js +44 -22
  5. package/dist/config/migrator/recommendation/htmlBuilder.js +175 -169
  6. package/dist/config/migrator/recommendationMigrator.js +30 -31
  7. package/dist/enums/toaster.js +1 -1
  8. package/dist/extensions/Blocks/Recommendation/block.js +16 -35
  9. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +21 -15
  10. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +38 -24
  11. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +39 -38
  12. package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +45 -34
  13. package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
  14. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +62 -52
  15. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -67
  16. package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
  17. package/dist/extensions/Blocks/Recommendation/extension.js +6 -5
  18. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +3 -2
  19. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +3 -2
  20. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -2
  21. package/dist/extensions/Blocks/Recommendation/templates/index.js +5 -4
  22. package/dist/src/composables/useHtmlValidator.d.ts +27 -0
  23. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
  24. package/dist/src/config/migrator/recommendation/extractors.d.ts +15 -0
  25. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +8 -0
  26. package/dist/src/enums/toaster.d.ts +1 -2
  27. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -13
  28. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  29. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +21 -0
  30. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +7 -0
  31. package/dist/src/extensions/Blocks/Recommendation/controls/main/layoutOrientation.d.ts +5 -0
  32. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +6 -0
  33. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -0
  34. package/package.json +1 -1
  35. package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +0 -16
  36. package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +0 -9
  37. package/dist/src/extensions/Blocks/Recommendation/useRecommendationBlockWarning.d.ts +0 -12
  38. package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +0 -28
  39. /package/dist/src/{extensions/Blocks/Recommendation/block.test.d.ts → composables/useHtmlValidator.test.d.ts} +0 -0
  40. /package/dist/src/{extensions/Blocks/Recommendation/utils/recommendationBlockCount.test.d.ts → config/compiler/utils/recommendationIgnoreUtils.test.d.ts} +0 -0
@@ -1,36 +1,40 @@
1
1
  import { ModificationDescription as p } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { RecommendationBlockId as m } from "../../constants/blockIds.js";
3
- import { CURRENCY_ATTR as y, MOBILE_CONTAINER_SELECTOR as q, MOBILE_ROW_SELECTOR as k, DESKTOP_CONTAINER_SELECTOR as P, CONTAINER_SELECTOR as v, ATTR_PRODUCT_ATTR as W } from "../../constants/selectors.js";
3
+ import { CURRENCY_ATTR as y, CSS_CLASS_SKIP_COMPILE as v, MOBILE_CONTAINER_SELECTOR as q, MOBILE_ROW_SELECTOR as w, DESKTOP_CONTAINER_SELECTOR as h, CONTAINER_SELECTOR as W, ATTR_PRODUCT_ATTR as j } from "../../constants/selectors.js";
4
4
  import { RecommendationConfigService as E } from "../../services/configService.js";
5
5
  import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
6
- import { prepareProductRows as _ } from "../../templates/index.js";
7
- import { formatPrice as j } from "../../utils/priceFormatter.js";
8
- import { isTdNode as F } from "../../utils/tagName.js";
9
- import { getDefaultProducts as L, DEFAULT_CARD_COMPOSITION as R, sanitizeImageUrl as V } from "../../templates/utils.js";
10
- const M = "recommendation-block-v2";
11
- function h(t) {
6
+ import { prepareProductRows as N } from "../../templates/index.js";
7
+ import { formatPrice as F } from "../../utils/priceFormatter.js";
8
+ import { isTdNode as V } from "../../utils/tagName.js";
9
+ import { getDefaultProducts as L, DEFAULT_CARD_COMPOSITION as M, sanitizeImageUrl as G } from "../../templates/utils.js";
10
+ const R = "recommendation-block-v2";
11
+ function A(t) {
12
12
  if (!t)
13
13
  return null;
14
14
  if ("getAttribute" in t) {
15
15
  const e = t.getAttribute("class");
16
- if (e && e.includes(M))
16
+ if (e && e.includes(R))
17
17
  return t;
18
18
  }
19
- return "querySelector" in t ? t.querySelector(`.${M}`) ?? null : null;
19
+ return "querySelector" in t ? t.querySelector(`.${R}`) ?? null : null;
20
+ }
21
+ function K(t) {
22
+ const e = A(t);
23
+ return !e || !("getAttribute" in e) ? !1 : (e.getAttribute("class") ?? "").split(/\s+/).includes(v);
20
24
  }
21
25
  function b(t) {
22
- const e = h(t);
26
+ const e = A(t);
23
27
  if (!e || !("getAttribute" in e))
24
28
  return "grid";
25
29
  const o = e.getAttribute("data-layout");
26
30
  return o === "list" || o === "horizontal" ? "list" : "grid";
27
31
  }
28
32
  function x(t) {
29
- const e = h(t);
33
+ const e = A(t);
30
34
  if (!e || !("getAttribute" in e))
31
- return R;
35
+ return M;
32
36
  const o = e.getAttribute("data-card-composition");
33
- return o ? o.split(",").filter(Boolean) : R;
37
+ return o ? o.split(",").filter(Boolean) : M;
34
38
  }
35
39
  function D(t) {
36
40
  if (!t || !("childNodes" in t))
@@ -47,14 +51,14 @@ function S(t, e, o) {
47
51
  function U(t, e) {
48
52
  return t && t.length > 0 ? t : e.length > 0 ? e : L();
49
53
  }
50
- function G(t) {
54
+ function Y(t) {
51
55
  const { currentNode: e, documentModifier: o } = t;
52
56
  if (!e || !("querySelector" in e))
53
57
  return;
54
- const n = e.querySelector(k);
58
+ const n = e.querySelector(w);
55
59
  n && (o.modifyHtml(n).setInnerHtml(""), o.apply(new p("Cleared mobile row content")));
56
60
  }
57
- function Y(t) {
61
+ function X(t) {
58
62
  const {
59
63
  currentNode: e,
60
64
  documentModifier: o,
@@ -66,20 +70,20 @@ function Y(t) {
66
70
  return;
67
71
  const r = i ?? b(e), s = E.getConfig(e);
68
72
  if (r === "list" || !s.mobileLayoutEnabled) {
69
- G({ currentNode: e, documentModifier: o });
73
+ Y({ currentNode: e, documentModifier: o });
70
74
  return;
71
75
  }
72
- const u = e.querySelector(k);
76
+ const u = e.querySelector(w);
73
77
  if (!u)
74
78
  return;
75
- const l = C(), d = U(n, l.recommendationProducts), a = c ?? x(e), g = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${_(d, r, {
79
+ const l = C(), d = U(n, l.recommendationProducts), a = c ?? x(e), g = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${N(d, r, {
76
80
  productsPerRow: s.mobileCardsInRow,
77
81
  composition: a,
78
82
  filterList: l.filterList
79
83
  })}</table></td>`;
80
84
  o.modifyHtml(u).setInnerHtml(g), o.apply(new p("Updated mobile product rows"));
81
85
  }
82
- function K(t) {
86
+ function z(t) {
83
87
  const {
84
88
  currentNode: e,
85
89
  documentModifier: o,
@@ -90,15 +94,15 @@ function K(t) {
90
94
  } = t;
91
95
  if (!e || !("querySelector" in e))
92
96
  return;
93
- const s = e.querySelector(P) ?? e.querySelector(v);
97
+ const s = e.querySelector(h) ?? e.querySelector(W);
94
98
  if (!s)
95
99
  return;
96
- const u = C(), l = U(i, u.recommendationProducts), { cardsInRow: d } = u.recommendationConfigs, a = r ?? x(e), f = c ?? b(e), g = _(l, f, {
100
+ const u = C(), l = U(i, u.recommendationProducts), { cardsInRow: d } = u.recommendationConfigs, a = r ?? x(e), f = c ?? b(e), g = N(l, f, {
97
101
  productsPerRow: d,
98
102
  composition: a,
99
103
  filterList: u.filterList
100
104
  });
101
- o.modifyHtml(s).setInnerHtml(g).apply(new p("Updated product")), Y(t), n == null || n();
105
+ o.modifyHtml(s).setInnerHtml(g).apply(new p("Updated product")), X(t), n == null || n();
102
106
  }
103
107
  function T(t, e, o, n) {
104
108
  const c = `0 ${Math.floor(o / 2)}px`;
@@ -111,7 +115,7 @@ function T(t, e, o, n) {
111
115
  t.querySelectorAll(".product-card-wrapper")
112
116
  ).forEach((u) => {
113
117
  const l = "parentNode" in u ? u.parentNode : null;
114
- l && F(l) && (e.modifyHtml(l).setStyle("padding", c), r = !0);
118
+ l && V(l) && (e.modifyHtml(l).setStyle("padding", c), r = !0);
115
119
  }), r;
116
120
  }
117
121
  function I(t, e, o) {
@@ -121,13 +125,13 @@ function I(t, e, o) {
121
125
  e.modifyHtml(r).setStyle("height", n), c = !0;
122
126
  }), c;
123
127
  }
124
- function X(t) {
128
+ function J(t) {
125
129
  const { currentNode: e, documentModifier: o } = t;
126
130
  if (!e)
127
131
  return;
128
132
  const n = E.getConfig(e), i = b(e);
129
133
  let c = !1;
130
- const r = e.querySelector(P);
134
+ const r = e.querySelector(h);
131
135
  if (r) {
132
136
  c = T(
133
137
  r,
@@ -160,9 +164,9 @@ function X(t) {
160
164
  }
161
165
  c && o.apply(new p("Reapply spacing after regeneration"));
162
166
  }
163
- function se(t) {
167
+ function de(t) {
164
168
  const { currentNode: e, documentModifier: o, afterRegenerate: n, products: i, layout: c, composition: r } = t;
165
- e && K({
169
+ e && z({
166
170
  currentNode: e,
167
171
  documentModifier: o,
168
172
  products: i,
@@ -170,12 +174,12 @@ function se(t) {
170
174
  composition: r,
171
175
  afterRegenerate: () => {
172
176
  setTimeout(() => {
173
- X({ currentNode: e, documentModifier: o });
177
+ J({ currentNode: e, documentModifier: o });
174
178
  }, 0), n == null || n();
175
179
  }
176
180
  });
177
181
  }
178
- function ae(t, e) {
182
+ function fe(t, e) {
179
183
  return t.length === e ? t : t.length > e ? t.slice(0, e) : [...t, ...L(e - t.length)];
180
184
  }
181
185
  function H() {
@@ -189,14 +193,14 @@ function H() {
189
193
  thousandSeparator: e.thousandSeparator
190
194
  };
191
195
  }
192
- function A(t, e = "price") {
196
+ function P(t, e = "price") {
193
197
  const o = H(), n = t[e], i = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
194
- return j({
198
+ return F({
195
199
  price: i,
196
200
  currency: o
197
201
  });
198
202
  }
199
- function z(t) {
203
+ function Q(t) {
200
204
  var c, r;
201
205
  const e = H(), o = ((c = t.original_price) == null ? void 0 : c[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((r = t.price) == null ? void 0 : r[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, i = o > 0 ? Math.round((o - n) / o * 100) : 0;
202
206
  return i > 0 ? `-${i}%` : "0%";
@@ -205,24 +209,24 @@ function $(t) {
205
209
  const { documentModifier: e, product: o, priceEl: n, oldPriceEl: i, omnibusPriceEl: c, omnibusDiscountEl: r } = t;
206
210
  let s = !1;
207
211
  if (n && "querySelector" in n) {
208
- const u = n.querySelector("strong") ?? n.querySelector("p"), l = A(o, "price");
212
+ const u = n.querySelector("strong") ?? n.querySelector("p"), l = P(o, "price");
209
213
  S(e, u ?? null, l) && (s = !0);
210
214
  }
211
215
  if (i && "querySelector" in i) {
212
- const u = i.querySelector("strong") ?? i.querySelector("p"), l = A(o, "original_price");
216
+ const u = i.querySelector("strong") ?? i.querySelector("p"), l = P(o, "original_price");
213
217
  S(e, u ?? null, l) && (s = !0);
214
218
  }
215
219
  if (c && "querySelector" in c) {
216
- const u = c.querySelector(".omnibus-price-value") ?? null, l = A(o, "original_price");
220
+ const u = c.querySelector(".omnibus-price-value") ?? null, l = P(o, "original_price");
217
221
  S(e, u, l) && (s = !0);
218
222
  }
219
223
  if (r && "querySelector" in r) {
220
- const u = r.querySelector(".omnibus-discount-value") ?? null, l = z(o);
224
+ const u = r.querySelector(".omnibus-discount-value") ?? null, l = Q(o);
221
225
  S(e, u, l) && (s = !0);
222
226
  }
223
227
  return s;
224
228
  }
225
- function J(t) {
229
+ function Z(t) {
226
230
  const {
227
231
  documentModifier: e,
228
232
  product: o,
@@ -237,7 +241,7 @@ function J(t) {
237
241
  let d = !1;
238
242
  if (n && "querySelector" in n) {
239
243
  const a = n.querySelector("img");
240
- a && (e.modifyHtml(a).setAttribute("src", V(o.image_url)).setAttribute("alt", o.name), d = !0);
244
+ a && (e.modifyHtml(a).setAttribute("src", G(o.image_url)).setAttribute("alt", o.name), d = !0);
241
245
  const f = n.querySelector("a");
242
246
  f && (e.modifyHtml(f).setAttribute("href", o.url), d = !0);
243
247
  }
@@ -259,10 +263,10 @@ function J(t) {
259
263
  return d;
260
264
  }
261
265
  function B(t) {
262
- return "querySelector" in t ? t.querySelector(P) ?? t : t;
266
+ return "querySelector" in t ? t.querySelector(h) ?? t : t;
263
267
  }
264
268
  const O = "product_attribute.";
265
- function Q(t, e) {
269
+ function ee(t, e) {
266
270
  var n;
267
271
  let o;
268
272
  if (t.startsWith(O)) {
@@ -272,7 +276,7 @@ function Q(t, e) {
272
276
  o = e[t];
273
277
  return typeof o == "string" && o.length > 0 ? o : typeof o == "number" ? String(o) : null;
274
278
  }
275
- function Z(t, e, o) {
279
+ function te(t, e, o) {
276
280
  if (!("querySelectorAll" in t))
277
281
  return !1;
278
282
  const n = t.querySelectorAll(
@@ -284,7 +288,7 @@ function Z(t, e, o) {
284
288
  n.forEach((r) => {
285
289
  if (!("getAttribute" in r))
286
290
  return;
287
- const s = r.getAttribute(W);
291
+ const s = r.getAttribute(j);
288
292
  if (!s)
289
293
  return;
290
294
  const u = i.get(s) ?? [];
@@ -296,7 +300,7 @@ function Z(t, e, o) {
296
300
  r.slice(0, u).forEach((l, d) => {
297
301
  if (!("querySelector" in l))
298
302
  return;
299
- const a = Q(s, o[d]);
303
+ const a = ee(s, o[d]);
300
304
  if (a === null)
301
305
  return;
302
306
  const f = l.querySelector("p") ?? null;
@@ -304,7 +308,7 @@ function Z(t, e, o) {
304
308
  });
305
309
  }), c;
306
310
  }
307
- function w(t, e, o) {
311
+ function _(t, e, o) {
308
312
  if (!("querySelectorAll" in t))
309
313
  return !1;
310
314
  const n = t.querySelectorAll(
@@ -324,7 +328,7 @@ function w(t, e, o) {
324
328
  ), d = Math.min(n.length, o.length);
325
329
  let a = !1;
326
330
  for (let f = 0; f < d; f++) {
327
- const g = J({
331
+ const g = Z({
328
332
  documentModifier: e,
329
333
  product: o[f],
330
334
  imageEl: n[f] ?? null,
@@ -337,9 +341,9 @@ function w(t, e, o) {
337
341
  });
338
342
  a = a || g;
339
343
  }
340
- return Z(t, e, o) && (a = !0), a;
344
+ return te(t, e, o) && (a = !0), a;
341
345
  }
342
- function de(t) {
346
+ function me(t) {
343
347
  const { currentNode: e, documentModifier: o, products: n } = t;
344
348
  if (!e || !("querySelectorAll" in e))
345
349
  return !1;
@@ -348,12 +352,12 @@ function de(t) {
348
352
  `[esd-extension-block-id="${m.IMAGE}"]`
349
353
  ).length !== n.length)
350
354
  return !1;
351
- let r = w(i, o, n);
355
+ let r = _(i, o, n);
352
356
  const s = b(e), u = E.getConfig(e);
353
357
  if (s !== "list" && u.mobileLayoutEnabled && "querySelector" in e) {
354
358
  const l = e.querySelector(q);
355
359
  if (l) {
356
- const d = w(
360
+ const d = _(
357
361
  l,
358
362
  o,
359
363
  n
@@ -363,7 +367,7 @@ function de(t) {
363
367
  }
364
368
  return r && o.apply(new p("Updated product content in-place")), !0;
365
369
  }
366
- function N(t, e, o) {
370
+ function k(t, e, o) {
367
371
  if (!("querySelectorAll" in t))
368
372
  return !1;
369
373
  const n = t.querySelectorAll(
@@ -387,27 +391,29 @@ function N(t, e, o) {
387
391
  }) && (u = !0);
388
392
  return u;
389
393
  }
390
- function fe(t) {
394
+ function pe(t) {
391
395
  const { currentNode: e, documentModifier: o } = t;
392
396
  if (!e || !("querySelectorAll" in e))
393
397
  return !1;
398
+ if (K(e))
399
+ return !0;
394
400
  const i = C().recommendationProducts;
395
401
  if (i.length === 0)
396
402
  return !1;
397
403
  const c = B(e);
398
- let r = N(c, o, i);
404
+ let r = k(c, o, i);
399
405
  const s = b(e), u = E.getConfig(e);
400
406
  if (s !== "list" && u.mobileLayoutEnabled && "querySelector" in e) {
401
407
  const l = e.querySelector(q);
402
408
  if (l) {
403
- const d = N(l, o, i);
409
+ const d = k(l, o, i);
404
410
  r = r || d;
405
411
  }
406
412
  }
407
413
  return r && o.apply(new p("Updated price formatting in-place")), r;
408
414
  }
409
- function me(t) {
410
- const { currentNode: e, documentModifier: o, currency: n } = t, i = h(e);
415
+ function ye(t) {
416
+ const { currentNode: e, documentModifier: o, currency: n } = t, i = A(e);
411
417
  if (!i)
412
418
  return;
413
419
  const c = n.alignment === "before" ? "0" : "1", r = (s, u) => {
@@ -416,17 +422,18 @@ function me(t) {
416
422
  r(y.CURRENCY, n.code), r(y.SYMBOL, n.symbol), r(y.ALIGNMENT, c), r(y.THOUSAND_SEPARATOR, n.thousandSeparator), r(y.DECIMAL_SEPARATOR, n.decimalSeparator), r(y.DECIMAL_COUNT, n.decimalCount.toString()), o.apply(new p("Update currency attributes"));
417
423
  }
418
424
  export {
419
- ae as adjustProductsToSize,
420
- A as formatProductPrice,
421
- h as getBlockElement,
425
+ fe as adjustProductsToSize,
426
+ P as formatProductPrice,
427
+ A as getBlockElement,
422
428
  x as getCardComposition,
423
429
  b as getCurrentLayout,
424
- X as reapplySpacing,
425
- Y as regenerateMobileProductRows,
426
- K as regenerateProductRows,
427
- se as regenerateProductRowsWithStyles,
428
- me as setCurrencyAttributes,
429
- fe as updatePricesInPlace,
430
- de as updateProductContentInPlace,
431
- J as updateSingleProductContent
430
+ K as isPartnerManagedBlock,
431
+ J as reapplySpacing,
432
+ X as regenerateMobileProductRows,
433
+ z as regenerateProductRows,
434
+ de as regenerateProductRowsWithStyles,
435
+ ye as setCurrencyAttributes,
436
+ pe as updatePricesInPlace,
437
+ me as updateProductContentInPlace,
438
+ Z as updateSingleProductContent
432
439
  };
@@ -1,11 +1,12 @@
1
1
  var m = Object.defineProperty;
2
- var _ = (o, e, t) => e in o ? m(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var a = (o, e, t) => _(o, typeof e != "symbol" ? e + "" : e, t);
4
- import { UIElementType as c, UEAttr as p } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ var p = (o, e, t) => e in o ? m(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var a = (o, e, t) => p(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import { UIElementType as c, UEAttr as _ } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
5
  import { CommonControl as d } from "../../common-control.js";
6
6
  import { RecommendationControlId as C } from "../constants/controlIds.js";
7
+ import "../constants/selectors.js";
7
8
  const S = C.SYNC_INFO_MESSAGE, r = "sync-info-message", u = "Note that changes will be applied to all product cards in your recommendation block.";
8
- class h extends d {
9
+ class O extends d {
9
10
  constructor() {
10
11
  super(...arguments);
11
12
  a(this, "_repositionedElement", null);
@@ -17,7 +18,7 @@ class h extends d {
17
18
  return `
18
19
  <div class="${r}">
19
20
  <${c.ICON}
20
- ${p.ICON.src}="migration-info-icon"
21
+ ${_.ICON.src}="migration-info-icon"
21
22
  class="${r}__icon">
22
23
  </${c.ICON}>
23
24
  <p class="${r}__text">
@@ -61,5 +62,5 @@ class h extends d {
61
62
  }
62
63
  export {
63
64
  S as SYNC_INFO_MESSAGE_CONTROL_ID,
64
- h as SyncInfoMessageControl
65
+ O as SyncInfoMessageControl
65
66
  };
@@ -1,13 +1,14 @@
1
1
  import { ExtensionBuilder as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { RecommendationBlock as m } from "./block.js";
3
3
  import { RecommendationBlockControl as n } from "./controls/main/index.js";
4
+ import "./constants/selectors.js";
4
5
  import "./store/recommendation.js";
5
6
  import { NameControls as i } from "./controls/name/index.js";
6
7
  import { PriceControls as e } from "./controls/price/index.js";
7
8
  import { OldPriceControls as s } from "./controls/oldPrice/index.js";
8
9
  import { OmnibusPriceControls as l } from "./controls/omnibusPrice/index.js";
9
- import { OmnibusDiscountControls as a } from "./controls/omnibusDiscount/index.js";
10
- import { ButtonControls as p } from "./controls/button/index.js";
10
+ import { OmnibusDiscountControls as p } from "./controls/omnibusDiscount/index.js";
11
+ import { ButtonControls as a } from "./controls/button/index.js";
11
12
  import { ImageControls as c } from "./controls/image/index.js";
12
13
  import { CustomAttributeControls as C } from "./controls/customAttribute/index.js";
13
14
  import { SpacingControl as f } from "./controls/spacing/index.js";
@@ -22,8 +23,8 @@ const b = [
22
23
  e,
23
24
  s,
24
25
  l,
25
- a,
26
26
  p,
27
+ a,
27
28
  c,
28
29
  C
29
30
  ], P = [
@@ -35,10 +36,10 @@ const b = [
35
36
  ], S = [
36
37
  ...P,
37
38
  ...b.flatMap((o) => Object.values(o))
38
- ], K = S.reduce(
39
+ ], L = S.reduce(
39
40
  (o, t) => o.addControl(t),
40
41
  new r().addBlock(m).withSettingsPanelRegistry(B)
41
42
  ).addStyles(y).withIconsRegistry(R).build();
42
43
  export {
43
- K as default
44
+ L as default
44
45
  };
@@ -2,6 +2,7 @@ import { SettingsPanelRegistry as E, SettingsPanelTab as _, SettingsTab as O, Co
2
2
  import { BLOCK_ID as U } from "./block.js";
3
3
  import { RecommendationBlockId as S } from "./constants/blockIds.js";
4
4
  import { RecommendationControlId as T } from "./constants/controlIds.js";
5
+ import "./constants/selectors.js";
5
6
  import { CONTROL_BLOCK_ID as A } from "./controls/main/index.js";
6
7
  import "./store/recommendation.js";
7
8
  import "./controls/name/index.js";
@@ -15,7 +16,7 @@ import { SPACING_CONTROL_ID as L } from "./controls/spacing/index.js";
15
16
  import { CARD_BACKGROUND_COLOR_CONTROL_ID as D } from "./controls/cardBackground/index.js";
16
17
  import { COMPOSITION_CONTROL_BLOCK_ID as B } from "./controls/cardComposition/index.js";
17
18
  import { SYNC_INFO_MESSAGE_CONTROL_ID as N } from "./controls/syncInfoMessage.js";
18
- class Z extends E {
19
+ class a extends E {
19
20
  registerBlockControls(I) {
20
21
  I[U] = [
21
22
  new _(
@@ -194,5 +195,5 @@ class Z extends E {
194
195
  }
195
196
  }
196
197
  export {
197
- Z as SettingsPanel
198
+ a as SettingsPanel
198
199
  };
@@ -2,6 +2,7 @@ import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAtt
2
2
  import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
3
  import { useConfigStore as G } from "../../../../stores/config.js";
4
4
  import { defineStore as P } from "pinia";
5
+ import "../constants/selectors.js";
5
6
  import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
7
  import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
7
8
  import { getDefaultProducts as S } from "../templates/utils.js";
@@ -59,7 +60,7 @@ const x = () => ({
59
60
  blockStates: {},
60
61
  currentRecommendationId: null,
61
62
  configVersion: 0
62
- }), T = P("guidoRecommendationExtension", {
63
+ }), K = P("guidoRecommendationExtension", {
63
64
  state: () => x(),
64
65
  getters: {
65
66
  // ====================================================================
@@ -475,5 +476,5 @@ const x = () => ({
475
476
  }
476
477
  });
477
478
  export {
478
- T as useRecommendationExtensionStore
479
+ K as useRecommendationExtensionStore
479
480
  };
@@ -1,3 +1,4 @@
1
+ import "../../constants/selectors.js";
1
2
  import { DEFAULT_PRODUCTS_PER_ROW as L } from "../../constants/layout.js";
2
3
  import { getDefaultProducts as E, DEFAULTS as I, createBlockTemplate as _, DEFAULT_CARD_COMPOSITION as S, spacer as b, buildElementRenderer as A, DEFAULT_CARD_VISIBILITY as f } from "../utils.js";
3
4
  import { ATTRIBUTE_CELL_CLASS as w, DEFAULT_CELL_PADDING as D, gridElementRenderer as C } from "./elementRenderer.js";
@@ -52,12 +53,12 @@ function U(t, e, o, r, n = {}) {
52
53
  function h(t, e, o, r = {}) {
53
54
  return U(t, e, C, o, r);
54
55
  }
55
- function F(t) {
56
+ function H(t) {
56
57
  const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o = _("grid", e), r = E(), n = h(r, L);
57
58
  return o.replace("{-{-TITLE-}-}", I.TITLE).replace("{-{-PRODUCT_ROWS-}-}", n).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
58
59
  }
59
60
  export {
60
- F as getDefaultTemplate,
61
+ H as getDefaultTemplate,
61
62
  P as prepareGridAttributeRows,
62
63
  U as prepareGridProductRows,
63
64
  h as prepareProductRows
@@ -1,12 +1,13 @@
1
+ import "../constants/selectors.js";
1
2
  import { DEFAULT_PRODUCTS_PER_ROW as s } from "../constants/layout.js";
2
3
  import { prepareProductRows as c } from "./grid/template.js";
3
- import { prepareProductRows as R } from "./list/template.js";
4
- function a(o, t, r = {}) {
4
+ import { prepareProductRows as m } from "./list/template.js";
5
+ function f(o, t, r = {}) {
5
6
  if (t === "list")
6
- return R(o, r.composition, r.filterList);
7
+ return m(o, r.composition, r.filterList);
7
8
  const { productsPerRow: e = s, composition: p, filterList: i } = r;
8
9
  return c(o, e, p, i);
9
10
  }
10
11
  export {
11
- a as prepareProductRows
12
+ f as prepareProductRows
12
13
  };
@@ -1,4 +1,31 @@
1
1
  import type { DynamicContent } from '@@/Types/generic';
2
+ import type { FiltersResponse } from '@@/Types/recommendation';
3
+ /**
4
+ * Parses a `{{recoId_index_attributeName}}` variable (already stripped of the
5
+ * braces/whitespace) into its recommendation id and attribute name. Returns
6
+ * null for anything that isn't a well-formed recommendation variable.
7
+ */
8
+ export declare function parseRecommendationVariable(field: string): {
9
+ recoId: string;
10
+ attribute: string;
11
+ } | null;
12
+ /**
13
+ * Builds the set of attribute forms valid inside partner-authored
14
+ * `{{recoId_index_attribute}}` variables: the built-in compiler attributes plus
15
+ * each account attribute in its canonical token form — bare for
16
+ * `defaultAttribute`, `product_attribute.<name>` for `productAttribute`. Using
17
+ * `resolveProductAttrValue` (the same producer the block builder uses) keeps the
18
+ * validator's notion of "valid form" identical to what is actually emitted.
19
+ */
20
+ export declare function buildPartnerAttributeNameSet(filterList: FiltersResponse): Set<string>;
21
+ /**
22
+ * Returns the `{{...}}` custom fields in the HTML that are invalid. Partner
23
+ * attributes in `ins-skip-compile` blocks (recoId ∈ ignoredIds) are checked
24
+ * against `ignoredAttributeNames`; Guido-generated reco variables and known merge
25
+ * tags pass. An unrecognized dotted token is ignored: it was never captured
26
+ * before, so flagging it would false-positive on merge tags like `{{user.name}}`.
27
+ */
28
+ export declare function findInvalidCustomFields(html: string, validCustomFields: string[], recommendationBlockIds: string[], ignoredIds: Set<string>, ignoredAttributeNames: Set<string> | null): string[];
2
29
  export declare const useHtmlValidator: () => {
3
30
  validateHtml: (html: string, customFields: DynamicContent[], isOnSaveValidation?: boolean) => Promise<boolean>;
4
31
  };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Returns true when a recommendation block has opted out of Guido's
3
+ * product-data → template-variable substitution. Partners signal opt-out by
4
+ * adding the `ins-skip-compile` class on the `.recommendation-block-v2`
5
+ * element. Only the variable substitution is skipped — campaign URL building,
6
+ * hidden-row removal, Outlook image widths, discount conditions, text-trim CSS
7
+ * and general HTML optimizations still apply. See `CSS_CLASS_SKIP_COMPILE` for
8
+ * the full scope.
9
+ */
10
+ export declare function isIgnoredRecommendationBlock(block: Element): boolean;
11
+ /**
12
+ * DOM-parses the HTML once and returns the set of `recommendation-id`
13
+ * values that belong to ignored blocks. Use this in regex/string-based
14
+ * compiler rules where the rule processes flat matches and only has the
15
+ * extracted block ID rather than a DOM Element reference.
16
+ */
17
+ export declare function getIgnoredRecommendationBlockIds(html: string): Set<string>;
@@ -5,3 +5,18 @@ export declare function extractTitleText(block: Element): string;
5
5
  * the caller treats that as "no segment background".
6
6
  */
7
7
  export declare function extractCardBgColor(block: Element): string;
8
+ /**
9
+ * Reads the legacy block's own `currency-*` attributes into a
10
+ * `currencySettings`-shaped object that `mapCurrency` understands. Used as a
11
+ * fallback when the external recommendationConfigs map has no entry for this
12
+ * block, so the migrated block keeps its real currency instead of defaulting.
13
+ * Returns undefined when the block carries no `currency` attribute.
14
+ */
15
+ export declare function extractCurrencyFromBlock(block: Element): Record<string, string> | undefined;
16
+ /**
17
+ * True when a PM has manually opted the legacy block out of content
18
+ * regeneration by adding the `ins-skip-compile` class. Detected before rebuild
19
+ * so the migrator preserves the partner's markup verbatim (keeping their
20
+ * hand-authored variables) instead of regenerating the block.
21
+ */
22
+ export declare function isPartnerManagedBlock(block: Element): boolean;
@@ -8,4 +8,12 @@ export declare function buildBlockHtml(params: {
8
8
  extraClasses?: string;
9
9
  legacyId?: string;
10
10
  legacyBgColor?: string;
11
+ /**
12
+ * When set, the block's existing inner HTML is preserved verbatim instead
13
+ * of regenerating product rows — used for partner-customized blocks so
14
+ * their hand-authored `{{...}}` variables survive migration.
15
+ */
16
+ preserveInnerHtml?: string;
17
+ /** Adds the `ins-skip-compile` opt-out class to the migrated block. */
18
+ skipCompile?: boolean;
11
19
  }): 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,6 +8,6 @@
8
8
  */
9
9
  export { RecommendationBlockId } from './blockIds';
10
10
  export { RecommendationControlId } from './controlIds';
11
- export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
11
+ export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CSS_CLASS_SKIP_COMPILE, RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
12
12
  export { LAYOUT_VALUES, LAYOUT_OPTIONS, DEFAULT_PRODUCTS_PER_ROW, DEFAULT_CARDS_IN_ROW, DEFAULT_MOBILE_CARDS_IN_ROW, MAX_PRODUCT_COUNT, MIN_PRODUCT_COUNT, MAX_PRODUCTS_PER_ROW, MIN_PRODUCTS_PER_ROW, MAX_MOBILE_PRODUCTS_PER_ROW, MIN_MOBILE_PRODUCTS_PER_ROW, DEFAULT_COLUMN_SPACING, DEFAULT_ROW_SPACING, DEFAULT_MOBILE_COLUMN_SPACING, DEFAULT_MOBILE_ROW_SPACING, MIN_SPACING, MAX_SPACING, SPACING_STEP, } from './layout';
13
13
  export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';