@useinsider/guido 2.2.0-beta.eeefcc3 → 3.0.0-beta.fd7cee3

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 (101) hide show
  1. package/README.md +41 -2
  2. package/dist/@types/config/schemas.js +1 -1
  3. package/dist/components/Guido.vue.js +1 -1
  4. package/dist/components/Guido.vue2.js +66 -66
  5. package/dist/components/organisms/base/Toaster.vue.js +4 -4
  6. package/dist/components/organisms/base/Toaster.vue2.js +12 -9
  7. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue.js +5 -5
  8. package/dist/components/organisms/email-preview/desktop-preview/EmailSizeIndicator.vue2.js +2 -2
  9. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +11 -13
  10. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +54 -23
  11. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +7 -5
  12. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +34 -21
  13. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +11 -11
  14. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +48 -36
  15. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +11 -9
  16. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +1 -1
  17. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +19 -19
  18. package/dist/composables/useRecommendation.js +9 -9
  19. package/dist/composables/useSave.js +16 -12
  20. package/dist/composables/useStripo.js +66 -62
  21. package/dist/composables/useStripoEventHandler.js +27 -12
  22. package/dist/composables/useSyncModuleExtractor.js +45 -0
  23. package/dist/config/compiler/utils/recommendationCompilerUtils.js +1 -1
  24. package/dist/config/migrator/recommendationMigrator.js +1 -1
  25. package/dist/enums/unsubscribe.js +25 -21
  26. package/dist/extensions/Blocks/Recommendation/block.js +1 -1
  27. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +36 -33
  28. package/dist/extensions/Blocks/Recommendation/constants/layout.js +16 -14
  29. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +15 -13
  30. package/dist/extensions/Blocks/Recommendation/controls/button/index.js +9 -9
  31. package/dist/extensions/Blocks/Recommendation/controls/image/index.js +1 -1
  32. package/dist/extensions/Blocks/Recommendation/controls/layout/index.js +41 -29
  33. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +16 -16
  34. package/dist/extensions/Blocks/Recommendation/controls/main/currency.js +30 -32
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +194 -104
  36. package/dist/extensions/Blocks/Recommendation/controls/main/locale.js +9 -9
  37. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +46 -38
  38. package/dist/extensions/Blocks/Recommendation/controls/main/shuffle.js +16 -16
  39. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +291 -217
  40. package/dist/extensions/Blocks/Recommendation/controls/mobileLayout/cssRules.js +14 -14
  41. package/dist/extensions/Blocks/Recommendation/controls/name/index.js +10 -10
  42. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +5 -5
  43. package/dist/extensions/Blocks/Recommendation/controls/oldPrice/index.js +14 -14
  44. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.js +9 -9
  45. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +3 -3
  46. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +1 -1
  47. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/index.js +9 -9
  48. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +3 -3
  49. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +13 -13
  50. package/dist/extensions/Blocks/Recommendation/controls/price/index.js +3 -3
  51. package/dist/extensions/Blocks/Recommendation/controls/spacing/index.js +223 -99
  52. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +172 -85
  53. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +2 -2
  54. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +1 -1
  55. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +2 -2
  56. package/dist/extensions/Blocks/Recommendation/templates/utils.js +32 -32
  57. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +8 -8
  58. package/dist/extensions/Blocks/Recommendation/validation/filterSchema.js +29 -0
  59. package/dist/extensions/Blocks/Unsubscribe/block.js +29 -29
  60. package/dist/extensions/Blocks/Unsubscribe/control.js +12 -9
  61. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +13 -11
  62. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +31 -1
  63. package/dist/guido.css +1 -1
  64. package/dist/services/stripoApi.js +55 -19
  65. package/dist/src/@types/config/schemas.d.ts +1 -1
  66. package/dist/src/@types/events.d.ts +38 -2
  67. package/dist/src/components/Guido.vue.d.ts +2 -2
  68. package/dist/src/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +1 -0
  69. package/dist/src/components/organisms/extensions/recommendation/Filters.vue.d.ts +17 -1
  70. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  71. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  72. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  73. package/dist/src/composables/useGuidoActions.d.ts +1 -1
  74. package/dist/src/composables/useSave.d.ts +2 -2
  75. package/dist/src/composables/useStripo.d.ts +2 -2
  76. package/dist/src/composables/useSyncModuleExtractor.d.ts +4 -0
  77. package/dist/src/enums/unsubscribe.d.ts +3 -0
  78. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +6 -0
  79. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +3 -3
  80. package/dist/src/extensions/Blocks/Recommendation/constants/layout.d.ts +6 -2
  81. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +8 -1
  82. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +38 -10
  83. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +27 -14
  84. package/dist/src/extensions/Blocks/Recommendation/controls/spacing/index.d.ts +50 -17
  85. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +19 -2
  86. package/dist/src/extensions/Blocks/Recommendation/templates/grid/migration.d.ts +1 -1
  87. package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +4 -2
  88. package/dist/src/extensions/Blocks/Recommendation/templates/list/migration.d.ts +1 -1
  89. package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +1 -1
  90. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +8 -0
  91. package/dist/src/extensions/Blocks/Recommendation/validation/filterSchema.d.ts +15 -0
  92. package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
  93. package/dist/src/mock/api/settings.d.ts +2 -0
  94. package/dist/src/services/stripoApi.d.ts +5 -0
  95. package/dist/src/stores/editor.d.ts +23 -0
  96. package/dist/src/utils/templatePreparation.d.ts +1 -1
  97. package/dist/static/styles/customEditorStyle.css.js +50 -23
  98. package/dist/stores/editor.js +2 -1
  99. package/dist/stores/unsubscribe.js +37 -34
  100. package/dist/utils/templatePreparation.js +1 -1
  101. package/package.json +2 -2
@@ -1,14 +1,17 @@
1
- import { RecommendationFeedSourceMaps as d, PriceAttributes as S } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as p } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as b } from "../../../../stores/config.js";
4
- import { defineStore as I } from "pinia";
5
- import { DEFAULT_CARDS_IN_ROW as R } from "../constants/layout.js";
6
- import { getDefaultProducts as k } from "../templates/utils.js";
7
- import { generateCompleteFilterQuery as f } from "../utils/filterUtil.js";
8
- const m = p();
9
- function h() {
1
+ import { RecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as k } from "../../../../enums/extensions/recommendationBlock.js";
2
+ import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as C } from "../../../../stores/config.js";
4
+ import { defineStore as G } from "pinia";
5
+ import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
+ import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
7
+ import { getDefaultProducts as S } from "../templates/utils.js";
8
+ import { generateCompleteFilterQuery as I } from "../utils/filterUtil.js";
9
+ import { isFilterValid as D } from "../validation/filterSchema.js";
10
+ const h = y();
11
+ let u = null, m = null, d = null;
12
+ function b() {
10
13
  return {
11
- cardsInRow: R,
14
+ cardsInRow: F,
12
15
  currencySettings: {
13
16
  name: "USD",
14
17
  value: "USD",
@@ -32,17 +35,18 @@ function h() {
32
35
  size: "6"
33
36
  };
34
37
  }
35
- function C() {
38
+ function P() {
36
39
  return {
37
- recommendationConfigs: h(),
40
+ recommendationConfigs: b(),
38
41
  recommendationProducts: [],
39
42
  filterStatus: !1,
40
43
  filterSelectionDrawerStatus: !1,
41
44
  filterGroup: 1,
42
- isInitialized: !1
45
+ isInitialized: !1,
46
+ filterSnapshot: null
43
47
  };
44
48
  }
45
- const y = () => ({
49
+ const v = () => ({
46
50
  recommendationCampaignUrls: {},
47
51
  activePredictiveAlgorithms: [],
48
52
  languages: {},
@@ -51,8 +55,8 @@ const y = () => ({
51
55
  blockStates: {},
52
56
  currentRecommendationId: null,
53
57
  configVersion: 0
54
- }), A = I("guidoRecommendationExtension", {
55
- state: () => y(),
58
+ }), E = G("guidoRecommendationExtension", {
59
+ state: () => v(),
56
60
  getters: {
57
61
  // ====================================================================
58
62
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -62,7 +66,7 @@ const y = () => ({
62
66
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
63
67
  */
64
68
  recommendationConfigs(t) {
65
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : h();
69
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : b();
66
70
  },
67
71
  /**
68
72
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -94,14 +98,22 @@ const y = () => ({
94
98
  hasFilters() {
95
99
  return !!this.recommendationConfigs.filters.length;
96
100
  },
101
+ hasValidFilters() {
102
+ const { filters: t } = this.recommendationConfigs;
103
+ return t.length ? t.every((r) => r.isValid) : !1;
104
+ },
97
105
  getFilterGroupCount() {
98
106
  const { filters: t } = this.recommendationConfigs;
99
- return t.length && t[t.length - 1].filterGroup || 0;
107
+ return t.length ? new Set(t.map((r) => r.filterGroup)).size : 0;
108
+ },
109
+ getUniqueFilterGroups() {
110
+ const { filters: t } = this.recommendationConfigs;
111
+ return [...new Set(t.map((r) => r.filterGroup))].sort((r, e) => r - e);
100
112
  },
101
113
  getActivePredictiveAlgorithms: (t) => {
102
114
  const r = [];
103
- return t.activePredictiveAlgorithms.forEach((e) => {
104
- r.push(...d.filter((n) => n.id === e));
115
+ return t.activePredictiveAlgorithms.filter((e) => !w.includes(e)).forEach((e) => {
116
+ r.push(...g.filter((n) => n.id === e));
105
117
  }), r.map((e) => ({
106
118
  text: e.name,
107
119
  value: e.key
@@ -117,7 +129,7 @@ const y = () => ({
117
129
  })),
118
130
  getFilterList() {
119
131
  return Object.values(this.filterList).map((t) => {
120
- const r = t.type === "defaultAttribute", e = S.includes(t.attributeName);
132
+ const r = t.type === "defaultAttribute", e = k.includes(t.attributeName);
121
133
  let n = r ? t.attributeName : `product_attributes.${t.attributeName}`;
122
134
  return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
123
135
  text: t.displayName,
@@ -141,7 +153,7 @@ const y = () => ({
141
153
  setCurrentBlock(t) {
142
154
  this.blockStates[t] || (this.blockStates = {
143
155
  ...this.blockStates,
144
- [t]: C()
156
+ [t]: P()
145
157
  }), this.currentRecommendationId = t;
146
158
  },
147
159
  /**
@@ -181,71 +193,118 @@ const y = () => ({
181
193
  const { triggerRefetch: n = !0 } = r;
182
194
  n && this.configVersion++;
183
195
  },
196
+ /**
197
+ * Creates a filter with the first available attribute and operator pre-selected.
198
+ */
199
+ createDefaultFilter(t, r) {
200
+ const [e] = this.getFilterList, [n] = R(e == null ? void 0 : e.type);
201
+ return {
202
+ type: "standardFilter",
203
+ attribute: (e == null ? void 0 : e.value) ?? "",
204
+ operator: (n == null ? void 0 : n.value) ?? "",
205
+ innerGroupOperator: "*",
206
+ outerGroupOperator: "*",
207
+ filterNumber: r,
208
+ filterGroup: t,
209
+ isValid: !1,
210
+ value: ""
211
+ };
212
+ },
184
213
  /**
185
214
  * Opens the filter selection drawer for the current block.
186
- * If no filters exist, initializes with a default empty filter
215
+ * Saves a snapshot of current filters for cancel/revert.
216
+ * If no filters exist, initializes with a default filter
187
217
  * so the user has a starting point for input.
188
218
  */
189
219
  openFilterDrawer() {
190
220
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
191
221
  return;
192
222
  const t = this.blockStates[this.currentRecommendationId];
193
- t.recommendationConfigs.filters.length || (t.recommendationConfigs.filters = [{
194
- type: "standardFilter",
195
- attribute: "",
196
- operatorReplace: "",
197
- operator: "",
198
- innerGroupOperator: "*",
199
- outerGroupOperator: "*",
200
- filterNumber: 1,
201
- filterGroup: 1,
202
- isValid: !1,
203
- value: ""
204
- }]), t.filterSelectionDrawerStatus = !0;
223
+ t.filterSnapshot = JSON.parse(
224
+ JSON.stringify(t.recommendationConfigs.filters)
225
+ ), t.recommendationConfigs.filters.length || (t.recommendationConfigs.filters = [this.createDefaultFilter(1, 1)]), t.filterSelectionDrawerStatus = !0;
205
226
  },
206
227
  /**
207
- * Closes the filter selection drawer for the current block
228
+ * Closes the filter selection drawer for the current block.
229
+ * Called after successful apply — discards the snapshot.
208
230
  */
209
231
  closeFilterDrawer() {
210
- this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || (this.blockStates[this.currentRecommendationId].filterSelectionDrawerStatus = !1);
232
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
233
+ return;
234
+ const t = this.blockStates[this.currentRecommendationId];
235
+ t.filterSnapshot = null, t.filterSelectionDrawerStatus = !1;
236
+ },
237
+ /**
238
+ * Cancels the filter selection drawer and reverts filters
239
+ * to the snapshot taken when the drawer was opened.
240
+ */
241
+ cancelFilterDrawer() {
242
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
243
+ return;
244
+ const t = this.blockStates[this.currentRecommendationId];
245
+ t.filterSnapshot !== null && (t.recommendationConfigs.filters = t.filterSnapshot, t.filterSnapshot = null), t.filterSelectionDrawerStatus = !1;
211
246
  },
212
247
  // ====================================================================
213
248
  // Shared Data Fetching (fetched once, used by all blocks)
214
249
  // ====================================================================
215
250
  async fetchRecommendationCreateData() {
216
- if (this.activePredictiveAlgorithms.length)
217
- return;
218
- const {
219
- activePredictiveAlgorithms: t,
220
- languages: r,
221
- currencies: e
222
- } = await m.fetchRecommendationCreateData();
223
- if (this.activePredictiveAlgorithms = t, this.languages = r, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
224
- const n = this.blockStates[this.currentRecommendationId];
225
- n.filterStatus = !!n.recommendationConfigs.filters.length;
251
+ if (!this.activePredictiveAlgorithms.length) {
252
+ if (u) {
253
+ await u;
254
+ return;
255
+ }
256
+ u = (async () => {
257
+ const {
258
+ activePredictiveAlgorithms: t,
259
+ languages: r,
260
+ currencies: e
261
+ } = await h.fetchRecommendationCreateData();
262
+ if (this.activePredictiveAlgorithms = t, this.languages = r, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
263
+ const n = this.blockStates[this.currentRecommendationId];
264
+ n.filterStatus = !!n.recommendationConfigs.filters.length;
265
+ }
266
+ this.currencyList = e;
267
+ })();
268
+ try {
269
+ await u;
270
+ } finally {
271
+ u = null;
272
+ }
226
273
  }
227
- this.currencyList = e;
228
274
  },
229
275
  async fetchRecommendationFilters() {
230
- const t = await m.fetchRecommendationFilters();
231
- this.filterList = t;
276
+ if (!Object.keys(this.filterList).length) {
277
+ if (m) {
278
+ await m;
279
+ return;
280
+ }
281
+ m = (async () => {
282
+ const t = await h.fetchRecommendationFilters();
283
+ this.filterList = t;
284
+ })();
285
+ try {
286
+ await m;
287
+ } finally {
288
+ m = null;
289
+ }
290
+ }
232
291
  },
233
292
  // ====================================================================
234
293
  // Per-Block Filter Actions
235
294
  // ====================================================================
236
295
  addFilterGroup(t) {
237
- this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || this.blockStates[this.currentRecommendationId].recommendationConfigs.filters.push({
238
- type: "standardFilter",
239
- attribute: "",
240
- operatorReplace: "",
241
- operator: "",
242
- innerGroupOperator: "",
243
- outerGroupOperator: "",
244
- value: "",
245
- filterNumber: 1,
246
- isValid: !0,
247
- filterGroup: t
248
- });
296
+ this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId] || this.blockStates[this.currentRecommendationId].recommendationConfigs.filters.push(
297
+ this.createDefaultFilter(t, 1)
298
+ );
299
+ },
300
+ deleteFilterGroup(t) {
301
+ if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
302
+ return;
303
+ const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(e.map((i) => i.filterGroup))].sort((i, o) => i - o), c = new Map(n.map((i, o) => [i, o + 1]));
304
+ r.recommendationConfigs.filters = e.map((i) => ({
305
+ ...i,
306
+ filterGroup: c.get(i.filterGroup) ?? i.filterGroup
307
+ }));
249
308
  },
250
309
  updateFilter(t) {
251
310
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
@@ -253,7 +312,10 @@ const y = () => ({
253
312
  const r = this.blockStates[this.currentRecommendationId], e = r.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
254
313
  if (e !== -1) {
255
314
  const n = [...r.recommendationConfigs.filters];
256
- n[e] = t, t.value.length && t.operator && t.attribute && t.innerGroupOperator && t.outerGroupOperator ? n[e].isValid = !0 : n[e].isValid = !1, r.recommendationConfigs.filters = n;
315
+ n[e] = {
316
+ ...t,
317
+ isValid: D(t)
318
+ }, r.recommendationConfigs.filters = n;
257
319
  }
258
320
  },
259
321
  deleteFilter(t) {
@@ -261,54 +323,79 @@ const y = () => ({
261
323
  return;
262
324
  const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
263
325
  if (e !== -1) {
264
- const n = [...r.recommendationConfigs.filters];
265
- n.splice(e, 1), r.recommendationConfigs.filters = n;
326
+ let n = [...r.recommendationConfigs.filters];
327
+ if (n.splice(e, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
328
+ let i = 1;
329
+ n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
330
+ } else {
331
+ const i = [...new Set(n.map((s) => s.filterGroup))].sort((s, l) => s - l), o = new Map(i.map((s, l) => [s, l + 1]));
332
+ n = n.map((s) => ({
333
+ ...s,
334
+ filterGroup: o.get(s.filterGroup) ?? s.filterGroup
335
+ }));
336
+ }
337
+ r.recommendationConfigs.filters = n;
266
338
  }
267
339
  },
268
340
  addFilter(t) {
269
341
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
270
342
  return;
271
- const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters], o = e.filter(
272
- (i) => i.filterGroup === t.filterGroup
273
- ).length + 1, s = e.findLastIndex((i) => i.filterGroup === t.filterGroup);
274
- s !== -1 ? e.splice(s + 1, 0, {
343
+ const r = this.blockStates[this.currentRecommendationId], e = [...r.recommendationConfigs.filters], c = e.filter(
344
+ (o) => o.filterGroup === t.filterGroup
345
+ ).length + 1, i = e.findLastIndex((o) => o.filterGroup === t.filterGroup);
346
+ i !== -1 ? e.splice(i + 1, 0, {
275
347
  ...t,
276
- filterNumber: o
348
+ filterNumber: c
277
349
  }) : e.push({
278
350
  ...t,
279
- filterNumber: o
351
+ filterNumber: c
280
352
  }), r.recommendationConfigs.filters = e;
281
353
  },
282
354
  generateFilterQuery() {
283
- return f(this.recommendationConfigs.filters);
355
+ return I(this.recommendationConfigs.filters);
284
356
  },
285
357
  // ====================================================================
286
358
  // Per-Block Product Fetching
287
359
  // ====================================================================
288
360
  async fetchRecommendationProducts() {
289
- var u;
290
- if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
291
- return;
292
- const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((l) => l.isValid), o = f(n), s = ((u = d.find((l) => l.key === e.strategy)) == null ? void 0 : u.path) || "", i = b(), c = {
361
+ if (!(this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])) {
362
+ if (d) {
363
+ await d;
364
+ return;
365
+ }
366
+ d = this._doFetchProducts();
367
+ try {
368
+ await d;
369
+ } finally {
370
+ d = null;
371
+ }
372
+ }
373
+ },
374
+ async _doFetchProducts() {
375
+ var p;
376
+ const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((a) => a.isValid), c = I(n), i = ((p = g.find((a) => a.key === e.strategy)) == null ? void 0 : p.path) || "", o = C(), s = {
293
377
  locale: e.language,
294
378
  currency: e.currencySettings.value,
295
- partnerName: i.partnerName,
379
+ partnerName: o.partnerName,
296
380
  size: e.size,
297
381
  details: !0,
298
- campaignId: i.variationId
382
+ campaignId: o.variationId
299
383
  };
300
- e.strategy === "manualMerchandising" ? c.productId = e.productIds.join(",") : e.strategy === "similarViewed" && (c.productId = "{itemId}"), o && (c.filter = o), e.shuffleProducts && (c.shuffle = !0);
301
- const g = parseInt(e.size) || 6;
302
- let a;
384
+ e.strategy === "manualMerchandising" ? s.productId = e.productIds.join(",") : e.strategy === "similarViewed" && (s.productId = "{itemId}"), e.strategy === "userBased" && (s.userId = "{user_id}"), c && (s.filter = c), e.shuffleProducts && (s.shuffle = !0);
385
+ const l = parseInt(e.size) || 6;
386
+ let f;
303
387
  try {
304
- a = await m.fetchRecommendationProducts(s, c);
388
+ f = await h.fetchRecommendationProducts(i, s);
305
389
  } catch {
306
- a = [];
390
+ f = [];
391
+ }
392
+ if (this.blockStates[t]) {
393
+ const a = f.length > 0 ? f : S(l);
394
+ this.blockStates[t].recommendationProducts = a.length < l ? [...a, ...S(l - a.length)] : a;
307
395
  }
308
- this.blockStates[t] && (this.blockStates[t].recommendationProducts = a.length > 0 ? a : k(g));
309
396
  }
310
397
  }
311
398
  });
312
399
  export {
313
- A as useRecommendationExtensionStore
400
+ E as useRecommendationExtensionStore
314
401
  };
@@ -141,7 +141,7 @@ const P = {
141
141
  data-text-before="Lowest 30-day price: "
142
142
  data-text-after=""
143
143
  esd-extension-block-id="${s.OMNIBUS_PRICE}">
144
- <p style="font-size: 12px; color: #666666;">
144
+ <p contenteditable="false" style="font-size: 12px; color: #666666;">
145
145
  <span class="omnibus-text-before">Lowest 30-day price: </span>
146
146
  <span class="omnibus-price-value">${c(t, "original_price")}</span>
147
147
  <span class="omnibus-text-after"></span>
@@ -172,7 +172,7 @@ const P = {
172
172
  data-text-before=""
173
173
  data-text-after=""
174
174
  esd-extension-block-id="${s.OMNIBUS_DISCOUNT}">
175
- <p style="font-size: 12px; color: #666666;">
175
+ <p contenteditable="false" style="font-size: 12px; color: #666666;">
176
176
  <span class="omnibus-text-before"></span>
177
177
  <span class="omnibus-discount-value">${g}</span>
178
178
  <span class="omnibus-text-after"></span>
@@ -5,7 +5,7 @@ const u = `
5
5
  align="left"
6
6
  esd-extension-block-id="recommendation-block"
7
7
  esd-handler-name="esd-extension-RecommendationBlock"
8
- class="ins-recommendation-v3-block-v2 esd-block-recommendation-v3-block esd-extension-block es-p20"
8
+ class="recommendation-block-v2 esd-block-recommendation-v3-block esd-extension-block es-p20"
9
9
  >
10
10
  <table width="100%" cellpadding="0" cellspacing="0" border="0">
11
11
  <tr>
@@ -102,7 +102,7 @@ const $ = {
102
102
  data-text-after=""
103
103
  esd-extension-block-id="${o.OMNIBUS_PRICE}"
104
104
  align="left">
105
- <p style="font-size: 12px; color: #666666; margin: 0;">
105
+ <p contenteditable="false" style="font-size: 12px; color: #666666; margin: 0;">
106
106
  <span class="omnibus-text-before">Lowest 30-day price: </span>
107
107
  <span class="omnibus-price-value">${s(t, "original_price")}</span>
108
108
  <span class="omnibus-text-after"></span>
@@ -124,7 +124,7 @@ const $ = {
124
124
  data-text-after=""
125
125
  esd-extension-block-id="${o.OMNIBUS_DISCOUNT}"
126
126
  align="left">
127
- <p style="font-size: 12px; color: #666666; margin: 0;">
127
+ <p contenteditable="false" style="font-size: 12px; color: #666666; margin: 0;">
128
128
  <span class="omnibus-text-before"></span>
129
129
  <span class="omnibus-discount-value">${b}</span>
130
130
  <span class="omnibus-text-after"></span>
@@ -1,28 +1,28 @@
1
- import { ATTR_PRODUCT_IMAGE as n, ATTR_PRODUCT_NAME as o, ATTR_PRODUCT_OLD_PRICE as a, ATTR_PRODUCT_PRICE as c, ATTR_PRODUCT_OMNIBUS_PRICE as l, ATTR_PRODUCT_OMNIBUS_DISCOUNT as i, ATTR_PRODUCT_BUTTON as s } from "../constants/selectors.js";
2
- const g = {
1
+ import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as s, ATTR_PRODUCT_OLD_PRICE as r, ATTR_PRODUCT_PRICE as l, ATTR_PRODUCT_OMNIBUS_PRICE as i, ATTR_PRODUCT_OMNIBUS_DISCOUNT as a, ATTR_PRODUCT_BUTTON as c } from "../constants/selectors.js";
2
+ const C = {
3
3
  TITLE: "You May Also Like!"
4
- }, u = [
5
- n,
4
+ }, D = [
6
5
  o,
7
- a,
8
- c,
6
+ s,
7
+ r,
9
8
  l,
10
9
  i,
11
- s
12
- ], b = {
13
- [n]: !0,
10
+ a,
11
+ c
12
+ ], O = {
14
13
  [o]: !0,
15
- [c]: !0,
16
- [a]: !0,
17
- [l]: !1,
14
+ [s]: !0,
15
+ [l]: !0,
16
+ [r]: !0,
18
17
  [i]: !1,
19
- [s]: !0
20
- }, p = `
18
+ [a]: !1,
19
+ [c]: !0
20
+ }, m = `
21
21
  <tr>
22
22
  <td class="spacer" style="height: 10px;"></td>
23
23
  </tr>
24
24
  `, d = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
25
- function R(t) {
25
+ function U(t) {
26
26
  return !t || typeof t != "string" || t.trim() === "" ? d : t.startsWith("http://") ? t.replace("http://", "https://") : t;
27
27
  }
28
28
  function T(t) {
@@ -40,19 +40,19 @@ function T(t) {
40
40
  category: []
41
41
  };
42
42
  }
43
- function D(t = 6) {
43
+ function A(t = 6) {
44
44
  return Array.from(
45
45
  { length: t },
46
- (e, r) => T(String(r + 1))
46
+ (e, n) => T(String(n + 1))
47
47
  );
48
48
  }
49
- function O(t = "grid", e) {
50
- const r = t === "list" ? `
51
- data-layout="list"` : "";
49
+ function I(t = "grid", e) {
50
+ const n = t === "list" ? `
51
+ data-layout="list"` : "", p = e ? ` ${e}` : "";
52
52
  return `
53
53
  <td
54
54
  align="left"
55
- class="ins-recommendation-v3-block-v2 esd-block-recommendation-v3-block es-p20${e ? ` ${e}` : ""}"${r}>
55
+ class="${`recommendation-block-v2 esd-block-recommendation-v3-block es-p20${t === "list" ? " es-m-p0 ins-recommendation-list-layout" : ""}${p}`}"${n}>
56
56
  <table width="100%" cellpadding="0" cellspacing="0" border="0">
57
57
  <tr>
58
58
  <td align="center">
@@ -84,7 +84,7 @@ function O(t = "grid", e) {
84
84
  </table>
85
85
  </td>
86
86
  </tr>
87
- ${p}
87
+ ${m}
88
88
  <tr>
89
89
  <td>
90
90
  <table
@@ -99,7 +99,7 @@ function O(t = "grid", e) {
99
99
  </table>
100
100
  </td>
101
101
  </tr>
102
- <tr>
102
+ <tr class="ins-recommendation-mobile-row"${t === "list" ? ' style="display: none;"' : ""}>
103
103
  <td>
104
104
  <table
105
105
  class="ins-recommendation-product-container
@@ -109,8 +109,8 @@ function O(t = "grid", e) {
109
109
  cellspacing="0"
110
110
  border="0"
111
111
  style="display: none;"
112
- >
113
- {-{-MOBILE_PRODUCT_ROWS-}-}
112
+ >${t === "list" ? "" : `
113
+ {-{-MOBILE_PRODUCT_ROWS-}-}`}
114
114
  </table>
115
115
  </td>
116
116
  </tr>
@@ -123,12 +123,12 @@ function O(t = "grid", e) {
123
123
  `;
124
124
  }
125
125
  export {
126
- g as DEFAULTS,
127
- u as DEFAULT_CARD_COMPOSITION,
128
- b as DEFAULT_CARD_VISIBILITY,
126
+ C as DEFAULTS,
127
+ D as DEFAULT_CARD_COMPOSITION,
128
+ O as DEFAULT_CARD_VISIBILITY,
129
129
  d as PLACEHOLDER_IMAGE,
130
- O as createBlockTemplate,
131
- D as getDefaultProducts,
132
- R as sanitizeImageUrl,
133
- p as spacer
130
+ I as createBlockTemplate,
131
+ A as getDefaultProducts,
132
+ U as sanitizeImageUrl,
133
+ m as spacer
134
134
  };
@@ -1,22 +1,22 @@
1
1
  function l(t) {
2
2
  if (t.length === 0)
3
3
  return "";
4
- const o = t.sort((r, e) => r.filterNumber - e.filterNumber), n = o.map((r) => `[${r.attribute}][${r.operatorReplace}][${r.value}]`), [i, ...p] = n;
5
- let u = i;
6
- for (let r = 0; r < p.length; r++) {
7
- const e = o[r + 1].innerGroupOperator;
8
- u += `${e}${p[r]}`;
4
+ const o = t.sort((r, e) => r.filterNumber - e.filterNumber), n = o.map((r) => `[${r.attribute}][${r.operator}][${r.value}]`), [p, ...i] = n;
5
+ let u = p;
6
+ for (let r = 0; r < i.length; r++) {
7
+ const e = o[r].innerGroupOperator;
8
+ u += `${e}${i[r]}`;
9
9
  }
10
10
  return `(${u})`;
11
11
  }
12
12
  function f(t) {
13
13
  if (!t || t.length === 0)
14
14
  return "";
15
- const o = t.reduce((r, e) => (r[e.filterGroup] || (r[e.filterGroup] = []), r[e.filterGroup].push(e), r), {}), n = Object.keys(o).map(Number).sort((r, e) => r - e), i = n.map((r) => {
15
+ const o = t.reduce((r, e) => (r[e.filterGroup] || (r[e.filterGroup] = []), r[e.filterGroup].push(e), r), {}), n = Object.keys(o).map(Number).sort((r, e) => r - e), p = n.map((r) => {
16
16
  const e = o[r];
17
17
  return l(e);
18
- }), [p, ...u] = i;
19
- let s = p;
18
+ }), [i, ...u] = p;
19
+ let s = i;
20
20
  for (let r = 0; r < u.length; r++) {
21
21
  const e = n[r + 1], c = o[e][0].outerGroupOperator;
22
22
  s += `${c}${u[r]}`;
@@ -0,0 +1,29 @@
1
+ import { safeParse as o, object as p, boolean as l, number as i, pipe as c, minLength as f, string as m } from "../../../../node_modules/valibot/dist/index.js";
2
+ const e = c(m(), f(1)), s = p({
3
+ type: e,
4
+ attribute: e,
5
+ operator: e,
6
+ innerGroupOperator: e,
7
+ outerGroupOperator: e,
8
+ value: e,
9
+ filterGroup: i(),
10
+ filterNumber: i(),
11
+ isValid: l()
12
+ });
13
+ function g(t) {
14
+ return o(s, t).success;
15
+ }
16
+ function S(t) {
17
+ const r = o(s, t);
18
+ return r.success ? /* @__PURE__ */ new Set() : new Set(
19
+ r.issues.flatMap((u) => {
20
+ var n;
21
+ return ((n = u.path) == null ? void 0 : n.map((a) => String(a.key))) ?? [];
22
+ })
23
+ );
24
+ }
25
+ export {
26
+ s as FilterSchema,
27
+ S as getInvalidFilterFields,
28
+ g as isFilterValid
29
+ };