@useinsider/guido 3.20.1-beta.ed186ad → 3.20.2-beta.87fb8ae
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.
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +69 -69
- package/dist/components/organisms/AutoSaveController.vue2.js +9 -10
- package/dist/components/organisms/header/EditorActions.vue.js +4 -4
- package/dist/components/organisms/header/EditorActions.vue2.js +51 -53
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +3 -3
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +22 -23
- package/dist/composables/useAutoSave.js +44 -46
- package/dist/composables/useLegacyStrategyConversion.js +16 -16
- package/dist/composables/useSave.js +23 -26
- package/dist/composables/useSaveValidation.js +53 -55
- package/dist/composables/useSaveValidationRollout.js +6 -17
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +296 -223
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +219 -205
- package/dist/extensions/Blocks/Recommendation/utils/blockRefresh.js +19 -0
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +51 -36
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +31 -35
- package/dist/guido.css +1 -1
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
- package/dist/src/composables/useAutoSave.d.ts +1 -4
- package/dist/src/composables/useSaveValidationRollout.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +18 -3
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +8 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/blockRefresh.d.ts +17 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +7 -0
- package/package.json +1 -1
- package/dist/services/settingsApi.js +0 -11
- package/dist/src/services/settingsApi.d.ts +0 -6
- package/dist/src/stores/setup-settings.d.ts +0 -4
- package/dist/stores/setup-settings.js +0 -10
|
@@ -1,78 +1,76 @@
|
|
|
1
|
-
import { useConfig as
|
|
2
|
-
import { useEditorLock as
|
|
3
|
-
import { useAutosaveStore as
|
|
4
|
-
import { useEditorStore as
|
|
5
|
-
import { computed as
|
|
6
|
-
const
|
|
7
|
-
const { isFeatureEnabled:
|
|
8
|
-
let
|
|
9
|
-
const
|
|
10
|
-
() =>
|
|
11
|
-
),
|
|
12
|
-
hasChanges:
|
|
13
|
-
isInSaveableState:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (!d.value) {
|
|
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) {
|
|
17
16
|
console.debug("guido:autosave:skipped", { trigger: e, reason: "not-active" });
|
|
18
17
|
return;
|
|
19
18
|
}
|
|
20
|
-
if (!
|
|
21
|
-
console.debug("guido:autosave:skipped", { trigger: e, reason: "gates-blocked", gates:
|
|
19
|
+
if (!m()) {
|
|
20
|
+
console.debug("guido:autosave:skipped", { trigger: e, reason: "gates-blocked", gates: h() });
|
|
22
21
|
return;
|
|
23
22
|
}
|
|
24
|
-
if (t.status ===
|
|
23
|
+
if (t.status === s.SAVING) {
|
|
25
24
|
console.debug("guido:autosave:skipped", { trigger: e, reason: "already-saving" });
|
|
26
25
|
return;
|
|
27
26
|
}
|
|
28
|
-
if (
|
|
27
|
+
if (g()) {
|
|
29
28
|
console.debug("guido:autosave:skipped", { trigger: e, reason: "editor-busy" });
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
|
-
e === "visibility" && (
|
|
33
|
-
const n = s.changeSeq;
|
|
31
|
+
e === "visibility" && (c = Date.now()), console.debug("guido:autosave:save-start", { trigger: e }), t.status = s.SAVING;
|
|
34
32
|
try {
|
|
35
|
-
if (await
|
|
36
|
-
console.debug("guido:autosave:blocked", { trigger: e, reason: "save-returned-undefined" }), t.status =
|
|
33
|
+
if (await b() === void 0) {
|
|
34
|
+
console.debug("guido:autosave:blocked", { trigger: e, reason: "save-returned-undefined" }), t.status = s.ERROR;
|
|
37
35
|
return;
|
|
38
36
|
}
|
|
39
|
-
|
|
40
|
-
} catch (
|
|
41
|
-
console.debug("guido:autosave:error", { trigger: e, error:
|
|
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;
|
|
42
40
|
}
|
|
43
|
-
},
|
|
41
|
+
}, n = () => {
|
|
44
42
|
const { visibilityState: e } = document;
|
|
45
43
|
if (console.debug("guido:autosave:visibility-change", {
|
|
46
44
|
visibilityState: e,
|
|
47
|
-
isActive:
|
|
45
|
+
isActive: u.value
|
|
48
46
|
}), e !== "hidden")
|
|
49
47
|
return;
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
48
|
+
const a = Date.now() - c;
|
|
49
|
+
if (a < v) {
|
|
52
50
|
console.debug("guido:autosave:visibility-debounced", {
|
|
53
|
-
sinceLastMs:
|
|
54
|
-
debounceMs:
|
|
51
|
+
sinceLastMs: a,
|
|
52
|
+
debounceMs: v
|
|
55
53
|
});
|
|
56
54
|
return;
|
|
57
55
|
}
|
|
58
|
-
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
},
|
|
62
|
-
document.removeEventListener("visibilitychange",
|
|
56
|
+
l("visibility");
|
|
57
|
+
}, d = () => {
|
|
58
|
+
i && (clearInterval(i), i = null);
|
|
59
|
+
}, r = () => {
|
|
60
|
+
document.removeEventListener("visibilitychange", n), window.removeEventListener("pagehide", n);
|
|
63
61
|
};
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
I(
|
|
63
|
+
u,
|
|
66
64
|
(e) => {
|
|
67
|
-
console.debug("guido:autosave:active-changed", { active: e }), e ? (
|
|
68
|
-
console.debug("guido:autosave:interval-tick"),
|
|
69
|
-
},
|
|
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);
|
|
70
68
|
},
|
|
71
69
|
{ immediate: !0 }
|
|
72
|
-
),
|
|
73
|
-
|
|
70
|
+
), L(() => {
|
|
71
|
+
d(), r(), t.status = s.IDLE, t.lastSavedAt = null;
|
|
74
72
|
});
|
|
75
73
|
};
|
|
76
74
|
export {
|
|
77
|
-
|
|
75
|
+
R as useAutoSave
|
|
78
76
|
};
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { useRecommendation as
|
|
1
|
+
import { useRecommendation as S } from "./useRecommendation.js";
|
|
2
2
|
import { useToaster as I } from "./useToaster.js";
|
|
3
3
|
import { useTranslations as v } from "./useTranslations.js";
|
|
4
4
|
import { ToasterTypeOptions as g } from "../enums/toaster.js";
|
|
5
5
|
import "../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
6
6
|
import { CURRENT_CONFIG_VERSION as L } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
|
|
7
|
-
import { useRecommendationExtensionStore as
|
|
8
|
-
import { resolveMigrationTarget as
|
|
7
|
+
import { useRecommendationExtensionStore as R } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
8
|
+
import { resolveMigrationTarget as b, buildLegacyMigrationPayload as k } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js";
|
|
9
9
|
import { commitBlockChangeOutsidePanel as T } from "../extensions/Blocks/Recommendation/utils/nodeConfigWriter.js";
|
|
10
10
|
import { useConfigStore as h } from "../stores/config.js";
|
|
11
11
|
const F = () => {
|
|
12
|
-
const e =
|
|
12
|
+
const e = R(), o = h(), { buildCampaignUrl: m } = S(), { showToaster: c } = I(), a = v();
|
|
13
13
|
return { convertLegacyStrategy: async () => {
|
|
14
14
|
const t = e.currentRecommendationId;
|
|
15
15
|
if (t === null || !e.isLegacyStrategyBlock || e.legacyConversionLoading)
|
|
16
16
|
return "";
|
|
17
|
-
const { strategy: d, productIds: y, size: l, strategyId: p, nodeConfigVersion: u } = e.recommendationConfigs, f = { strategyId: p, size: l, nodeConfigVersion: u }, s =
|
|
18
|
-
campaignId:
|
|
19
|
-
templateLibraryId:
|
|
20
|
-
}),
|
|
17
|
+
const { strategy: d, productIds: y, size: l, strategyId: p, nodeConfigVersion: u } = e.recommendationConfigs, f = { strategyId: p, size: l, nodeConfigVersion: u }, s = b({
|
|
18
|
+
campaignId: o.campaignId,
|
|
19
|
+
templateLibraryId: o.templateLibraryId
|
|
20
|
+
}), C = k({
|
|
21
21
|
blockId: t,
|
|
22
22
|
url: m(String(t)),
|
|
23
|
-
campaignId:
|
|
24
|
-
variationId:
|
|
23
|
+
campaignId: o.campaignId,
|
|
24
|
+
variationId: o.variationId,
|
|
25
25
|
strategy: d,
|
|
26
26
|
productIds: y,
|
|
27
27
|
target: s
|
|
28
28
|
});
|
|
29
|
-
let
|
|
29
|
+
let r;
|
|
30
30
|
try {
|
|
31
|
-
|
|
31
|
+
r = await e.convertLegacyStrategy(C, s);
|
|
32
32
|
} catch (i) {
|
|
33
33
|
return console.error("[useLegacyStrategyConversion] migration failed", i), c({
|
|
34
34
|
type: g.Error,
|
|
@@ -40,7 +40,7 @@ const F = () => {
|
|
|
40
40
|
}), "";
|
|
41
41
|
}
|
|
42
42
|
try {
|
|
43
|
-
await e.
|
|
43
|
+
await e.fetchRecommendationProductsForBlock(t);
|
|
44
44
|
} catch (i) {
|
|
45
45
|
console.error("[useLegacyStrategyConversion] product refetch failed", i);
|
|
46
46
|
}
|
|
@@ -48,16 +48,16 @@ const F = () => {
|
|
|
48
48
|
return n ? T(
|
|
49
49
|
t,
|
|
50
50
|
{
|
|
51
|
-
strategyId:
|
|
51
|
+
strategyId: r,
|
|
52
52
|
size: n.recommendationConfigs.size,
|
|
53
53
|
configVersion: L
|
|
54
54
|
},
|
|
55
55
|
n.recommendationProducts,
|
|
56
56
|
"Converted legacy recommendation strategy"
|
|
57
|
-
) ? (e.currentRecommendationId === t && e.openLegacyStrategyUpdatedModal(),
|
|
57
|
+
) ? (e.currentRecommendationId === t && e.openLegacyStrategyUpdatedModal(), r) : (console.error("[useLegacyStrategyConversion] node write failed", t), e.revertLegacyConversion(t, f), c({
|
|
58
58
|
type: g.Error,
|
|
59
59
|
message: a("email-editor.legacy-strategy-update-failed")
|
|
60
|
-
}), "") :
|
|
60
|
+
}), "") : r;
|
|
61
61
|
} };
|
|
62
62
|
};
|
|
63
63
|
export {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
1
|
+
import { useActionsApi as W } 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
|
|
23
|
-
if (!
|
|
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"))
|
|
24
24
|
return !1;
|
|
25
|
-
const i = await
|
|
25
|
+
const i = await x(t, e);
|
|
26
26
|
if (!i.length)
|
|
27
27
|
return !1;
|
|
28
28
|
if (!o) {
|
|
29
|
-
const s = await
|
|
30
|
-
s != null && s.message &&
|
|
29
|
+
const s = await k(i);
|
|
30
|
+
s != null && s.message && V({
|
|
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) || !
|
|
38
|
-
if (!await
|
|
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())
|
|
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
|
|
43
|
-
|
|
42
|
+
const R = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
|
|
43
|
+
f({ ...t, ...R, silent: e.silent });
|
|
44
44
|
}
|
|
45
45
|
return t;
|
|
46
46
|
}, U = async (t, e) => {
|
|
47
47
|
var i;
|
|
48
|
-
|
|
49
|
-
const o = await
|
|
48
|
+
r();
|
|
49
|
+
const o = await d();
|
|
50
50
|
if (n(o.rawHtml, e)) {
|
|
51
|
-
if (
|
|
52
|
-
const s = await
|
|
51
|
+
if (B.value && !e) {
|
|
52
|
+
const s = await C(
|
|
53
53
|
o.compiledHtml,
|
|
54
54
|
o.dynamicContentList
|
|
55
55
|
);
|
|
@@ -59,34 +59,31 @@ const Bt = () => {
|
|
|
59
59
|
}
|
|
60
60
|
} else if (!await L(o))
|
|
61
61
|
return;
|
|
62
|
-
if (!((i =
|
|
62
|
+
if (!((i = a.value) != null && i.externalValidation && !await a.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 (!
|
|
67
|
+
if (!P.allowSaveWithErrors)
|
|
68
68
|
return;
|
|
69
|
-
|
|
70
|
-
const t = await
|
|
71
|
-
if (n(t.rawHtml, !1) && !((e =
|
|
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))
|
|
72
72
|
return u(t, { silent: !1, blankCompiled: !0 });
|
|
73
73
|
}, M = async () => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
a();
|
|
77
|
-
const { html: t, css: e } = await V();
|
|
74
|
+
r();
|
|
75
|
+
const { html: t, css: e } = await H();
|
|
78
76
|
if (!n(t, !0) || await c(t, e, !0))
|
|
79
77
|
return;
|
|
80
78
|
const o = Y(t), i = {
|
|
81
|
-
dynamicContentList:
|
|
79
|
+
dynamicContentList: h.getSelectedDynamicContentList,
|
|
82
80
|
compiledHtml: "",
|
|
83
81
|
rawHtml: t,
|
|
84
82
|
css: e,
|
|
85
83
|
ampHtml: "",
|
|
86
84
|
ampErrors: [],
|
|
87
85
|
modules: [],
|
|
88
|
-
|
|
89
|
-
recommendation: { configs: {} },
|
|
86
|
+
recommendation: { campaignUrls: {}, configs: {} },
|
|
90
87
|
unsubscribe: {
|
|
91
88
|
status: o.length > 0,
|
|
92
89
|
config: o
|
|
@@ -21,7 +21,7 @@ import { useHttp as re } from "./useHttp.js";
|
|
|
21
21
|
import { useTranslations as se } from "./useTranslations.js";
|
|
22
22
|
import { findInvalidCouponBlocks as ae, COUPON_TAG_MODIFIED_KEY as ce } from "./validators/useCouponBlockValidator.js";
|
|
23
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",
|
|
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());
|
|
25
25
|
function be(t) {
|
|
26
26
|
return ae(t).map((i) => ({
|
|
27
27
|
rule: o.CouponTagModified,
|
|
@@ -45,22 +45,22 @@ function ve(t) {
|
|
|
45
45
|
}));
|
|
46
46
|
}
|
|
47
47
|
function De(t, i) {
|
|
48
|
-
const n = t.match(
|
|
48
|
+
const n = t.match(R);
|
|
49
49
|
if (!n)
|
|
50
50
|
return [];
|
|
51
|
-
const
|
|
51
|
+
const c = [];
|
|
52
52
|
return n.forEach((u) => {
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
55
|
-
const [d] =
|
|
56
|
-
Le(d) && !i.includes(d) &&
|
|
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({
|
|
57
57
|
rule: o.CustomFieldScript,
|
|
58
58
|
type: r.Warning,
|
|
59
59
|
key: I,
|
|
60
60
|
detail: d
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
|
-
}),
|
|
63
|
+
}), c;
|
|
64
64
|
}
|
|
65
65
|
function Ke(t) {
|
|
66
66
|
return t.length > 0 ? [] : [{ rule: o.EmptyHtml, type: r.Warning, key: de }];
|
|
@@ -85,26 +85,26 @@ function Be(t) {
|
|
|
85
85
|
detail: i
|
|
86
86
|
}));
|
|
87
87
|
}
|
|
88
|
-
function Ye(t, i, n,
|
|
88
|
+
function Ye(t, i, n, c) {
|
|
89
89
|
const u = ie(t);
|
|
90
|
-
return oe(t, i, u, n,
|
|
90
|
+
return oe(t, i, u, n, c).map((a) => ({
|
|
91
91
|
rule: o.InvalidCustomField,
|
|
92
92
|
type: r.Error,
|
|
93
93
|
key: I,
|
|
94
|
-
detail:
|
|
94
|
+
detail: a
|
|
95
95
|
}));
|
|
96
96
|
}
|
|
97
97
|
function xe(t) {
|
|
98
|
-
const i = t.match(/{%(.*?)%}/g), n = [],
|
|
98
|
+
const i = t.match(/{%(.*?)%}/g), n = [], c = [];
|
|
99
99
|
if (i && i.forEach((u) => {
|
|
100
|
-
const
|
|
101
|
-
(!
|
|
100
|
+
const a = u.match(Y), d = u.match(x), E = (a == null ? void 0 : a.join("")) || "";
|
|
101
|
+
(!a || u !== E) && !d && c.push({
|
|
102
102
|
rule: o.ConditionsSyntax,
|
|
103
103
|
type: r.Error,
|
|
104
104
|
key: fe,
|
|
105
105
|
detail: u
|
|
106
|
-
}),
|
|
107
|
-
g.trim() === "=" &&
|
|
106
|
+
}), a && a.forEach((g) => {
|
|
107
|
+
g.trim() === "=" && c.push({
|
|
108
108
|
rule: o.WrongEqualityOperator,
|
|
109
109
|
type: r.Error,
|
|
110
110
|
key: ye
|
|
@@ -113,14 +113,14 @@ function xe(t) {
|
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
115
|
}), n.length) {
|
|
116
|
-
const u = n.filter((d) => d === "if").length,
|
|
117
|
-
u !==
|
|
116
|
+
const u = n.filter((d) => d === "if").length, a = n.filter((d) => d === "endif").length;
|
|
117
|
+
u !== a && c.push({
|
|
118
118
|
rule: o.MissingIfEndif,
|
|
119
119
|
type: r.Error,
|
|
120
120
|
key: Ee
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
-
return
|
|
123
|
+
return c;
|
|
124
124
|
}
|
|
125
125
|
function Me(t) {
|
|
126
126
|
const i = (t.match(/{% /gm) || []).length, n = (t.match(/ %}/gm) || []).length;
|
|
@@ -131,29 +131,29 @@ function Me(t) {
|
|
|
131
131
|
}];
|
|
132
132
|
}
|
|
133
133
|
function Ue(t) {
|
|
134
|
-
return (t.match(
|
|
134
|
+
return (t.match(R) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, c) => n + c, 0) === 0 ? [] : [{
|
|
135
135
|
rule: o.BracesInsideIfTag,
|
|
136
136
|
type: r.Warning,
|
|
137
137
|
key: Se
|
|
138
138
|
}];
|
|
139
139
|
}
|
|
140
140
|
function Pe(t) {
|
|
141
|
-
return (t.match(
|
|
141
|
+
return (t.match(Oe) ?? []).map((i) => ({
|
|
142
142
|
rule: o.InvalidImageType,
|
|
143
143
|
type: r.Error,
|
|
144
144
|
key: Ce,
|
|
145
145
|
detail: i
|
|
146
146
|
}));
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function O(t, i, n, c) {
|
|
149
149
|
const u = new DOMParser().parseFromString(t, "text/html");
|
|
150
|
-
return Array.from(u.querySelectorAll(i)).filter((
|
|
150
|
+
return Array.from(u.querySelectorAll(i)).filter((a) => {
|
|
151
151
|
var d;
|
|
152
|
-
return !((d =
|
|
153
|
-
}).map(() => ({ rule: n, type: r.Error, key:
|
|
152
|
+
return !((d = a.id) != null && d.trim());
|
|
153
|
+
}).map(() => ({ rule: n, type: r.Error, key: c }));
|
|
154
154
|
}
|
|
155
155
|
const dt = () => {
|
|
156
|
-
const { config: t, isFeatureEnabled: i } = J(), n = se(), { post:
|
|
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) => ({
|
|
157
157
|
rule: e.rule,
|
|
158
158
|
type: e.type,
|
|
159
159
|
detail: e.detail,
|
|
@@ -169,25 +169,25 @@ const dt = () => {
|
|
|
169
169
|
return te(y.filterList);
|
|
170
170
|
}, A = async (e) => {
|
|
171
171
|
try {
|
|
172
|
-
const
|
|
173
|
-
return
|
|
172
|
+
const l = await c(Fe, { html: T(e) }), { status: s, message: m } = l.data, p = [];
|
|
173
|
+
return s || p.push({
|
|
174
174
|
rule: o.InvalidLinks,
|
|
175
175
|
type: r.Error,
|
|
176
176
|
// status===undefined means a bare message instead of a boolean; surface it,
|
|
177
177
|
// but fall back to the canned key when it's missing so a malformed body
|
|
178
178
|
// never renders a literal 'undefined' row (SD-147430).
|
|
179
|
-
...
|
|
179
|
+
...s === void 0 && m ? { message: m } : { key: Te }
|
|
180
180
|
}), m === n(k) && p.push({
|
|
181
181
|
rule: o.LinkCheckInProgress,
|
|
182
182
|
type: r.Error,
|
|
183
183
|
key: k
|
|
184
184
|
}), p;
|
|
185
|
-
} catch (
|
|
186
|
-
return console.warn("Link-check collector failed; skipping the link rule.",
|
|
185
|
+
} catch (l) {
|
|
186
|
+
return console.warn("Link-check collector failed; skipping the link rule.", l), [];
|
|
187
187
|
}
|
|
188
188
|
}, v = async (e) => {
|
|
189
189
|
try {
|
|
190
|
-
const
|
|
190
|
+
const l = await c("/newsletter/contents/validate-syntax", [{
|
|
191
191
|
identifier: "default",
|
|
192
192
|
syntax: "liquid",
|
|
193
193
|
contents: {
|
|
@@ -197,23 +197,21 @@ const dt = () => {
|
|
|
197
197
|
ampHtml: null
|
|
198
198
|
}
|
|
199
199
|
}]);
|
|
200
|
-
if (!Array.isArray(
|
|
201
|
-
const m =
|
|
200
|
+
if (!Array.isArray(l.data)) {
|
|
201
|
+
const m = l.data;
|
|
202
202
|
return [{
|
|
203
203
|
rule: o.LiquidSyntax,
|
|
204
204
|
type: r.Warning,
|
|
205
205
|
message: m.message ?? n(F)
|
|
206
206
|
}];
|
|
207
207
|
}
|
|
208
|
-
const [
|
|
209
|
-
return Object.values((
|
|
208
|
+
const [s] = l.data;
|
|
209
|
+
return Object.values((s == null ? void 0 : s.errors) ?? {}).map((m) => ({
|
|
210
210
|
rule: o.LiquidSyntax,
|
|
211
211
|
type: r.Warning,
|
|
212
212
|
message: m.replace(/^line \d+:\s*/, "")
|
|
213
213
|
}));
|
|
214
|
-
} catch
|
|
215
|
-
if (s != null && s.authReported)
|
|
216
|
-
throw s;
|
|
214
|
+
} catch {
|
|
217
215
|
return [{
|
|
218
216
|
rule: o.LiquidSyntax,
|
|
219
217
|
type: r.Error,
|
|
@@ -221,62 +219,62 @@ const dt = () => {
|
|
|
221
219
|
}];
|
|
222
220
|
}
|
|
223
221
|
}, D = () => {
|
|
224
|
-
const e = Object.values(y.blockStates).map((
|
|
225
|
-
const m =
|
|
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);
|
|
226
224
|
return {
|
|
227
225
|
rule: o.RecommendationRequiredFields,
|
|
228
226
|
type: m ? r.Warning : r.Error,
|
|
229
227
|
key: m ? H : V
|
|
230
228
|
};
|
|
231
|
-
}),
|
|
229
|
+
}), l = (f.recommendationConfigs ?? []).filter((s) => s.filters.some((m) => m.value === "")).map(() => ({
|
|
232
230
|
rule: o.RecommendationFilters,
|
|
233
231
|
type: r.Error,
|
|
234
232
|
key: _e
|
|
235
233
|
}));
|
|
236
|
-
return [...e, ...
|
|
237
|
-
}, K = async (e,
|
|
234
|
+
return [...e, ...l];
|
|
235
|
+
}, K = async (e, l) => {
|
|
238
236
|
var C, h;
|
|
239
|
-
const
|
|
240
|
-
...
|
|
237
|
+
const s = [
|
|
238
|
+
...l.map((w) => w.value),
|
|
241
239
|
...U,
|
|
242
240
|
...((h = (C = t.value) == null ? void 0 : C.template) == null ? void 0 : h.customFieldAttributes) ?? []
|
|
243
241
|
], m = B(e), p = await b(m), { isTransactional: _ } = L;
|
|
244
242
|
return [
|
|
245
243
|
...await A(e),
|
|
246
|
-
..._ ? [] : De(e,
|
|
244
|
+
..._ ? [] : De(e, s),
|
|
247
245
|
...Ke(e),
|
|
248
246
|
...we(e),
|
|
249
247
|
...Be(e),
|
|
250
|
-
..._ ? [] : Ye(e,
|
|
248
|
+
..._ ? [] : Ye(e, s, m, p),
|
|
251
249
|
...xe(e),
|
|
252
250
|
...Me(e),
|
|
253
251
|
...Ue(e),
|
|
254
252
|
...D(),
|
|
255
253
|
...Pe(e),
|
|
256
|
-
...
|
|
254
|
+
...O(
|
|
257
255
|
e,
|
|
258
256
|
M,
|
|
259
257
|
o.CheckboxUnsubGroup,
|
|
260
258
|
he
|
|
261
259
|
),
|
|
262
|
-
...
|
|
260
|
+
...O(
|
|
263
261
|
e,
|
|
264
262
|
P,
|
|
265
263
|
o.RadioButtonUnsubGroup,
|
|
266
264
|
ke
|
|
267
265
|
)
|
|
268
266
|
];
|
|
269
|
-
}, S = async (e,
|
|
267
|
+
}, S = async (e, l) => [
|
|
270
268
|
...be(e),
|
|
271
269
|
...Ae(e),
|
|
272
270
|
...ve(e),
|
|
273
|
-
...i("liquidSyntax") ? await v(e) : await K(e,
|
|
271
|
+
...i("liquidSyntax") ? await v(e) : await K(e, l)
|
|
274
272
|
].map(N);
|
|
275
273
|
return { collectSaveValidationErrors: S, validateCurrentTemplate: async () => {
|
|
276
|
-
const { html: e } = await
|
|
274
|
+
const { html: e } = await a();
|
|
277
275
|
await E(e);
|
|
278
|
-
const { html:
|
|
279
|
-
return S(
|
|
276
|
+
const { html: l } = await u({ minimize: !0, resetDataSavedFlag: !1 }), { compiledHtml: s } = d(l);
|
|
277
|
+
return S(s, g.getSelectedDynamicContentList);
|
|
280
278
|
} };
|
|
281
279
|
};
|
|
282
280
|
export {
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const t = s();
|
|
7
|
-
return { isEnabled: a(() => t.isEmailAutoSaveEnabled), loadRollout: () => t.isLoaded ? Promise.resolve() : (o ?? (o = l().getSetupSettings().then(({ isEmailAutoSaveEnabled: e }) => {
|
|
8
|
-
t.$patch({
|
|
9
|
-
isEmailAutoSaveEnabled: !!Number(e ?? 0),
|
|
10
|
-
isLoaded: !0
|
|
11
|
-
});
|
|
12
|
-
}).catch((e) => {
|
|
13
|
-
console.warn("Failed to load setup settings; soft-save stays off.", e);
|
|
14
|
-
}).finally(() => {
|
|
15
|
-
o = null;
|
|
16
|
-
})), o) };
|
|
1
|
+
import { useConfigStore as t } from "../stores/config.js";
|
|
2
|
+
import { computed as o } from "vue";
|
|
3
|
+
const n = ["newsletteruatcamp", "newsletterqacamp"], c = () => {
|
|
4
|
+
const e = t();
|
|
5
|
+
return { isEnabled: o(() => n.includes(e.partnerName)) };
|
|
17
6
|
};
|
|
18
7
|
export {
|
|
19
|
-
|
|
8
|
+
c as useSaveValidationRollout
|
|
20
9
|
};
|