@useinsider/guido 3.20.2-beta.87fb8ae → 3.21.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 (48) hide show
  1. package/dist/components/Guido.vue.js +1 -1
  2. package/dist/components/Guido.vue2.js +65 -64
  3. package/dist/components/organisms/AutoSaveController.vue2.js +10 -9
  4. package/dist/components/organisms/header/EditorActions.vue.js +4 -4
  5. package/dist/components/organisms/header/EditorActions.vue2.js +53 -51
  6. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +3 -3
  7. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +23 -22
  8. package/dist/composables/useAutoSave.js +46 -44
  9. package/dist/composables/useSave.js +26 -23
  10. package/dist/composables/useSaveValidation.js +113 -114
  11. package/dist/composables/useSaveValidationRollout.js +17 -6
  12. package/dist/composables/useStripo.js +4 -3
  13. package/dist/extensions/Blocks/Items/block.js +43 -42
  14. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +9 -5
  15. package/dist/extensions/Blocks/Unsubscribe/block.js +70 -75
  16. package/dist/guido.css +1 -1
  17. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +271 -192
  18. package/dist/package.json.js +1 -1
  19. package/dist/services/settingsApi.js +11 -0
  20. package/dist/src/components/Guido.vue.d.ts +1 -1
  21. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  22. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  23. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  24. package/dist/src/composables/useAutoSave.d.ts +4 -1
  25. package/dist/src/composables/useSaveValidationRollout.d.ts +1 -0
  26. package/dist/src/extensions/Blocks/Checkbox/controls/blockBackground/index.d.ts +1 -0
  27. package/dist/src/extensions/Blocks/CouponBlock/controls/index.d.ts +8 -0
  28. package/dist/src/extensions/Blocks/Items/controls/index.d.ts +40 -0
  29. package/dist/src/extensions/Blocks/RadioButton/controls/blockBackground/index.d.ts +1 -0
  30. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +1 -0
  31. package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +11 -0
  32. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +7 -0
  33. package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +2 -0
  34. package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +7 -0
  35. package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +7 -0
  36. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +7 -0
  37. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +7 -0
  38. package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +7 -0
  39. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +7 -0
  40. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -0
  41. package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +1 -6
  42. package/dist/src/extensions/Blocks/_Boilerplate/controls/blockBackground/index.d.ts +1 -0
  43. package/dist/src/extensions/Blocks/controlFactories.d.ts +22 -0
  44. package/dist/src/services/settingsApi.d.ts +6 -0
  45. package/dist/src/stores/setup-settings.d.ts +4 -0
  46. package/dist/static/styles/components/button.css.js +5 -0
  47. package/dist/stores/setup-settings.js +10 -0
  48. package/package.json +4 -4
@@ -1,76 +1,78 @@
1
- import { useConfig as E } from "./useConfig.js";
2
- import { useEditorLock as f } from "./useEditorLock.js";
3
- import { useAutosaveStore as p, AUTOSAVE_STATUS as s } from "../stores/autosave.js";
4
- import { useEditorStore as A } from "../stores/editor.js";
5
- import { computed as y, watch as I, onUnmounted as L } from "vue";
6
- const w = 18e4, v = 6e4, R = (b) => {
7
- const { isFeatureEnabled: S } = E(), o = A(), t = p(), { isEditorBusy: g } = f();
8
- let i = null, c = 0;
9
- const u = y(
10
- () => S("autosave") && t.isOn
11
- ), m = () => o.hasChanges && o.isInSaveableState, h = () => ({
12
- hasChanges: o.hasChanges,
13
- isInSaveableState: o.isInSaveableState
14
- }), l = async (e) => {
15
- if (!u.value) {
1
+ import { useConfig as p } from "./useConfig.js";
2
+ import { useEditorLock as y } from "./useEditorLock.js";
3
+ import { useAutosaveStore as I, AUTOSAVE_STATUS as a } from "../stores/autosave.js";
4
+ import { useEditorStore as L } from "../stores/editor.js";
5
+ import { computed as w, watch as V, onUnmounted as k } from "vue";
6
+ const D = 18e4, b = 6e4, _ = (g, { clearsChanges: h = () => !0 } = {}) => {
7
+ const { isFeatureEnabled: m } = p(), s = L(), t = I(), { isEditorBusy: f } = y();
8
+ let o = null, l = 0, u = -1;
9
+ const d = w(
10
+ () => m("autosave") && t.isOn
11
+ ), A = () => s.hasChanges && s.isInSaveableState && s.changeSeq !== u, E = () => ({
12
+ hasChanges: s.hasChanges,
13
+ isInSaveableState: s.isInSaveableState,
14
+ isUnchangedSinceLastSave: s.changeSeq === u
15
+ }), r = async (e) => {
16
+ if (!d.value) {
16
17
  console.debug("guido:autosave:skipped", { trigger: e, reason: "not-active" });
17
18
  return;
18
19
  }
19
- if (!m()) {
20
- console.debug("guido:autosave:skipped", { trigger: e, reason: "gates-blocked", gates: h() });
20
+ if (!A()) {
21
+ console.debug("guido:autosave:skipped", { trigger: e, reason: "gates-blocked", gates: E() });
21
22
  return;
22
23
  }
23
- if (t.status === s.SAVING) {
24
+ if (t.status === a.SAVING) {
24
25
  console.debug("guido:autosave:skipped", { trigger: e, reason: "already-saving" });
25
26
  return;
26
27
  }
27
- if (g()) {
28
+ if (f()) {
28
29
  console.debug("guido:autosave:skipped", { trigger: e, reason: "editor-busy" });
29
30
  return;
30
31
  }
31
- e === "visibility" && (c = Date.now()), console.debug("guido:autosave:save-start", { trigger: e }), t.status = s.SAVING;
32
+ e === "visibility" && (l = Date.now()), console.debug("guido:autosave:save-start", { trigger: e }), t.status = a.SAVING;
33
+ const n = s.changeSeq;
32
34
  try {
33
- if (await b() === void 0) {
34
- console.debug("guido:autosave:blocked", { trigger: e, reason: "save-returned-undefined" }), t.status = s.ERROR;
35
+ if (await g() === void 0) {
36
+ console.debug("guido:autosave:blocked", { trigger: e, reason: "save-returned-undefined" }), t.status = a.ERROR;
35
37
  return;
36
38
  }
37
- o.hasChanges = !1, t.status = s.SAVED, t.lastSavedAt = /* @__PURE__ */ new Date(), console.debug("guido:autosave:save-complete", { trigger: e, at: t.lastSavedAt });
38
- } catch (a) {
39
- console.debug("guido:autosave:error", { trigger: e, error: a }), t.status = s.ERROR;
39
+ u = n, h() && (s.hasChanges = !1), t.status = a.SAVED, t.lastSavedAt = /* @__PURE__ */ new Date(), console.debug("guido:autosave:save-complete", { trigger: e, at: t.lastSavedAt });
40
+ } catch (S) {
41
+ console.debug("guido:autosave:error", { trigger: e, error: S }), t.status = a.ERROR;
40
42
  }
41
- }, n = () => {
43
+ }, i = () => {
42
44
  const { visibilityState: e } = document;
43
45
  if (console.debug("guido:autosave:visibility-change", {
44
46
  visibilityState: e,
45
- isActive: u.value
47
+ isActive: d.value
46
48
  }), e !== "hidden")
47
49
  return;
48
- const a = Date.now() - c;
49
- if (a < v) {
50
+ const n = Date.now() - l;
51
+ if (n < b) {
50
52
  console.debug("guido:autosave:visibility-debounced", {
51
- sinceLastMs: a,
52
- debounceMs: v
53
+ sinceLastMs: n,
54
+ debounceMs: b
53
55
  });
54
56
  return;
55
57
  }
56
- l("visibility");
57
- }, d = () => {
58
- i && (clearInterval(i), i = null);
59
- }, r = () => {
60
- document.removeEventListener("visibilitychange", n), window.removeEventListener("pagehide", n);
58
+ r("visibility");
59
+ }, c = () => {
60
+ o && (clearInterval(o), o = null);
61
+ }, v = () => {
62
+ document.removeEventListener("visibilitychange", i), window.removeEventListener("pagehide", i);
61
63
  };
62
- I(
63
- u,
64
+ V(
65
+ d,
64
66
  (e) => {
65
- console.debug("guido:autosave:active-changed", { active: e }), e ? (d(), i = setInterval(() => {
66
- console.debug("guido:autosave:interval-tick"), l("interval");
67
- }, w), document.addEventListener("visibilitychange", n), window.addEventListener("pagehide", n)) : (d(), r(), t.status = s.IDLE);
67
+ console.debug("guido:autosave:active-changed", { active: e }), e ? (c(), o = setInterval(() => {
68
+ console.debug("guido:autosave:interval-tick"), r("interval");
69
+ }, D), document.addEventListener("visibilitychange", i), window.addEventListener("pagehide", i)) : (c(), v(), t.status = a.IDLE);
68
70
  },
69
71
  { immediate: !0 }
70
- ), L(() => {
71
- d(), r(), t.status = s.IDLE, t.lastSavedAt = null;
72
+ ), k(() => {
73
+ c(), v(), t.status = a.IDLE, t.lastSavedAt = null;
72
74
  });
73
75
  };
74
76
  export {
75
- R as useAutoSave
77
+ _ as useAutoSave
76
78
  };
@@ -1,4 +1,4 @@
1
- import { useActionsApi as W } from "./useActionsApi.js";
1
+ import { useActionsApi as R } from "./useActionsApi.js";
2
2
  import { useConfig as q } from "./useConfig.js";
3
3
  import { useEditorLock as O } from "./useEditorLock.js";
4
4
  import { useSaveStart as D, useSaveComplete as F } from "./useGuidoActions.js";
@@ -19,37 +19,37 @@ import { useLiquidValidator as et } from "./validators/useLiquidValidator.js";
19
19
  import { useSyncModuleBlockValidator as ot } from "./validators/useSyncModuleBlockValidator.js";
20
20
  import { useUnsubscribeBlockValidator as st } from "./validators/useUnsubscribeBlockValidator.js";
21
21
  const Bt = () => {
22
- const r = D(), f = F(), { validateHtml: p } = _(), { validateLiquidSyntax: v } = et(), { validateCouponBlockTags: y } = tt(), { validateUnsubscribeBlockUniqueness: S, validateUnsubscribeBlockHasTemplate: w } = st(), { validateSyncModuleBlocks: n } = ot(), { callbacks: a, isFeatureEnabled: m } = q(), { extractSyncModuleData: b } = G(), { setSyncModuleUnsubscriptionPages: g } = J(), { editorSave: E, getTemplateData: H } = W(), { showToaster: V } = $(), { getBlockedDomains: x, resolveToast: k } = Z(), { prepareTemplateDetails: d } = X(), { collectSaveValidationErrors: C } = j(), { isEnabled: B } = z(), T = Q(), h = N(), P = K(), { runExclusive: l } = O(), c = async (t, e, o) => {
23
- if (!m("allowlistEnabled"))
22
+ const a = D(), p = F(), { validateHtml: v } = _(), { validateLiquidSyntax: S } = et(), { validateCouponBlockTags: y } = tt(), { validateUnsubscribeBlockUniqueness: w, validateUnsubscribeBlockHasTemplate: E } = st(), { validateSyncModuleBlocks: n } = ot(), { callbacks: r, isFeatureEnabled: d } = q(), { extractSyncModuleData: b } = G(), { setSyncModuleUnsubscriptionPages: g } = J(), { editorSave: H, getTemplateData: V } = R(), { showToaster: x } = $(), { getBlockedDomains: k, resolveToast: C } = Z(), { prepareTemplateDetails: m } = X(), { collectSaveValidationErrors: B } = j(), { isEnabled: h } = z(), T = Q(), P = N(), f = K(), { runExclusive: l } = O(), c = async (t, e, o) => {
23
+ if (!d("allowlistEnabled"))
24
24
  return !1;
25
- const i = await x(t, e);
25
+ const i = await k(t, e);
26
26
  if (!i.length)
27
27
  return !1;
28
28
  if (!o) {
29
- const s = await k(i);
30
- s != null && s.message && V({
29
+ const s = await C(i);
30
+ s != null && s.message && x({
31
31
  type: I.Warning,
32
32
  message: s.message,
33
33
  actionButton: s.actionButton
34
34
  });
35
35
  }
36
36
  return !0;
37
- }, L = async (t) => !y(t.compiledHtml) || !S(t.compiledHtml) || !w(t.compiledHtml) ? !1 : m("liquidSyntax") ? v(t.compiledHtml) : p(t.compiledHtml, t.dynamicContentList, !0), u = async (t, e) => {
38
- if (!await E())
37
+ }, L = async (t) => !y(t.compiledHtml) || !w(t.compiledHtml) || !E(t.compiledHtml) ? !1 : d("liquidSyntax") ? S(t.compiledHtml) : v(t.compiledHtml, t.dynamicContentList, !0), u = async (t, e) => {
38
+ if (!await H())
39
39
  return;
40
40
  const { unsubscribePayload: i, stripoModules: s } = b(t.rawHtml);
41
41
  if (await g(i), t.modules = s, !e.suppress) {
42
- const R = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
43
- f({ ...t, ...R, silent: e.silent });
42
+ const W = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
43
+ p({ ...t, ...W, silent: e.silent });
44
44
  }
45
45
  return t;
46
46
  }, U = async (t, e) => {
47
47
  var i;
48
- r();
49
- const o = await d();
48
+ a();
49
+ const o = await m();
50
50
  if (n(o.rawHtml, e)) {
51
- if (B.value && !e) {
52
- const s = await C(
51
+ if (h.value && !e) {
52
+ const s = await B(
53
53
  o.compiledHtml,
54
54
  o.dynamicContentList
55
55
  );
@@ -59,31 +59,34 @@ const Bt = () => {
59
59
  }
60
60
  } else if (!await L(o))
61
61
  return;
62
- if (!((i = a.value) != null && i.externalValidation && !await a.value.externalValidation(o)) && !await c(o.compiledHtml, o.css, e))
62
+ if (!((i = r.value) != null && i.externalValidation && !await r.value.externalValidation(o)) && !await c(o.compiledHtml, o.css, e))
63
63
  return u(o, { silent: e, suppress: t });
64
64
  }
65
65
  }, A = async () => {
66
66
  var e;
67
- if (!P.allowSaveWithErrors)
67
+ if (!f.allowSaveWithErrors)
68
68
  return;
69
- r();
70
- const t = await d();
71
- if (n(t.rawHtml, !1) && !((e = a.value) != null && e.externalValidation && !await a.value.externalValidation(t)) && !await c(t.compiledHtml, t.css, !1))
69
+ a();
70
+ const t = await m();
71
+ if (n(t.rawHtml, !1) && !((e = r.value) != null && e.externalValidation && !await r.value.externalValidation(t)) && !await c(t.compiledHtml, t.css, !1))
72
72
  return u(t, { silent: !1, blankCompiled: !0 });
73
73
  }, M = async () => {
74
- r();
75
- const { html: t, css: e } = await H();
74
+ if (!f.allowSaveWithErrors)
75
+ return;
76
+ a();
77
+ const { html: t, css: e } = await V();
76
78
  if (!n(t, !0) || await c(t, e, !0))
77
79
  return;
78
80
  const o = Y(t), i = {
79
- dynamicContentList: h.getSelectedDynamicContentList,
81
+ dynamicContentList: P.getSelectedDynamicContentList,
80
82
  compiledHtml: "",
81
83
  rawHtml: t,
82
84
  css: e,
83
85
  ampHtml: "",
84
86
  ampErrors: [],
85
87
  modules: [],
86
- recommendation: { campaignUrls: {}, configs: {} },
88
+ // No campaignUrls: hosts overwrite their stored map with any object, and raw HTML can't rebuild it.
89
+ recommendation: { configs: {} },
87
90
  unsubscribe: {
88
91
  status: o.length > 0,
89
92
  config: o
@@ -1,164 +1,164 @@
1
- import { getIgnoredRecommendationBlockIds as B } from "../config/compiler/utils/recommendationIgnoreUtils.js";
2
- import { CanNotMakeAnyChangesForRunningKey as k, DISPLAY_CONDITIONS_REGEX as Y, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as x } from "../enums/html-validator.js";
1
+ import { getIgnoredRecommendationBlockIds as Y } from "../config/compiler/utils/recommendationIgnoreUtils.js";
2
+ import { CanNotMakeAnyChangesForRunningKey as k, DISPLAY_CONDITIONS_REGEX as x, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as M } from "../enums/html-validator.js";
3
3
  import { SaveValidationRule as o } from "../enums/save-validation.js";
4
4
  import { ToasterTypeOptions as r } from "../enums/toaster.js";
5
- import { BLOCK_ROOT_SELECTOR as M } from "../extensions/Blocks/Checkbox/constants/selectors.js";
6
- import { itemsBlockDynamicVariables as U } from "../extensions/Blocks/Items/enums/productEnums.js";
7
- import { BLOCK_ROOT_SELECTOR as P } from "../extensions/Blocks/RadioButton/constants/selectors.js";
8
- import { useRecommendationExtensionStore as W } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
- import { getInvalidFields as G, STRATEGY_FIELD_KEY as q, RecommendationAssignStrategyKey as H, RecommendationRequiredFieldsKey as V } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
10
- import { useConfigStore as X } from "../stores/config.js";
11
- import { useDynamicContentStore as j } from "../stores/dynamic-content.js";
12
- import { useRecommendationStore as z } from "../stores/recommendation.js";
5
+ import { BLOCK_ROOT_SELECTOR as U } from "../extensions/Blocks/Checkbox/constants/selectors.js";
6
+ import { itemsBlockDynamicVariables as P } from "../extensions/Blocks/Items/enums/productEnums.js";
7
+ import { BLOCK_ROOT_SELECTOR as W } from "../extensions/Blocks/RadioButton/constants/selectors.js";
8
+ import { useRecommendationExtensionStore as G } from "../extensions/Blocks/Recommendation/store/recommendation.js";
9
+ import { getInvalidFields as q, STRATEGY_FIELD_KEY as H, RecommendationAssignStrategyKey as V, RecommendationRequiredFieldsKey as X } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
10
+ import { useConfigStore as j } from "../stores/config.js";
11
+ import { useDynamicContentStore as z } from "../stores/dynamic-content.js";
12
+ import { useRecommendationStore as $ } from "../stores/recommendation.js";
13
13
  import { base64EncodeWithSpecialChars as T } from "../utils/base64.js";
14
- import { escapeHtml as $ } from "../utils/htmlEscape.js";
15
- import { useTemplatePreparation as Q } from "../utils/templatePreparation.js";
16
- import { useActionsApi as Z } from "./useActionsApi.js";
17
- import { useConfig as J } from "./useConfig.js";
18
- import { useHtmlCompiler as ee } from "./useHtmlCompiler.js";
19
- import { buildPartnerAttributeNameSet as te, getInvalidDynamicContentTags as ne, getRecommendationBlockIds as ie, findInvalidCustomFields as oe } from "./useHtmlValidator.js";
20
- import { useHttp as re } from "./useHttp.js";
21
- import { useTranslations as se } from "./useTranslations.js";
22
- import { findInvalidCouponBlocks as ae, COUPON_TAG_MODIFIED_KEY as ce } from "./validators/useCouponBlockValidator.js";
23
- import { findDuplicateUnsubPageTypes as le, countUnsubBlocksWithoutPage as me, EMPTY_BLOCK_KEY as ue } from "./validators/useUnsubscribeBlockValidator.js";
24
- const de = "newsletter.html-content-is-empty", pe = "custom-fields.missing-closing-braces", ge = "custom-fields.missing-opening-braces", I = "custom-fields.invalid-custom-fields", fe = "newsletter.display-conditions-invalid-syntax", ye = "custom-conditions.wrong-equality-operators", Ee = "custom-conditions.missing-if-endif-tag", Ie = "custom-conditions.no-space-after-braces", Se = "custom-conditions.no-braces-inside-if-tag", _e = "newsletter.fill-all-necessary-fields", Ce = "newsletter.invalid-image-type", he = "unsubscribe-templates.select-checkbox-groups", ke = "unsubscribe-templates.select-radio-button-groups", Te = "newsletter.invalid-url-link-for-toaster", F = "journey-builder.liquid-validation-failed", Fe = "/newsletter/template-library/check-template-html-body", Oe = /src="[^"]*\.(svg|pst)"/gm, R = /({%(.*?)%})/g, Re = ["if", "endif", "else", "elif", "now"], Le = (t) => !Re.includes(t.toLowerCase()), Ne = (t) => ["if", "endif"].includes(t.toLowerCase());
14
+ import { escapeHtml as Q } from "../utils/htmlEscape.js";
15
+ import { useTemplatePreparation as Z } from "../utils/templatePreparation.js";
16
+ import { useActionsApi as J } from "./useActionsApi.js";
17
+ import { useConfig as ee } from "./useConfig.js";
18
+ import { useHtmlCompiler as te } from "./useHtmlCompiler.js";
19
+ import { buildPartnerAttributeNameSet as ne, getInvalidDynamicContentTags as ie, getRecommendationBlockIds as oe, findInvalidCustomFields as re } from "./useHtmlValidator.js";
20
+ import { useHttp as se } from "./useHttp.js";
21
+ import { useTranslations as ae } from "./useTranslations.js";
22
+ import { findInvalidCouponBlocks as ce, COUPON_TAG_MODIFIED_KEY as le } from "./validators/useCouponBlockValidator.js";
23
+ import { findDuplicateUnsubPageTypes as me, countUnsubBlocksWithoutPage as ue, EMPTY_BLOCK_KEY as de } from "./validators/useUnsubscribeBlockValidator.js";
24
+ const pe = "newsletter.html-content-is-empty", ge = "custom-fields.missing-closing-braces", fe = "custom-fields.missing-opening-braces", S = "custom-fields.invalid-custom-fields", ye = "newsletter.display-conditions-invalid-syntax", Ee = "custom-conditions.wrong-equality-operators", Ie = "custom-conditions.missing-if-endif-tag", Se = "custom-conditions.no-space-after-braces", _e = "custom-conditions.no-braces-inside-if-tag", Ce = "newsletter.fill-all-necessary-fields", he = "newsletter.invalid-image-type", ke = "unsubscribe-templates.select-checkbox-groups", Te = "unsubscribe-templates.select-radio-button-groups", F = "newsletter.invalid-url-link-for-toaster", R = "journey-builder.liquid-validation-failed", Fe = "/newsletter/template-library/check-template-html-body", Re = /src="[^"]*\.(svg|pst)"/gm, L = /({%(.*?)%})/g, Oe = ["if", "endif", "else", "elif", "now"], Le = (t) => !Oe.includes(t.toLowerCase()), Ne = (t) => ["if", "endif"].includes(t.toLowerCase());
25
25
  function be(t) {
26
- return ae(t).map((i) => ({
26
+ return ce(t).map((i) => ({
27
27
  rule: o.CouponTagModified,
28
28
  type: r.Warning,
29
- key: ce,
29
+ key: le,
30
30
  detail: i
31
31
  }));
32
32
  }
33
33
  function Ae(t) {
34
- return le(t).map((i) => ({
34
+ return me(t).map((i) => ({
35
35
  rule: o.DuplicateUnsubBlock,
36
36
  type: r.Error,
37
37
  key: i.messageKey
38
38
  }));
39
39
  }
40
40
  function ve(t) {
41
- return Array.from({ length: me(t) }, () => ({
41
+ return Array.from({ length: ue(t) }, () => ({
42
42
  rule: o.UnsubBlockMissingTemplate,
43
43
  type: r.Warning,
44
- key: ue
44
+ key: de
45
45
  }));
46
46
  }
47
47
  function De(t, i) {
48
- const n = t.match(R);
48
+ const n = t.match(L);
49
49
  if (!n)
50
50
  return [];
51
- const c = [];
51
+ const l = [];
52
52
  return n.forEach((u) => {
53
- const a = u.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
54
- if (a && a.length > 0) {
55
- const [d] = a;
56
- Le(d) && !i.includes(d) && c.push({
53
+ const c = u.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
54
+ if (c && c.length > 0) {
55
+ const [d] = c;
56
+ Le(d) && !i.includes(d) && l.push({
57
57
  rule: o.CustomFieldScript,
58
58
  type: r.Warning,
59
- key: I,
59
+ key: S,
60
60
  detail: d
61
61
  });
62
62
  }
63
- }), c;
63
+ }), l;
64
64
  }
65
65
  function Ke(t) {
66
- return t.length > 0 ? [] : [{ rule: o.EmptyHtml, type: r.Warning, key: de }];
66
+ return t.length > 0 ? [] : [{ rule: o.EmptyHtml, type: r.Warning, key: pe }];
67
67
  }
68
68
  function we(t) {
69
69
  const i = (t.match(/{/gm) || []).length, n = (t.match(/}/gm) || []).length;
70
70
  return i > n ? [{
71
71
  rule: o.MismatchedBraces,
72
72
  type: r.Warning,
73
- key: pe
73
+ key: ge
74
74
  }] : i < n ? [{
75
75
  rule: o.MismatchedBraces,
76
76
  type: r.Warning,
77
- key: ge
77
+ key: fe
78
78
  }] : [];
79
79
  }
80
80
  function Be(t) {
81
- return ne(t).map((i) => ({
81
+ return ie(t).map((i) => ({
82
82
  rule: o.InvalidDynamicTag,
83
83
  type: r.Warning,
84
- key: I,
84
+ key: S,
85
85
  detail: i
86
86
  }));
87
87
  }
88
- function Ye(t, i, n, c) {
89
- const u = ie(t);
90
- return oe(t, i, u, n, c).map((a) => ({
88
+ function Ye(t, i, n, l) {
89
+ const u = oe(t);
90
+ return re(t, i, u, n, l).map((c) => ({
91
91
  rule: o.InvalidCustomField,
92
92
  type: r.Error,
93
- key: I,
94
- detail: a
93
+ key: S,
94
+ detail: c
95
95
  }));
96
96
  }
97
97
  function xe(t) {
98
- const i = t.match(/{%(.*?)%}/g), n = [], c = [];
98
+ const i = t.match(/{%(.*?)%}/g), n = [], l = [];
99
99
  if (i && i.forEach((u) => {
100
- const a = u.match(Y), d = u.match(x), E = (a == null ? void 0 : a.join("")) || "";
101
- (!a || u !== E) && !d && c.push({
100
+ const c = u.match(x), d = u.match(M), I = (c == null ? void 0 : c.join("")) || "";
101
+ (!c || u !== I) && !d && l.push({
102
102
  rule: o.ConditionsSyntax,
103
103
  type: r.Error,
104
- key: fe,
104
+ key: ye,
105
105
  detail: u
106
- }), a && a.forEach((g) => {
107
- g.trim() === "=" && c.push({
106
+ }), c && c.forEach((g) => {
107
+ g.trim() === "=" && l.push({
108
108
  rule: o.WrongEqualityOperator,
109
109
  type: r.Error,
110
- key: ye
110
+ key: Ee
111
111
  }), (g.match(/^[a-zA-Z]*$/g) ?? []).forEach((f) => {
112
112
  Ne(f) && n.push(f);
113
113
  });
114
114
  });
115
115
  }), n.length) {
116
- const u = n.filter((d) => d === "if").length, a = n.filter((d) => d === "endif").length;
117
- u !== a && c.push({
116
+ const u = n.filter((d) => d === "if").length, c = n.filter((d) => d === "endif").length;
117
+ u !== c && l.push({
118
118
  rule: o.MissingIfEndif,
119
119
  type: r.Error,
120
- key: Ee
120
+ key: Ie
121
121
  });
122
122
  }
123
- return c;
123
+ return l;
124
124
  }
125
125
  function Me(t) {
126
126
  const i = (t.match(/{% /gm) || []).length, n = (t.match(/ %}/gm) || []).length;
127
127
  return i === n ? [] : [{
128
128
  rule: o.ConditionTagSpacing,
129
129
  type: r.Warning,
130
- key: Ie
130
+ key: Se
131
131
  }];
132
132
  }
133
133
  function Ue(t) {
134
- return (t.match(R) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, c) => n + c, 0) === 0 ? [] : [{
134
+ return (t.match(L) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, l) => n + l, 0) === 0 ? [] : [{
135
135
  rule: o.BracesInsideIfTag,
136
136
  type: r.Warning,
137
- key: Se
137
+ key: _e
138
138
  }];
139
139
  }
140
140
  function Pe(t) {
141
- return (t.match(Oe) ?? []).map((i) => ({
141
+ return (t.match(Re) ?? []).map((i) => ({
142
142
  rule: o.InvalidImageType,
143
143
  type: r.Error,
144
- key: Ce,
144
+ key: he,
145
145
  detail: i
146
146
  }));
147
147
  }
148
- function O(t, i, n, c) {
148
+ function O(t, i, n, l) {
149
149
  const u = new DOMParser().parseFromString(t, "text/html");
150
- return Array.from(u.querySelectorAll(i)).filter((a) => {
150
+ return Array.from(u.querySelectorAll(i)).filter((c) => {
151
151
  var d;
152
- return !((d = a.id) != null && d.trim());
153
- }).map(() => ({ rule: n, type: r.Error, key: c }));
152
+ return !((d = c.id) != null && d.trim());
153
+ }).map(() => ({ rule: n, type: r.Error, key: l }));
154
154
  }
155
155
  const dt = () => {
156
- const { config: t, isFeatureEnabled: i } = J(), n = se(), { post: c } = re(), { getCompiledEmail: u, getTemplateData: a } = Z(), { compileHtml: d } = ee(), { hydrateRecommendationStore: E } = Q(), g = j(), f = z(), y = W(), L = X(), N = (e) => ({
156
+ const { config: t, isFeatureEnabled: i } = ee(), n = ae(), { post: l } = se(), { getCompiledEmail: u, getTemplateData: c } = J(), { compileHtml: d } = te(), { hydrateRecommendationStore: I } = Z(), g = z(), f = $(), y = G(), N = j(), b = (e) => ({
157
157
  rule: e.rule,
158
158
  type: e.type,
159
159
  detail: e.detail,
160
- message: "key" in e ? n(e.key) : $(e.message)
161
- }), b = async (e) => {
160
+ message: "key" in e ? n(e.key) : Q(e.message)
161
+ }), A = async (e) => {
162
162
  if (e.size === 0)
163
163
  return /* @__PURE__ */ new Set();
164
164
  try {
@@ -166,28 +166,25 @@ const dt = () => {
166
166
  } catch {
167
167
  return null;
168
168
  }
169
- return te(y.filterList);
170
- }, A = async (e) => {
169
+ return ne(y.filterList);
170
+ }, v = async (e) => {
171
171
  try {
172
- const l = await c(Fe, { html: T(e) }), { status: s, message: m } = l.data, p = [];
173
- return s || p.push({
172
+ const s = await l(Fe, { html: T(e) }), { status: a, message: m } = s.data, p = [], E = a === void 0 && !!m && m !== n(F);
173
+ return a || p.push({
174
174
  rule: o.InvalidLinks,
175
175
  type: r.Error,
176
- // status===undefined means a bare message instead of a boolean; surface it,
177
- // but fall back to the canned key when it's missing so a malformed body
178
- // never renders a literal 'undefined' row (SD-147430).
179
- ...s === void 0 && m ? { message: m } : { key: Te }
176
+ ...E ? { message: m } : { key: F }
180
177
  }), m === n(k) && p.push({
181
178
  rule: o.LinkCheckInProgress,
182
179
  type: r.Error,
183
180
  key: k
184
181
  }), p;
185
- } catch (l) {
186
- return console.warn("Link-check collector failed; skipping the link rule.", l), [];
182
+ } catch (s) {
183
+ return console.warn("Link-check collector failed; skipping the link rule.", s), [];
187
184
  }
188
- }, v = async (e) => {
185
+ }, D = async (e) => {
189
186
  try {
190
- const l = await c("/newsletter/contents/validate-syntax", [{
187
+ const s = await l("/newsletter/contents/validate-syntax", [{
191
188
  identifier: "default",
192
189
  syntax: "liquid",
193
190
  contents: {
@@ -197,84 +194,86 @@ const dt = () => {
197
194
  ampHtml: null
198
195
  }
199
196
  }]);
200
- if (!Array.isArray(l.data)) {
201
- const m = l.data;
197
+ if (!Array.isArray(s.data)) {
198
+ const m = s.data;
202
199
  return [{
203
200
  rule: o.LiquidSyntax,
204
201
  type: r.Warning,
205
- message: m.message ?? n(F)
202
+ message: m.message ?? n(R)
206
203
  }];
207
204
  }
208
- const [s] = l.data;
209
- return Object.values((s == null ? void 0 : s.errors) ?? {}).map((m) => ({
205
+ const [a] = s.data;
206
+ return Object.values((a == null ? void 0 : a.errors) ?? {}).map((m) => ({
210
207
  rule: o.LiquidSyntax,
211
208
  type: r.Warning,
212
209
  message: m.replace(/^line \d+:\s*/, "")
213
210
  }));
214
- } catch {
211
+ } catch (s) {
212
+ if (s != null && s.authReported)
213
+ throw s;
215
214
  return [{
216
215
  rule: o.LiquidSyntax,
217
216
  type: r.Error,
218
- message: n(F)
217
+ message: n(R)
219
218
  }];
220
219
  }
221
- }, D = () => {
222
- const e = Object.values(y.blockStates).map((s) => G(s.recommendationConfigs, y)).filter((s) => s.length > 0).map((s) => {
223
- const m = s.every((p) => p === q);
220
+ }, K = () => {
221
+ const e = Object.values(y.blockStates).map((a) => q(a.recommendationConfigs, y)).filter((a) => a.length > 0).map((a) => {
222
+ const m = a.every((p) => p === H);
224
223
  return {
225
224
  rule: o.RecommendationRequiredFields,
226
225
  type: m ? r.Warning : r.Error,
227
- key: m ? H : V
226
+ key: m ? V : X
228
227
  };
229
- }), l = (f.recommendationConfigs ?? []).filter((s) => s.filters.some((m) => m.value === "")).map(() => ({
228
+ }), s = (f.recommendationConfigs ?? []).filter((a) => a.filters.some((m) => m.value === "")).map(() => ({
230
229
  rule: o.RecommendationFilters,
231
230
  type: r.Error,
232
- key: _e
231
+ key: Ce
233
232
  }));
234
- return [...e, ...l];
235
- }, K = async (e, l) => {
233
+ return [...e, ...s];
234
+ }, w = async (e, s) => {
236
235
  var C, h;
237
- const s = [
238
- ...l.map((w) => w.value),
239
- ...U,
236
+ const a = [
237
+ ...s.map((B) => B.value),
238
+ ...P,
240
239
  ...((h = (C = t.value) == null ? void 0 : C.template) == null ? void 0 : h.customFieldAttributes) ?? []
241
- ], m = B(e), p = await b(m), { isTransactional: _ } = L;
240
+ ], m = Y(e), p = await A(m), { isTransactional: E } = N;
242
241
  return [
243
- ...await A(e),
244
- ..._ ? [] : De(e, s),
242
+ ...await v(e),
243
+ ...E ? [] : De(e, a),
245
244
  ...Ke(e),
246
245
  ...we(e),
247
246
  ...Be(e),
248
- ..._ ? [] : Ye(e, s, m, p),
247
+ ...E ? [] : Ye(e, a, m, p),
249
248
  ...xe(e),
250
249
  ...Me(e),
251
250
  ...Ue(e),
252
- ...D(),
251
+ ...K(),
253
252
  ...Pe(e),
254
253
  ...O(
255
254
  e,
256
- M,
255
+ U,
257
256
  o.CheckboxUnsubGroup,
258
- he
257
+ ke
259
258
  ),
260
259
  ...O(
261
260
  e,
262
- P,
261
+ W,
263
262
  o.RadioButtonUnsubGroup,
264
- ke
263
+ Te
265
264
  )
266
265
  ];
267
- }, S = async (e, l) => [
266
+ }, _ = async (e, s) => [
268
267
  ...be(e),
269
268
  ...Ae(e),
270
269
  ...ve(e),
271
- ...i("liquidSyntax") ? await v(e) : await K(e, l)
272
- ].map(N);
273
- return { collectSaveValidationErrors: S, validateCurrentTemplate: async () => {
274
- const { html: e } = await a();
275
- await E(e);
276
- const { html: l } = await u({ minimize: !0, resetDataSavedFlag: !1 }), { compiledHtml: s } = d(l);
277
- return S(s, g.getSelectedDynamicContentList);
270
+ ...i("liquidSyntax") ? await D(e) : await w(e, s)
271
+ ].map(b);
272
+ return { collectSaveValidationErrors: _, validateCurrentTemplate: async () => {
273
+ const { html: e } = await c();
274
+ await I(e);
275
+ const { html: s } = await u({ minimize: !0, resetDataSavedFlag: !1 }), { compiledHtml: a } = d(s);
276
+ return _(a, g.getSelectedDynamicContentList);
278
277
  } };
279
278
  };
280
279
  export {