@useinsider/guido 3.2.0 → 3.3.0

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 (144) hide show
  1. package/README.md +117 -1
  2. package/dist/@types/config/schemas.js +153 -95
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +90 -88
  5. package/dist/components/organisms/AutoSaveController.vue.js +17 -0
  6. package/dist/components/organisms/AutoSaveController.vue2.js +13 -0
  7. package/dist/components/organisms/header/AutoSaveToggle.vue.js +22 -0
  8. package/dist/components/organisms/header/AutoSaveToggle.vue2.js +19 -0
  9. package/dist/components/organisms/header/RightSlot.vue.js +8 -8
  10. package/dist/components/organisms/header/RightSlot.vue2.js +9 -8
  11. package/dist/components/organisms/onboarding/AMPOnboarding.vue2.js +51 -31
  12. package/dist/components/organisms/onboarding/GenericOnboarding.vue.js +1 -1
  13. package/dist/components/organisms/onboarding/GenericOnboarding.vue2.js +23 -22
  14. package/dist/components/organisms/onboarding/ItemsOnboarding.vue.js +1 -1
  15. package/dist/components/organisms/onboarding/ItemsOnboarding.vue2.js +37 -39
  16. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue.js +3 -3
  17. package/dist/components/organisms/onboarding/TextBlockOnboarding.vue2.js +30 -41
  18. package/dist/components/organisms/onboarding/VersionHistoryOnboarding.vue2.js +15 -14
  19. package/dist/composables/useActionsApi.js +4 -4
  20. package/dist/composables/useAutoSave.js +71 -0
  21. package/dist/composables/useFullStoryBridge.js +14 -0
  22. package/dist/composables/useRecommendation.js +46 -26
  23. package/dist/composables/useRibbonOffset.js +21 -0
  24. package/dist/composables/useSave.js +19 -16
  25. package/dist/composables/useStripo.js +40 -40
  26. package/dist/composables/validators/useCouponBlockValidator.js +24 -0
  27. package/dist/config/compiler/recommendationCompilerRules.js +79 -74
  28. package/dist/config/compiler/unsubscribeCompilerRules.js +40 -37
  29. package/dist/config/compiler/utils/recommendationCompilerUtils.js +107 -71
  30. package/dist/config/migrator/index.js +9 -9
  31. package/dist/config/migrator/radioButtonMigrator.js +64 -44
  32. package/dist/config/migrator/recommendation/compositionMapper.js +98 -0
  33. package/dist/config/migrator/recommendation/extractors.js +27 -0
  34. package/dist/config/migrator/recommendation/htmlBuilder.js +496 -0
  35. package/dist/config/migrator/recommendation/parseLegacyConfig.js +33 -0
  36. package/dist/config/migrator/recommendation/settingsMapper.js +70 -0
  37. package/dist/config/migrator/recommendation/themeMapper.js +93 -0
  38. package/dist/config/migrator/recommendationMigrator.js +74 -290
  39. package/dist/enums/extensions/recommendationBlock.js +2 -1
  40. package/dist/enums/onboarding.js +7 -2
  41. package/dist/enums/unsubscribe.js +34 -27
  42. package/dist/extensions/Blocks/Items/controls/price/singlePrice.js +38 -38
  43. package/dist/extensions/Blocks/Items/enums/productEnums.js +19 -7
  44. package/dist/extensions/Blocks/RadioButton/template.js +1 -1
  45. package/dist/extensions/Blocks/Recommendation/block.js +35 -32
  46. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  47. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +5 -5
  48. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +21 -18
  49. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +99 -0
  50. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +27 -26
  51. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +3 -1
  52. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +228 -181
  53. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +27 -57
  54. package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +14 -0
  55. package/dist/extensions/Blocks/Recommendation/services/configService.js +65 -29
  56. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +18 -17
  57. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +123 -79
  58. package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +19 -10
  59. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +8 -8
  60. package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +25 -15
  61. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +11 -11
  62. package/dist/extensions/Blocks/Recommendation/templates/utils.js +1 -1
  63. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +17 -14
  64. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMap.js +21 -0
  65. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +13 -22
  66. package/dist/extensions/Blocks/Unsubscribe/block.js +11 -11
  67. package/dist/guido.css +1 -1
  68. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +393 -264
  69. package/dist/node_modules/valibot/dist/index.js +450 -235
  70. package/dist/package.json.js +1 -1
  71. package/dist/services/templateLibraryApi.js +5 -4
  72. package/dist/src/@types/config/defaults.d.ts +5 -1
  73. package/dist/src/@types/config/index.d.ts +3 -3
  74. package/dist/src/@types/config/schemas.d.ts +217 -0
  75. package/dist/src/@types/config/types.d.ts +9 -1
  76. package/dist/src/components/Guido.vue.d.ts +1 -1
  77. package/dist/src/components/organisms/AutoSaveController.vue.d.ts +2 -0
  78. package/dist/src/components/organisms/header/AutoSaveToggle.vue.d.ts +2 -0
  79. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  80. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  81. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  82. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  83. package/dist/src/composables/useActionsApi.d.ts +1 -1
  84. package/dist/src/composables/useAutoSave.d.ts +3 -0
  85. package/dist/src/composables/useConfig.d.ts +58 -0
  86. package/dist/src/composables/useFullStoryBridge.d.ts +11 -0
  87. package/dist/src/composables/useRecommendation.d.ts +10 -1
  88. package/dist/src/composables/useRecommendation.test.d.ts +1 -0
  89. package/dist/src/composables/useRibbonOffset.d.ts +4 -0
  90. package/dist/src/composables/useSave.d.ts +1 -1
  91. package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
  92. package/dist/src/config/migrator/index.d.ts +2 -1
  93. package/dist/src/config/migrator/recommendation/compositionMapper.d.ts +2 -0
  94. package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +1 -0
  95. package/dist/src/config/migrator/recommendation/extractors.d.ts +7 -0
  96. package/dist/src/config/migrator/recommendation/extractors.test.d.ts +1 -0
  97. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +11 -0
  98. package/dist/src/config/migrator/recommendation/parseLegacyConfig.d.ts +15 -0
  99. package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +1 -0
  100. package/dist/src/config/migrator/recommendation/settingsMapper.d.ts +7 -0
  101. package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +1 -0
  102. package/dist/src/config/migrator/recommendation/themeMapper.d.ts +5 -0
  103. package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +1 -0
  104. package/dist/src/config/migrator/recommendation/types.d.ts +205 -0
  105. package/dist/src/config/migrator/recommendationMigrator.d.ts +13 -1
  106. package/dist/src/config/migrator/recommendationMigrator.test.d.ts +1 -0
  107. package/dist/src/enums/onboarding.d.ts +6 -0
  108. package/dist/src/enums/unsubscribe.d.ts +5 -0
  109. package/dist/src/extensions/Blocks/RadioButton/template.d.ts +1 -1
  110. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  111. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +3 -0
  112. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +35 -0
  113. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +1 -0
  114. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +3 -20
  115. package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +29 -0
  116. package/dist/src/extensions/Blocks/Recommendation/services/configService.d.ts +10 -0
  117. package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +1 -0
  118. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +34 -0
  119. package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +1 -1
  120. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.d.ts +21 -0
  121. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +1 -0
  122. package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -3
  123. package/dist/src/library.d.ts +1 -1
  124. package/dist/src/stores/autosave.d.ts +12 -0
  125. package/dist/src/stores/config.d.ts +522 -0
  126. package/dist/src/stores/editor.d.ts +23 -0
  127. package/dist/src/stores/onboarding.d.ts +4 -0
  128. package/dist/src/utils/htmlEscape.d.ts +5 -0
  129. package/dist/src/utils/htmlEscape.test.d.ts +1 -0
  130. package/dist/src/utils/timeUtil.d.ts +8 -0
  131. package/dist/static/styles/components/button.css.js +16 -9
  132. package/dist/static/styles/components/loader.css.js +4 -0
  133. package/dist/static/styles/components/narrow-panel.css.js +52 -0
  134. package/dist/stores/autosave.js +17 -0
  135. package/dist/stores/editor.js +3 -1
  136. package/dist/stores/onboarding.js +4 -0
  137. package/dist/utils/htmlEscape.js +13 -0
  138. package/dist/utils/pairProductVariables.js +89 -88
  139. package/dist/utils/templatePreparation.js +72 -32
  140. package/dist/utils/timeUtil.js +19 -0
  141. package/package.json +7 -3
  142. package/dist/enums/displayConditions.js +0 -80
  143. package/dist/extensions/Blocks/Recommendation/templates/grid/migration.js +0 -251
  144. package/dist/src/enums/displayConditions.d.ts +0 -2
@@ -1,27 +1,27 @@
1
- import { useActionsApi as F } from "./useActionsApi.js";
2
- import { useBlocksConfig as D } from "./useBlocksConfig.js";
3
- import { useConfig as I } from "./useConfig.js";
4
- import { useCustomInterfaceAppearance as P } from "./useCustomInterfaceAppearance.js";
5
- import { useStripoEventHandler as U } from "./useStripoEventHandler.js";
6
- import { useToaster as R } from "./useToaster.js";
7
- import { localePatch as q } from "../config/i18n/index.js";
8
- import { displayConditions as x } from "../enums/displayConditions.js";
9
- import { useStripoApi as H } from "../services/stripoApi.js";
10
- import O from "../static/styles/customEditorStyle.css.js";
11
- import { useEditorStore as C } from "../stores/editor.js";
1
+ import { useActionsApi as D } from "./useActionsApi.js";
2
+ import { useBlocksConfig as I } from "./useBlocksConfig.js";
3
+ import { useConfig as P } from "./useConfig.js";
4
+ import { useCustomInterfaceAppearance as U } from "./useCustomInterfaceAppearance.js";
5
+ import { useFullStoryBridge as R } from "./useFullStoryBridge.js";
6
+ import { useStripoEventHandler as q } from "./useStripoEventHandler.js";
7
+ import { useToaster as x } from "./useToaster.js";
8
+ import { localePatch as H } from "../config/i18n/index.js";
9
+ import { useStripoApi as O } from "../services/stripoApi.js";
10
+ import j from "../static/styles/customEditorStyle.css.js";
11
+ import { useEditorStore as E } from "../stores/editor.js";
12
12
  import { dynamicContentToMergeTags as L } from "../utils/genericUtil.js";
13
13
  import $ from "../package.json.js";
14
- const ie = (E, c) => {
15
- const { features: l, template: h, isFeatureEnabled: u } = I(), { handleError: m } = R(), { getToken: b, getCustomFonts: w, getSyncModulesStatus: k } = H(), { handleEvent: T } = U(), { getStripoBlocksConfig: V } = D(), _ = async (i, n = [], r = !1) => {
16
- var g, y, S;
17
- const e = C(), { html: p, css: a } = i, { baseBlocks: o, extensions: d } = await V(), f = ((g = l.value) == null ? void 0 : g.displayConditions) ?? !0, v = ((y = l.value) == null ? void 0 : y.modulesDisabled) ?? !1, M = ((S = h.value) == null ? void 0 : S.forceRecreate) ?? !1;
14
+ const se = (C, l) => {
15
+ const { features: c, template: h, isFeatureEnabled: u } = P(), { handleError: m } = x(), { getToken: w, getCustomFonts: b, getSyncModulesStatus: k } = O(), { handleEvent: B } = q(), { getStripoBlocksConfig: T } = I(), V = async (i, r = [], s = !1) => {
16
+ var g, S, y;
17
+ const e = E(), { html: p, css: a } = i, { baseBlocks: o, extensions: d } = await T(), f = ((g = c.value) == null ? void 0 : g.displayConditions) ?? !0, F = ((S = c.value) == null ? void 0 : S.modulesDisabled) ?? !1, v = ((y = h.value) == null ? void 0 : y.forceRecreate) ?? !1;
18
18
  window.UIEditor.initEditor(
19
19
  document.querySelector("#guido-editor"),
20
20
  {
21
- metadata: E,
21
+ metadata: C,
22
22
  html: p,
23
23
  css: a,
24
- forceRecreate: M,
24
+ forceRecreate: v,
25
25
  locale: "en",
26
26
  undoButtonSelector: "#guido__undo-button",
27
27
  redoButtonSelector: "#guido__redo-button",
@@ -31,45 +31,45 @@ const ie = (E, c) => {
31
31
  customAppearanceMergetags: !u("liquidSyntax"),
32
32
  customAppearanceMergetagsBorderColor: "#f1f3fe",
33
33
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
34
- customViewStyles: O,
34
+ customViewStyles: j,
35
35
  conditionsEnabled: f,
36
36
  customConditionsEnabled: f,
37
- conditionCategories: x,
38
37
  enableXSSSecurity: !0,
39
- modulesDisabled: v,
40
- syncModulesEnabled: r,
38
+ modulesDisabled: F,
39
+ syncModulesEnabled: s,
41
40
  messageSettingsEnabled: !0,
42
41
  displayGmailAnnotations: !0,
43
42
  displayHiddenPreheader: !1,
44
43
  displayTitle: !1,
45
44
  displayUTM: !1,
46
45
  selectElementAfterDrop: !0,
46
+ allowedScriptSourceDomains: "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com",
47
47
  ...o ? { baseBlocks: o } : {},
48
48
  editorFonts: {
49
49
  showDefaultStandardFonts: !0,
50
50
  showDefaultNotStandardFonts: !0,
51
- customFonts: n
51
+ customFonts: r
52
52
  },
53
53
  mergeTags: [
54
54
  {
55
55
  entries: L(
56
- c.preselectedDynamicContentList,
56
+ l.preselectedDynamicContentList,
57
57
  u("liquidSyntax")
58
58
  )
59
59
  }
60
60
  ],
61
61
  async onTokenRefreshRequest(t) {
62
62
  try {
63
- const s = await b();
64
- t(s);
65
- } catch (s) {
66
- m(s, "Failed to refresh token");
63
+ const n = await w();
64
+ t(n);
65
+ } catch (n) {
66
+ m(n, "Failed to refresh token");
67
67
  }
68
68
  },
69
69
  onTemplateLoaded() {
70
70
  try {
71
- const { importCss: t } = P(), { activateCustomViewStyles: s, updateTimerInClonedTemplate: A } = F();
72
- t(), s(), A(), c.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
71
+ const { importCss: t } = U(), { activateCustomViewStyles: n, updateTimerInClonedTemplate: M } = D(), { injectFullStory: A } = R();
72
+ t(), n(), A(), M(), l.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
73
73
  e.hasChanges = !1;
74
74
  }, 1e3);
75
75
  } catch (t) {
@@ -88,39 +88,39 @@ const ie = (E, c) => {
88
88
  onDataChanged() {
89
89
  e.hasChanges = !0;
90
90
  },
91
- onEvent: T,
91
+ onEvent: B,
92
92
  ignoreClickOutsideSelectors: [
93
93
  "#guido-dynamic-content-modal",
94
94
  ".in-on-board-wrapper",
95
95
  ".in-drawer__container"
96
96
  ],
97
97
  extensions: d,
98
- localePatch: q
98
+ localePatch: H
99
99
  }
100
100
  );
101
- }, B = (i) => new Promise((n, r) => {
101
+ }, _ = (i) => new Promise((r, s) => {
102
102
  var d;
103
103
  if (document.getElementById("UiEditorScript")) {
104
- i(), n();
104
+ i(), r();
105
105
  return;
106
106
  }
107
107
  const e = $.guido, a = `https://email-static.useinsider.com/guido/${(d = e == null ? void 0 : e.stripo) == null ? void 0 : d.version}/UIEditor.js`, o = document.createElement("script");
108
108
  o.id = "UiEditorScript", o.type = "module", o.src = a, o.onload = () => {
109
- i(), n();
109
+ i(), r();
110
110
  }, o.onerror = () => {
111
- r(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
111
+ s(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
112
112
  }, document.body.appendChild(o);
113
113
  });
114
114
  return { initPlugin: async (i) => {
115
- await B(async () => {
116
- const n = C(), [r, e] = await Promise.all([
117
- w(),
115
+ await _(async () => {
116
+ const r = E(), [s, e] = await Promise.all([
117
+ b(),
118
118
  k()
119
119
  ]);
120
- n.syncModulesEnabled = e, await _(i, r, e);
120
+ r.syncModulesEnabled = e, await V(i, s, e);
121
121
  });
122
122
  } };
123
123
  };
124
124
  export {
125
- ie as useStripo
125
+ se as useStripo
126
126
  };
@@ -0,0 +1,24 @@
1
+ import { ToasterTypeOptions as c } from "../../enums/toaster.js";
2
+ import { COUPON_PLACEHOLDER_DEFAULT as i, COUPON_PLACEHOLDER_LIQUID as l } from "../../extensions/Blocks/CouponBlock/template.js";
3
+ import { useToaster as m } from "../useToaster.js";
4
+ import { useTranslations as p } from "../useTranslations.js";
5
+ const u = /* @__PURE__ */ new Set([
6
+ i,
7
+ l
8
+ ]), A = () => {
9
+ const { showToaster: t } = m(), r = p();
10
+ return { validateCouponBlockTags: (e) => {
11
+ const n = new DOMParser().parseFromString(e, "text/html");
12
+ return Array.from(n.querySelectorAll(".coupon-block")).find((s) => {
13
+ var o;
14
+ const a = ((o = s.textContent) == null ? void 0 : o.trim()) ?? "";
15
+ return !u.has(a);
16
+ }) ? (t({
17
+ type: c.Warning,
18
+ message: r("newsletter.coupon-tag-modified")
19
+ }), !1) : !0;
20
+ } };
21
+ };
22
+ export {
23
+ A as useCouponBlockValidator
24
+ };
@@ -1,16 +1,16 @@
1
- import { useRecommendation as N } from "../../composables/useRecommendation.js";
2
- import { DUMMY_IMAGE_MAPPINGS as C, REGEX as T, VerticalOrientation as M, CSS as E, ATTRIBUTES as R, CONDITIONS as $, HTML as h } from "../../enums/recommendation.js";
1
+ import { useRecommendation as C } from "../../composables/useRecommendation.js";
2
+ import { DUMMY_IMAGE_MAPPINGS as y, REGEX as T, VerticalOrientation as M, CSS as E, ATTRIBUTES as A, CONDITIONS as g, HTML as N } from "../../enums/recommendation.js";
3
3
  import { prepareRecommendationBlocks as x } from "./utils/recommendationCompilerUtils.js";
4
4
  const w = [
5
5
  {
6
6
  id: "replace-images-with-variable-names",
7
7
  description: "Replacing dummy images with variable names in recommendation module",
8
8
  type: "custom",
9
- processor: (i) => {
10
- let e = i;
11
- return Object.entries(C).forEach(([, p]) => {
12
- Object.entries(p).forEach(([c, n]) => {
13
- e = e.replaceAll(n, `{{${c}}}`);
9
+ processor: (c) => {
10
+ let e = c;
11
+ return Object.entries(y).forEach(([, l]) => {
12
+ Object.entries(l).forEach(([n, s]) => {
13
+ e = e.replaceAll(s, `{{${n}}}`);
14
14
  });
15
15
  }), e;
16
16
  },
@@ -29,21 +29,21 @@ const w = [
29
29
  id: "add-recommendation-unresponsive-css",
30
30
  description: "Adding recommendation unresponsive css",
31
31
  type: "custom",
32
- processor: (i) => {
33
- const { calculateCardWidth: e, getRecommendationCampaignData: p } = N();
34
- let c = i;
35
- const n = c.match(T.ID);
36
- if (n) {
32
+ processor: (c) => {
33
+ const { calculateCardWidth: e, getRecommendationCampaignData: l } = C();
34
+ let n = c;
35
+ const s = n.match(T.ID);
36
+ if (s) {
37
37
  const a = [];
38
- if (n.forEach((s) => {
39
- const d = /recommendation-id="(.*?)"/i.exec(s), _ = d ? d[1].trim() : "", A = p(_);
40
- A.textTrimming && A.orientation === M && a.push(e(A));
38
+ if (s.forEach((i) => {
39
+ const u = /recommendation-id="(.*?)"/i.exec(i), _ = u ? u[1].trim() : "", R = l(_);
40
+ R.textTrimming && R.orientation === M && a.push(e(R));
41
41
  }), a.length) {
42
- const s = `width:${Math.min(...a)}px!important;`;
43
- c = c.replace(E.REGULAR_NAME_HEIGHT, `${E.TRIMMED_NAME_HEIGHT} ${s} ${E.ELLIPSIS}`).replace(E.REGULAR_NAME_CONTAINER_HEIGHT, E.TRIMMED_NAME_CONTAINER_CSS).replace(E.RESPONSIVE_NAME_SIZE, `${E.RESPONSIVE_NAME_HEIGHT} ${s} ${E.ELLIPSIS}`).replace(E.RESPONSIVE_NAME_CONTAINER_HEIGHT, E.TRIMMED_RESPONSIVE_NAME_CONTAINER_CSS);
42
+ const i = `width:${Math.min(...a)}px!important;`;
43
+ n = n.replace(E.REGULAR_NAME_HEIGHT, `${E.TRIMMED_NAME_HEIGHT} ${i} ${E.ELLIPSIS}`).replace(E.REGULAR_NAME_CONTAINER_HEIGHT, E.TRIMMED_NAME_CONTAINER_CSS).replace(E.RESPONSIVE_NAME_SIZE, `${E.RESPONSIVE_NAME_HEIGHT} ${i} ${E.ELLIPSIS}`).replace(E.RESPONSIVE_NAME_CONTAINER_HEIGHT, E.TRIMMED_RESPONSIVE_NAME_CONTAINER_CSS);
44
44
  }
45
45
  }
46
- return c;
46
+ return n;
47
47
  },
48
48
  priority: 52
49
49
  },
@@ -51,34 +51,34 @@ const w = [
51
51
  id: "prepare-recommendations",
52
52
  description: "Replacing product data with template variables in recommendation blocks",
53
53
  type: "custom",
54
- processor: (i) => x(i),
54
+ processor: (c) => x(c),
55
55
  priority: 48
56
56
  },
57
57
  {
58
58
  id: "add-discount-conditions",
59
59
  description: "Adding discount conditions to the recommendation block",
60
60
  type: "custom",
61
- processor: (i) => {
62
- let e = i;
63
- const p = e.match(T.ATTRIBUTE_PARAGRAPH), { getRecommendationCampaignData: c } = N();
64
- return p !== null && p.forEach((n) => {
65
- const a = n.match(T.CUSTOM_FIELD);
61
+ processor: (c) => {
62
+ let e = c;
63
+ const l = e.match(T.ATTRIBUTE_PARAGRAPH), { getRecommendationCampaignData: n } = C();
64
+ return l !== null && l.forEach((s) => {
65
+ const a = s.match(T.CUSTOM_FIELD);
66
66
  if (!a)
67
67
  return;
68
- const [s] = a, d = s.match(T.CUSTOM_FIELD_INDEXES_PART), _ = s.match(T.CUSTOM_FIELD_NAME_PART), A = n.match(T.ATTRIBUTE_PARAGRAPH_START_TAG);
69
- if (!d || !_ || !A)
68
+ const [i] = a, u = i.match(T.CUSTOM_FIELD_INDEXES_PART), _ = i.match(T.CUSTOM_FIELD_NAME_PART), R = s.match(T.ATTRIBUTE_PARAGRAPH_START_TAG);
69
+ if (!u || !_ || !R)
70
70
  return;
71
- const [I] = d, [S] = _, [m] = A, o = S.substring(1, S.length - 2), r = m.match(T.COMPOSITION) !== null;
72
- let t = s;
71
+ const [S] = u, [b] = _, [d] = R, o = b.substring(1, b.length - 2), r = d.match(T.COMPOSITION) !== null;
72
+ let t = i;
73
73
  if (r) {
74
- const b = I.substring(2, I.length - 3), l = c(b);
75
- o === R.OMNIBUS_PRICE && (l.priceBeforeTextValue && (t = `${l.priceBeforeTextValue}${t}`), l.priceAfterTextValue && (t = `${t}${l.priceAfterTextValue}`)), o === R.OMNIBUS_DISCOUNT && (l.discountBeforeTextValue && (t = `${l.discountBeforeTextValue}${t}`), l.discountAfterTextValue && (t = `${t}${l.discountAfterTextValue}`));
74
+ const I = S.substring(2, S.length - 3), m = n(I);
75
+ o === A.OMNIBUS_PRICE && (m.priceBeforeTextValue && (t = `${m.priceBeforeTextValue}${t}`), m.priceAfterTextValue && (t = `${t}${m.priceAfterTextValue}`)), o === A.OMNIBUS_DISCOUNT && (m.discountBeforeTextValue && (t = `${m.discountBeforeTextValue}${t}`), m.discountAfterTextValue && (t = `${t}${m.discountAfterTextValue}`));
76
76
  }
77
- const u = I.substring(2);
77
+ const p = S.substring(2);
78
78
  let f = "";
79
- o in $.IF && (f = $.IF[o].replaceAll(`{${R.DISCOUNT}}`, `${u}${R.DISCOUNT}`).replaceAll(`{${R.OMNIBUS_DISCOUNT}}`, `${u}${R.OMNIBUS_DISCOUNT}`).replaceAll(`{${R.OMNIBUS_PRICE}}`, `${u}${R.OMNIBUS_PRICE}`));
80
- const g = `${m}${t}${h.PARAGRAPH_END_TAG}`, y = `${f}${r ? g : n}${$.ELSE}${m}${h.PARAGRAPH_END_TAG}${$.END_IF}`;
81
- e = e.replace(n, y);
79
+ o in g.IF && (f = g.IF[o].replaceAll(`{${A.DISCOUNT}}`, `${p}${A.DISCOUNT}`).replaceAll(`{${A.OMNIBUS_DISCOUNT}}`, `${p}${A.OMNIBUS_DISCOUNT}`).replaceAll(`{${A.OMNIBUS_PRICE}}`, `${p}${A.OMNIBUS_PRICE}`));
80
+ const $ = `${d}${t}${N.PARAGRAPH_END_TAG}`, h = `${f}${r ? $ : s}${g.ELSE}${d}${N.PARAGRAPH_END_TAG}${g.END_IF}`;
81
+ e = e.replace(s, h);
82
82
  }), e;
83
83
  },
84
84
  priority: 53
@@ -95,19 +95,24 @@ const w = [
95
95
  {
96
96
  id: "strip-recommendation-editor-attributes",
97
97
  description: "Strip editor-only attributes from compiled recommendation output",
98
- type: "regex",
99
- // eslint-disable-next-line @stylistic/max-len
100
- pattern: '\\s+(?:esd-extension-block-id|data-attribute-type|data-visibility|data-text-before|data-text-after|product-attr|composition)="[^"]*"',
101
- replacement: "",
102
- flags: "g",
98
+ type: "custom",
99
+ // Scoped to REC_START/REC_END markers so it cannot strip `product-attr`
100
+ // from Items block elements, which the items compiler rule depends on.
101
+ processor: (c) => {
102
+ const e = /\s+(?:esd-extension-block-id|data-attribute-type|data-visibility|data-text-before|data-text-after|product-attr|composition)="[^"]*"/g;
103
+ return c.replace(
104
+ /<!--REC_START-->([\s\S]*?)<!--REC_END-->/g,
105
+ (l, n) => `<!--REC_START-->${n.replace(e, "")}<!--REC_END-->`
106
+ );
107
+ },
103
108
  priority: 55
104
109
  },
105
110
  {
106
111
  id: "strip-unused-recommendation-classes",
107
112
  description: "Remove CSS classes not referenced by any style rule from recommendation elements",
108
113
  type: "custom",
109
- processor: (i) => {
110
- let e = i.replace(
114
+ processor: (c) => {
115
+ let e = c.replace(
111
116
  / class="(?:product-card-segment|attribute-cell|recommendation-attribute-row|product-image|product-name|product-price|product-old-price|product-omnibus-price|product-omnibus-discount|product-button|recommendation-product-row|product-card-wrapper)"/g,
112
117
  ""
113
118
  );
@@ -119,8 +124,8 @@ const w = [
119
124
  id: "remove-empty-mobile-layout-artifacts",
120
125
  description: "Remove empty mobile container rows and unused mobile layout CSS",
121
126
  type: "custom",
122
- processor: (i) => {
123
- let e = i;
127
+ processor: (c) => {
128
+ let e = c;
124
129
  return e = e.replace(
125
130
  /<tr[^>]*class="ins-recommendation-mobile-row"[^>]*><\/tr>/g,
126
131
  ""
@@ -129,9 +134,9 @@ const w = [
129
134
  ""
130
135
  ), e = e.replace(
131
136
  /@media[^{]*max-width\s*:\s*480px[^{]*\{((?:[^{}]*\{[^{}]*\})*[^{}]*)\}/g,
132
- (p, c) => {
133
- const n = c.match(/[^{}]+\{[^{}]*\}/g) || [], a = /ins-recommendation|product-image-cell|button-cell|product-info-cell/;
134
- return n.every((d) => a.test(d)) ? "" : p;
137
+ (l, n) => {
138
+ const s = n.match(/[^{}]+\{[^{}]*\}/g) || [], a = /ins-recommendation|product-image-cell|button-cell|product-info-cell/;
139
+ return s.every((u) => a.test(u)) ? "" : l;
135
140
  }
136
141
  )), e;
137
142
  },
@@ -141,59 +146,59 @@ const w = [
141
146
  id: "deduplicate-inline-styles",
142
147
  description: "Replace repeated inline styles with CSS class references within recommendation blocks",
143
148
  type: "custom",
144
- processor: (i) => {
145
- const e = i.replace(
149
+ processor: (c) => {
150
+ const e = c.replace(
146
151
  /<a\b[^>]*\bes-button\b[^>]*>/g,
147
152
  (o) => o.replace(
148
153
  /([;"]color:)([^;"]+)/g,
149
- (r, t, u) => u.includes("!important") ? r : `${t}${u} !important`
154
+ (r, t, p) => p.includes("!important") ? r : `${t}${p} !important`
150
155
  )
151
- ), p = /<!--REC_START-->([\s\S]*?)<!--REC_END-->/g, c = / style="([^"]*)"/g, n = /* @__PURE__ */ new Map();
152
- let a = p.exec(e);
156
+ ), l = /<!--REC_START-->([\s\S]*?)<!--REC_END-->/g, n = / style="([^"]*)"/g, s = /* @__PURE__ */ new Map();
157
+ let a = l.exec(e);
153
158
  for (; a !== null; ) {
154
- let o = c.exec(a[1]);
159
+ let o = n.exec(a[1]);
155
160
  for (; o !== null; ) {
156
161
  const [, r] = o;
157
- n.set(r, (n.get(r) || 0) + 1), o = c.exec(a[1]);
162
+ s.set(r, (s.get(r) || 0) + 1), o = n.exec(a[1]);
158
163
  }
159
- c.lastIndex = 0, a = p.exec(e);
164
+ n.lastIndex = 0, a = l.exec(e);
160
165
  }
161
- const s = /* @__PURE__ */ new Map(), d = [];
166
+ const i = /* @__PURE__ */ new Map(), u = [];
162
167
  let _ = 0;
163
- if (n.forEach((o, r) => {
164
- if (o >= 6) {
165
- const t = `rc${_++}`;
166
- s.set(r, t), d.push(`.${t}{${r}}`);
168
+ if (s.forEach((o, r) => {
169
+ if (!r.includes("v-text-anchor") && o >= 6) {
170
+ const t = `rc${_++}`, p = r.endsWith(";") ? r : `${r};`;
171
+ i.set(r, t), u.push(`.${t}{${p}}`);
167
172
  }
168
- }), s.size === 0) {
173
+ }), i.size === 0) {
169
174
  let o = e;
170
175
  return o = o.replaceAll("<!--REC_START-->", ""), o = o.replaceAll("<!--REC_END-->", ""), o;
171
176
  }
172
- const A = (o) => o.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), I = (o, r) => `${o.slice(0, -1)} ${r}"`, S = /* @__PURE__ */ new Map();
173
- s.forEach((o, r) => {
174
- const t = A(r);
175
- S.set(r, {
177
+ const R = (o) => o.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), S = (o, r) => `${o.slice(0, -1)} ${r}"`, b = /* @__PURE__ */ new Map();
178
+ i.forEach((o, r) => {
179
+ const t = R(r);
180
+ b.set(r, {
176
181
  caseA: new RegExp(`(class="[^"]*")((?:[^>]*?)) style="${t}"`, "g"),
177
182
  caseB: new RegExp(` style="${t}"((?:[^>]*?))(class="[^"]*")`, "g")
178
183
  });
179
184
  });
180
- let m = e.replace("</style>", `${d.join("")}</style>`);
181
- return m = m.replace(
185
+ let d = e.replace("</style>", `${u.join("")}</style>`);
186
+ return d = d.replace(
182
187
  /<!--REC_START-->([\s\S]*?)<!--REC_END-->/g,
183
188
  (o, r) => {
184
189
  let t = r;
185
- return s.forEach((u, f) => {
186
- const g = S.get(f);
190
+ return i.forEach((p, f) => {
191
+ const $ = b.get(f);
187
192
  t = t.replace(
188
- g.caseA,
189
- (y, b, l) => I(b, u) + l
193
+ $.caseA,
194
+ (h, I, m) => S(I, p) + m
190
195
  ), t = t.replace(
191
- g.caseB,
192
- (y, b, l) => b + I(l, u)
193
- ), t = t.replaceAll(` style="${f}"`, ` class="${u}"`);
196
+ $.caseB,
197
+ (h, I, m) => I + S(m, p)
198
+ ), t = t.replaceAll(` style="${f}"`, ` class="${p}"`);
194
199
  }), t;
195
200
  }
196
- ), m = m.replaceAll("<!--REC_START-->", ""), m = m.replaceAll("<!--REC_END-->", ""), m;
201
+ ), d = d.replaceAll("<!--REC_START-->", ""), d = d.replaceAll("<!--REC_END-->", ""), d;
197
202
  },
198
203
  priority: 58
199
204
  }
@@ -1,41 +1,44 @@
1
- import { usePartner as y } from "../../composables/usePartner.js";
2
- import { LINK_REGEXES as p, LINK_TYPES as S, INSIDER_ID as m, URLS as R } from "../../enums/unsubscribe.js";
3
- import { parsePageList as I } from "../../extensions/Blocks/Unsubscribe/utils/utils.js";
4
- import { useConfigStore as N } from "../../stores/config.js";
5
- import { useDynamicContentStore as U } from "../../stores/dynamic-content.js";
6
- import { useUnsubscribeStore as C } from "../../stores/unsubscribe.js";
7
- const G = [
1
+ import { usePartner as U } from "../../composables/usePartner.js";
2
+ import { LINK_REGEXES as p, PRODUCT_TYPE_URL_SEGMENTS as R, LINK_TYPES as _, INSIDER_ID as m, URLS as y } from "../../enums/unsubscribe.js";
3
+ import { parsePageList as N } from "../../extensions/Blocks/Unsubscribe/utils/utils.js";
4
+ import { useConfigStore as C } from "../../stores/config.js";
5
+ import { useDynamicContentStore as L } from "../../stores/dynamic-content.js";
6
+ import { useUnsubscribeStore as P } from "../../stores/unsubscribe.js";
7
+ import { ProductType as B } from "../../@types/config/schemas.js";
8
+ import "../../@types/config/defaults.js";
9
+ const F = [
8
10
  {
9
11
  id: "add-unsubscribe-link-values",
10
12
  description: "Adding unsubscribe link values",
11
13
  type: "custom",
12
- processor: (t) => {
13
- const { getPartnerName: i } = y(), o = N(), s = U(), d = C(), a = o.variationId;
14
- if (!a)
15
- return t;
16
- let e = t;
17
- const r = `/${i()}/email/${a}?user={{iid}}`, E = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".unsubscribe-block-v2[data-unsubscribe-page-list]");
18
- let c = !1, l = !1;
19
- return E.forEach((f) => {
20
- var b;
21
- const u = f.getAttribute("data-unsubscribe-page-list");
14
+ processor: (s) => {
15
+ const { getPartnerName: i } = U(), n = C(), t = L(), E = P(), c = n.variationId;
16
+ if (!c)
17
+ return s;
18
+ const r = R[n.productType] ?? R[B.EMAIL];
19
+ let e = s;
20
+ const d = `/${i()}/${r}/${c}?user={{iid}}`, f = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".unsubscribe-block-v2[data-unsubscribe-page-list]");
21
+ let a = !1, l = !1;
22
+ return f.forEach((g) => {
23
+ var S;
24
+ const u = g.getAttribute("data-unsubscribe-page-list");
22
25
  if (!u)
23
26
  return;
24
- const _ = I(u), g = ((b = d.templates) == null ? void 0 : b.filter(
25
- (n) => _.includes(n.id)
27
+ const I = N(u), b = ((S = E.templates) == null ? void 0 : S.filter(
28
+ (o) => I.includes(o.id)
26
29
  )) ?? [];
27
- c = c || g.some((n) => n.type === S.UNSUBSCRIBE_LINK_TYPE), l = l || g.some((n) => n.type === S.PREFERENCES_LINK_TYPE);
28
- }), (c || l) && (s.selectedDynamicContentList.some((u) => u.value === m) || s.selectedDynamicContentList.push({
30
+ a = a || b.some((o) => o.type === _.UNSUBSCRIBE_LINK_TYPE), l = l || b.some((o) => o.type === _.PREFERENCES_LINK_TYPE);
31
+ }), (a || l) && (t.selectedDynamicContentList.some((u) => u.value === m) || t.selectedDynamicContentList.push({
29
32
  text: m,
30
33
  value: m,
31
34
  fallback: ""
32
- })), c && (e = e.replace(
35
+ })), a && (e = e.replace(
33
36
  p.GLOBAL_UNSUBSCRIBE_LINK_REGEX,
34
- R.UNSUBSCRIBE_URL + r
37
+ y.UNSUBSCRIBE_URL + d
35
38
  )), l && (e = e.replace(
36
39
  p.PREFERENCES_UNSUBSCRIBE_LINK_REGEX,
37
- R.PREFERENCES_URL + r
38
- )), E.length && (e = e.replace(p.UNSUBSCRIBE_LINK_REGEX, "")), e;
40
+ y.PREFERENCES_URL + d
41
+ )), f.length && (e = e.replace(p.UNSUBSCRIBE_LINK_REGEX, "")), e;
39
42
  },
40
43
  priority: 60
41
44
  },
@@ -52,25 +55,25 @@ const G = [
52
55
  id: "format-comment-braces",
53
56
  description: "Adding spaces around comment braces for proper formatting",
54
57
  type: "custom",
55
- processor: (t) => t.replace(/{#/g, "{ #").replace(/#}/g, "# }"),
58
+ processor: (s) => s.replace(/{#/g, "{ #").replace(/#}/g, "# }"),
56
59
  priority: 62
57
60
  },
58
61
  {
59
62
  id: "add-universal-link-flags",
60
63
  description: "Adding universal link flags",
61
64
  type: "custom",
62
- processor: (t) => {
63
- let i = t;
64
- const o = i.match(/<a[^>]+>(.*?)<\/a>/gm);
65
- return o && o.forEach((s) => {
66
- if (s.includes("insEmail=1"))
65
+ processor: (s) => {
66
+ let i = s;
67
+ const n = i.match(/<a[^>]+>(.*?)<\/a>/gm);
68
+ return n && n.forEach((t) => {
69
+ if (t.includes("insEmail=1"))
67
70
  return;
68
- if (s.match(/<a\s+(?:[^>]*?\s+)?href=(["'`”])(.*?)\1\s+(?:[^>]*?\s+)?universal=(["'`”])true\3/gm)) {
69
- const a = s.replace(/href=(["'`”])(.*?)\1/gm, (e) => {
70
- const r = e.slice(6, e.length - 1).trim();
71
- return e.includes("?") || e.includes("#") ? r.slice(-1) === "&" ? e.replace(r, `${r}insEmail=1`) : e.replace(r, `${r}&insEmail=1`) : e.replace(r, `${r}?insEmail=1`);
71
+ if (t.match(/<a\s+(?:[^>]*?\s+)?href=(["'`”])(.*?)\1\s+(?:[^>]*?\s+)?universal=(["'`”])true\3/gm)) {
72
+ const c = t.replace(/href=(["'`”])(.*?)\1/gm, (r) => {
73
+ const e = r.slice(6, r.length - 1).trim();
74
+ return r.includes("?") || r.includes("#") ? e.slice(-1) === "&" ? r.replace(e, `${e}insEmail=1`) : r.replace(e, `${e}&insEmail=1`) : r.replace(e, `${e}?insEmail=1`);
72
75
  });
73
- i = i.replace(s, a);
76
+ i = i.replace(t, c);
74
77
  }
75
78
  }), i;
76
79
  },
@@ -78,5 +81,5 @@ const G = [
78
81
  }
79
82
  ];
80
83
  export {
81
- G as unsubscribeCompilerRules
84
+ F as unsubscribeCompilerRules
82
85
  };