@useinsider/guido 3.19.0 → 3.20.0-beta.0849ec7
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/README.md +22 -3
- package/dist/@types/config/schemas.js +76 -53
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +102 -86
- package/dist/components/organisms/AutoSaveController.vue2.js +9 -8
- package/dist/components/organisms/base/AuthErrorModal.vue.js +18 -0
- package/dist/components/organisms/base/AuthErrorModal.vue2.js +42 -0
- package/dist/components/organisms/base/Toaster.vue2.js +13 -12
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -11
- package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +78 -57
- package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
- package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
- package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +28 -42
- package/dist/components/organisms/header/EditorActions.vue.js +5 -5
- package/dist/components/organisms/header/EditorActions.vue2.js +90 -57
- package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
- package/dist/components/organisms/header/LeftSlot.vue2.js +16 -12
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +28 -24
- package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.js +21 -0
- package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue2.js +46 -0
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
- package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +47 -0
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +20 -0
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +49 -0
- package/dist/components/wrappers/WpDrawer.vue.js +9 -7
- package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
- package/dist/components/wrappers/WpModal.vue.js +1 -1
- package/dist/components/wrappers/WpModal.vue2.js +4 -3
- package/dist/composables/useActionsApi.js +52 -47
- package/dist/composables/useAuthError.js +52 -0
- package/dist/composables/useAutoSave.js +11 -11
- package/dist/composables/useCodeEditorApi.js +23 -9
- package/dist/composables/useCortexBlueprintBridge.js +122 -54
- package/dist/composables/useCustomInterfaceAppearance.js +65 -51
- package/dist/composables/useEmailTemplateApplier.js +111 -50
- package/dist/composables/useHtmlCompiler.js +37 -26
- package/dist/composables/useHtmlValidator.js +89 -82
- package/dist/composables/useHttp.js +64 -54
- package/dist/composables/useLegacyStrategyConversion.js +65 -0
- package/dist/composables/useRecommendation.js +40 -35
- package/dist/composables/useSave.js +90 -45
- package/dist/composables/useSaveValidation.js +282 -0
- package/dist/composables/useSaveValidationRollout.js +9 -0
- package/dist/composables/useStripo.js +43 -39
- package/dist/composables/useToaster.js +18 -22
- package/dist/composables/useTranslations.js +3 -2
- package/dist/composables/useVersionHistoryApi.js +33 -24
- package/dist/composables/validators/useCouponBlockValidator.js +24 -21
- package/dist/composables/validators/useLiquidValidator.js +15 -15
- package/dist/composables/validators/useUnsubscribeBlockValidator.js +34 -27
- package/dist/config/migrator/index.js +14 -13
- package/dist/config/migrator/itemsBlockMigrator.js +236 -248
- package/dist/config/migrator/recommendationMigrator.js +28 -21
- package/dist/config/migrator/recommendationPartnerMigrator.js +56 -0
- package/dist/enums/extensions/recommendationBlock.js +51 -34
- package/dist/enums/save-validation.js +4 -0
- package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
- package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
- package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
- package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
- package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
- package/dist/extensions/Blocks/Items/template.js +219 -204
- package/dist/extensions/Blocks/Recommendation/block.js +65 -45
- package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +21 -20
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +103 -90
- package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +150 -52
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +274 -92
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +42 -0
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +26 -16
- package/dist/extensions/Blocks/Recommendation/utils/partnerCustomizations.js +3 -1
- package/dist/extensions/Blocks/Recommendation/utils/partnerScope.js +25 -0
- package/dist/extensions/Blocks/Recommendation/utils/productIds.js +5 -3
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +24 -0
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +21 -12
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +46 -37
- package/dist/src/@types/config/schemas.d.ts +36 -0
- package/dist/src/@types/save-validation.d.ts +19 -0
- package/dist/src/components/Guido.vue.d.ts +17 -1
- package/dist/src/components/organisms/base/AuthErrorModal.vue.d.ts +2 -0
- package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +17 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +17 -1
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +17 -1
- package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts +2 -0
- package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
- package/dist/src/components/organisms/validation/ValidationErrorDrawer.vue.d.ts +2 -0
- package/dist/src/components/wrappers/WpDrawer.vue.d.ts +4 -3
- package/dist/src/components/wrappers/WpModal.vue.d.ts +5 -1
- package/dist/src/composables/useAuthError.d.ts +12 -0
- package/dist/src/composables/useConfig.d.ts +8 -0
- package/dist/src/composables/useCortexBlueprintBridge.d.ts +2 -3
- package/dist/src/composables/useEmailTemplateApplier.d.ts +18 -5
- package/dist/src/composables/useGuidoActions.d.ts +2 -0
- package/dist/src/composables/useHtmlValidator.d.ts +21 -0
- package/dist/src/composables/useHttp.d.ts +2 -0
- package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
- package/dist/src/composables/useSave.d.ts +6 -1
- package/dist/src/composables/useSaveValidation.d.ts +6 -0
- package/dist/src/composables/useSaveValidationRollout.d.ts +3 -0
- package/dist/src/composables/validators/useCouponBlockValidator.d.ts +3 -0
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +10 -0
- package/dist/src/config/migrator/index.d.ts +2 -1
- package/dist/src/config/migrator/recommendationPartnerMigrator.d.ts +19 -0
- package/dist/src/enums/extensions/recommendationBlock.d.ts +7 -1
- package/dist/src/enums/save-validation.d.ts +27 -0
- package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
- package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
- package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +10 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +7 -2
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +162 -1
- package/dist/src/extensions/Blocks/Recommendation/types/nodeConfig.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +32 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/partnerScope.d.ts +33 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +14 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +4 -0
- package/dist/src/mock/cortexChatStore.d.ts +12 -0
- package/dist/src/services/recommendationApi.d.ts +2 -1
- package/dist/src/stores/config.d.ts +374 -0
- package/dist/src/stores/guido-email-editor.d.ts +20 -10
- package/dist/src/stores/onboarding.d.ts +812 -10
- package/dist/src/stores/recommendation.d.ts +5 -0
- package/dist/src/stores/save-validation.d.ts +22 -0
- package/dist/src/utils/dateUtil.d.ts +10 -0
- package/dist/src/utils/genericUtil.d.ts +3 -0
- package/dist/src/utils/stripoEditorApi.d.ts +4 -0
- package/dist/src/utils/templatePreparation.d.ts +30 -0
- package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
- package/dist/static/assets/icons/line-info.svg.js +5 -0
- package/dist/static/styles/components/recommendation-strategy.css.js +113 -9
- package/dist/static/styles/components/skeleton.css.js +23 -0
- package/dist/static/styles/components/version-history.css.js +2 -6
- package/dist/stores/config.js +55 -24
- package/dist/stores/guido-email-editor.js +3 -1
- package/dist/stores/onboarding.js +50 -36
- package/dist/stores/save-validation.js +30 -0
- package/dist/stores/unsubscribe.js +3 -3
- package/dist/utils/pairProductVariables.js +71 -71
- package/dist/utils/stripoEditorApi.js +11 -0
- package/dist/utils/templatePreparation.js +54 -51
- package/package.json +2 -1
|
@@ -1,55 +1,100 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
1
|
+
import { useActionsApi as W } from "./useActionsApi.js";
|
|
2
2
|
import { useConfig as q } from "./useConfig.js";
|
|
3
|
-
import { useEditorLock as
|
|
4
|
-
import { useSaveStart as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
if (
|
|
3
|
+
import { useEditorLock as O } from "./useEditorLock.js";
|
|
4
|
+
import { useSaveStart as D, useSaveComplete as F } from "./useGuidoActions.js";
|
|
5
|
+
import { useSaveValidation as j } from "./useSaveValidation.js";
|
|
6
|
+
import { useSaveValidationRollout as z } from "./useSaveValidationRollout.js";
|
|
7
|
+
import { useSyncModuleExtractor as G } from "./useSyncModuleExtractor.js";
|
|
8
|
+
import { ToasterTypeOptions as I } from "../enums/toaster.js";
|
|
9
|
+
import { useStripoApi as J } from "../services/stripoApi.js";
|
|
10
|
+
import { useConfigStore as K } from "../stores/config.js";
|
|
11
|
+
import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
|
|
12
|
+
import { useSaveValidationStore as Q } from "../stores/save-validation.js";
|
|
13
|
+
import { useTemplatePreparation as X, getHtmlReferencedUnsubscribePages as Y } from "../utils/templatePreparation.js";
|
|
14
|
+
import { useAllowlist as Z } from "./useAllowlist.js";
|
|
15
|
+
import { useHtmlValidator as _ } from "./useHtmlValidator.js";
|
|
16
|
+
import { useToaster as $ } from "./useToaster.js";
|
|
17
|
+
import { useCouponBlockValidator as tt } from "./validators/useCouponBlockValidator.js";
|
|
18
|
+
import { useLiquidValidator as et } from "./validators/useLiquidValidator.js";
|
|
19
|
+
import { useSyncModuleBlockValidator as ot } from "./validators/useSyncModuleBlockValidator.js";
|
|
20
|
+
import { useUnsubscribeBlockValidator as st } from "./validators/useUnsubscribeBlockValidator.js";
|
|
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"))
|
|
24
|
+
return !1;
|
|
25
|
+
const i = await x(t, e);
|
|
26
|
+
if (!i.length)
|
|
27
|
+
return !1;
|
|
28
|
+
if (!o) {
|
|
29
|
+
const s = await k(i);
|
|
30
|
+
s != null && s.message && V({
|
|
31
|
+
type: I.Warning,
|
|
32
|
+
message: s.message,
|
|
33
|
+
actionButton: s.actionButton
|
|
34
|
+
});
|
|
35
|
+
}
|
|
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())
|
|
29
39
|
return;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
const { unsubscribePayload: i, stripoModules: s } = b(t.rawHtml);
|
|
41
|
+
if (await g(i), t.modules = s, !e.suppress) {
|
|
42
|
+
const R = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
|
|
43
|
+
f({ ...t, ...R, silent: e.silent });
|
|
44
|
+
}
|
|
45
|
+
return t;
|
|
46
|
+
}, U = async (t, e) => {
|
|
47
|
+
var i;
|
|
48
|
+
r();
|
|
49
|
+
const o = await d();
|
|
50
|
+
if (n(o.rawHtml, e)) {
|
|
51
|
+
if (B.value && !e) {
|
|
52
|
+
const s = await C(
|
|
53
|
+
o.compiledHtml,
|
|
54
|
+
o.dynamicContentList
|
|
55
|
+
);
|
|
56
|
+
if (s.length) {
|
|
57
|
+
T.open(s, "save");
|
|
58
|
+
return;
|
|
40
59
|
}
|
|
60
|
+
} else if (!await L(o))
|
|
41
61
|
return;
|
|
42
|
-
|
|
62
|
+
if (!((i = a.value) != null && i.externalValidation && !await a.value.externalValidation(o)) && !await c(o.compiledHtml, o.css, e))
|
|
63
|
+
return u(o, { silent: e, suppress: t });
|
|
43
64
|
}
|
|
44
|
-
|
|
65
|
+
}, A = async () => {
|
|
66
|
+
var e;
|
|
67
|
+
if (!P.allowSaveWithErrors)
|
|
45
68
|
return;
|
|
46
|
-
|
|
47
|
-
|
|
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
|
+
return u(t, { silent: !1, blankCompiled: !0 });
|
|
73
|
+
}, M = async () => {
|
|
74
|
+
r();
|
|
75
|
+
const { html: t, css: e } = await H();
|
|
76
|
+
if (!n(t, !0) || await c(t, e, !0))
|
|
77
|
+
return;
|
|
78
|
+
const o = Y(t), i = {
|
|
79
|
+
dynamicContentList: h.getSelectedDynamicContentList,
|
|
80
|
+
compiledHtml: "",
|
|
81
|
+
rawHtml: t,
|
|
82
|
+
css: e,
|
|
83
|
+
ampHtml: "",
|
|
84
|
+
ampErrors: [],
|
|
85
|
+
modules: [],
|
|
86
|
+
recommendation: { campaignUrls: {}, configs: {} },
|
|
87
|
+
unsubscribe: {
|
|
88
|
+
status: o.length > 0,
|
|
89
|
+
config: o
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
return u(i, { silent: !0 });
|
|
48
93
|
};
|
|
49
|
-
return { save: (
|
|
50
|
-
() =>
|
|
51
|
-
) };
|
|
94
|
+
return { save: (t = !1, e = !1) => l(
|
|
95
|
+
() => U(t, e)
|
|
96
|
+
), saveWithErrors: () => l(A), saveRawOnly: () => l(M) };
|
|
52
97
|
};
|
|
53
98
|
export {
|
|
54
|
-
|
|
99
|
+
Bt as useSave
|
|
55
100
|
};
|
|
@@ -0,0 +1,282 @@
|
|
|
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";
|
|
3
|
+
import { SaveValidationRule as o } from "../enums/save-validation.js";
|
|
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";
|
|
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());
|
|
25
|
+
function be(t) {
|
|
26
|
+
return ae(t).map((i) => ({
|
|
27
|
+
rule: o.CouponTagModified,
|
|
28
|
+
type: r.Warning,
|
|
29
|
+
key: ce,
|
|
30
|
+
detail: i
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
function Ae(t) {
|
|
34
|
+
return le(t).map((i) => ({
|
|
35
|
+
rule: o.DuplicateUnsubBlock,
|
|
36
|
+
type: r.Error,
|
|
37
|
+
key: i.messageKey
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
function ve(t) {
|
|
41
|
+
return Array.from({ length: me(t) }, () => ({
|
|
42
|
+
rule: o.UnsubBlockMissingTemplate,
|
|
43
|
+
type: r.Warning,
|
|
44
|
+
key: ue
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
function De(t, i) {
|
|
48
|
+
const n = t.match(R);
|
|
49
|
+
if (!n)
|
|
50
|
+
return [];
|
|
51
|
+
const c = [];
|
|
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({
|
|
57
|
+
rule: o.CustomFieldScript,
|
|
58
|
+
type: r.Warning,
|
|
59
|
+
key: I,
|
|
60
|
+
detail: d
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}), c;
|
|
64
|
+
}
|
|
65
|
+
function Ke(t) {
|
|
66
|
+
return t.length > 0 ? [] : [{ rule: o.EmptyHtml, type: r.Warning, key: de }];
|
|
67
|
+
}
|
|
68
|
+
function we(t) {
|
|
69
|
+
const i = (t.match(/{/gm) || []).length, n = (t.match(/}/gm) || []).length;
|
|
70
|
+
return i > n ? [{
|
|
71
|
+
rule: o.MismatchedBraces,
|
|
72
|
+
type: r.Warning,
|
|
73
|
+
key: pe
|
|
74
|
+
}] : i < n ? [{
|
|
75
|
+
rule: o.MismatchedBraces,
|
|
76
|
+
type: r.Warning,
|
|
77
|
+
key: ge
|
|
78
|
+
}] : [];
|
|
79
|
+
}
|
|
80
|
+
function Be(t) {
|
|
81
|
+
return ne(t).map((i) => ({
|
|
82
|
+
rule: o.InvalidDynamicTag,
|
|
83
|
+
type: r.Warning,
|
|
84
|
+
key: I,
|
|
85
|
+
detail: i
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
function Ye(t, i, n, c) {
|
|
89
|
+
const u = ie(t);
|
|
90
|
+
return oe(t, i, u, n, c).map((a) => ({
|
|
91
|
+
rule: o.InvalidCustomField,
|
|
92
|
+
type: r.Error,
|
|
93
|
+
key: I,
|
|
94
|
+
detail: a
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
function xe(t) {
|
|
98
|
+
const i = t.match(/{%(.*?)%}/g), n = [], c = [];
|
|
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({
|
|
102
|
+
rule: o.ConditionsSyntax,
|
|
103
|
+
type: r.Error,
|
|
104
|
+
key: fe,
|
|
105
|
+
detail: u
|
|
106
|
+
}), a && a.forEach((g) => {
|
|
107
|
+
g.trim() === "=" && c.push({
|
|
108
|
+
rule: o.WrongEqualityOperator,
|
|
109
|
+
type: r.Error,
|
|
110
|
+
key: ye
|
|
111
|
+
}), (g.match(/^[a-zA-Z]*$/g) ?? []).forEach((f) => {
|
|
112
|
+
Ne(f) && n.push(f);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}), n.length) {
|
|
116
|
+
const u = n.filter((d) => d === "if").length, a = n.filter((d) => d === "endif").length;
|
|
117
|
+
u !== a && c.push({
|
|
118
|
+
rule: o.MissingIfEndif,
|
|
119
|
+
type: r.Error,
|
|
120
|
+
key: Ee
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return c;
|
|
124
|
+
}
|
|
125
|
+
function Me(t) {
|
|
126
|
+
const i = (t.match(/{% /gm) || []).length, n = (t.match(/ %}/gm) || []).length;
|
|
127
|
+
return i === n ? [] : [{
|
|
128
|
+
rule: o.ConditionTagSpacing,
|
|
129
|
+
type: r.Warning,
|
|
130
|
+
key: Ie
|
|
131
|
+
}];
|
|
132
|
+
}
|
|
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 ? [] : [{
|
|
135
|
+
rule: o.BracesInsideIfTag,
|
|
136
|
+
type: r.Warning,
|
|
137
|
+
key: Se
|
|
138
|
+
}];
|
|
139
|
+
}
|
|
140
|
+
function Pe(t) {
|
|
141
|
+
return (t.match(Oe) ?? []).map((i) => ({
|
|
142
|
+
rule: o.InvalidImageType,
|
|
143
|
+
type: r.Error,
|
|
144
|
+
key: Ce,
|
|
145
|
+
detail: i
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
function O(t, i, n, c) {
|
|
149
|
+
const u = new DOMParser().parseFromString(t, "text/html");
|
|
150
|
+
return Array.from(u.querySelectorAll(i)).filter((a) => {
|
|
151
|
+
var d;
|
|
152
|
+
return !((d = a.id) != null && d.trim());
|
|
153
|
+
}).map(() => ({ rule: n, type: r.Error, key: c }));
|
|
154
|
+
}
|
|
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) => ({
|
|
157
|
+
rule: e.rule,
|
|
158
|
+
type: e.type,
|
|
159
|
+
detail: e.detail,
|
|
160
|
+
message: "key" in e ? n(e.key) : $(e.message)
|
|
161
|
+
}), b = async (e) => {
|
|
162
|
+
if (e.size === 0)
|
|
163
|
+
return /* @__PURE__ */ new Set();
|
|
164
|
+
try {
|
|
165
|
+
await y.fetchRecommendationFilters();
|
|
166
|
+
} catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
return te(y.filterList);
|
|
170
|
+
}, A = async (e) => {
|
|
171
|
+
try {
|
|
172
|
+
const l = await c(Fe, { html: T(e) }), { status: s, message: m } = l.data, p = [];
|
|
173
|
+
return s || p.push({
|
|
174
|
+
rule: o.InvalidLinks,
|
|
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 }
|
|
180
|
+
}), m === n(k) && p.push({
|
|
181
|
+
rule: o.LinkCheckInProgress,
|
|
182
|
+
type: r.Error,
|
|
183
|
+
key: k
|
|
184
|
+
}), p;
|
|
185
|
+
} catch (l) {
|
|
186
|
+
return console.warn("Link-check collector failed; skipping the link rule.", l), [];
|
|
187
|
+
}
|
|
188
|
+
}, v = async (e) => {
|
|
189
|
+
try {
|
|
190
|
+
const l = await c("/newsletter/contents/validate-syntax", [{
|
|
191
|
+
identifier: "default",
|
|
192
|
+
syntax: "liquid",
|
|
193
|
+
contents: {
|
|
194
|
+
subject: null,
|
|
195
|
+
preheader: null,
|
|
196
|
+
html: T(e),
|
|
197
|
+
ampHtml: null
|
|
198
|
+
}
|
|
199
|
+
}]);
|
|
200
|
+
if (!Array.isArray(l.data)) {
|
|
201
|
+
const m = l.data;
|
|
202
|
+
return [{
|
|
203
|
+
rule: o.LiquidSyntax,
|
|
204
|
+
type: r.Warning,
|
|
205
|
+
message: m.message ?? n(F)
|
|
206
|
+
}];
|
|
207
|
+
}
|
|
208
|
+
const [s] = l.data;
|
|
209
|
+
return Object.values((s == null ? void 0 : s.errors) ?? {}).map((m) => ({
|
|
210
|
+
rule: o.LiquidSyntax,
|
|
211
|
+
type: r.Warning,
|
|
212
|
+
message: m.replace(/^line \d+:\s*/, "")
|
|
213
|
+
}));
|
|
214
|
+
} catch {
|
|
215
|
+
return [{
|
|
216
|
+
rule: o.LiquidSyntax,
|
|
217
|
+
type: r.Error,
|
|
218
|
+
message: n(F)
|
|
219
|
+
}];
|
|
220
|
+
}
|
|
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);
|
|
224
|
+
return {
|
|
225
|
+
rule: o.RecommendationRequiredFields,
|
|
226
|
+
type: m ? r.Warning : r.Error,
|
|
227
|
+
key: m ? H : V
|
|
228
|
+
};
|
|
229
|
+
}), l = (f.recommendationConfigs ?? []).filter((s) => s.filters.some((m) => m.value === "")).map(() => ({
|
|
230
|
+
rule: o.RecommendationFilters,
|
|
231
|
+
type: r.Error,
|
|
232
|
+
key: _e
|
|
233
|
+
}));
|
|
234
|
+
return [...e, ...l];
|
|
235
|
+
}, K = async (e, l) => {
|
|
236
|
+
var C, h;
|
|
237
|
+
const s = [
|
|
238
|
+
...l.map((w) => w.value),
|
|
239
|
+
...U,
|
|
240
|
+
...((h = (C = t.value) == null ? void 0 : C.template) == null ? void 0 : h.customFieldAttributes) ?? []
|
|
241
|
+
], m = B(e), p = await b(m), { isTransactional: _ } = L;
|
|
242
|
+
return [
|
|
243
|
+
...await A(e),
|
|
244
|
+
..._ ? [] : De(e, s),
|
|
245
|
+
...Ke(e),
|
|
246
|
+
...we(e),
|
|
247
|
+
...Be(e),
|
|
248
|
+
..._ ? [] : Ye(e, s, m, p),
|
|
249
|
+
...xe(e),
|
|
250
|
+
...Me(e),
|
|
251
|
+
...Ue(e),
|
|
252
|
+
...D(),
|
|
253
|
+
...Pe(e),
|
|
254
|
+
...O(
|
|
255
|
+
e,
|
|
256
|
+
M,
|
|
257
|
+
o.CheckboxUnsubGroup,
|
|
258
|
+
he
|
|
259
|
+
),
|
|
260
|
+
...O(
|
|
261
|
+
e,
|
|
262
|
+
P,
|
|
263
|
+
o.RadioButtonUnsubGroup,
|
|
264
|
+
ke
|
|
265
|
+
)
|
|
266
|
+
];
|
|
267
|
+
}, S = async (e, l) => [
|
|
268
|
+
...be(e),
|
|
269
|
+
...Ae(e),
|
|
270
|
+
...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);
|
|
278
|
+
} };
|
|
279
|
+
};
|
|
280
|
+
export {
|
|
281
|
+
dt as useSaveValidation
|
|
282
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
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)) };
|
|
6
|
+
};
|
|
7
|
+
export {
|
|
8
|
+
c as useSaveValidationRollout
|
|
9
|
+
};
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useBlocksConfig as
|
|
3
|
-
import { useConfig as
|
|
4
|
-
import { useCustomInterfaceAppearance as
|
|
1
|
+
import { useActionsApi as L } from "./useActionsApi.js";
|
|
2
|
+
import { useBlocksConfig as O } from "./useBlocksConfig.js";
|
|
3
|
+
import { useConfig as H } from "./useConfig.js";
|
|
4
|
+
import { useCustomInterfaceAppearance as w } from "./useCustomInterfaceAppearance.js";
|
|
5
5
|
import { useFullStoryBridge as N } from "./useFullStoryBridge.js";
|
|
6
6
|
import { useModuleRepair as j } from "./useModuleRepair.js";
|
|
7
7
|
import { useStripoEventHandler as z } from "./useStripoEventHandler.js";
|
|
8
8
|
import { useStripoNotifications as $ } from "./useStripoNotifications.js";
|
|
9
9
|
import { useToaster as G } from "./useToaster.js";
|
|
10
10
|
import { localePatch as J } from "../config/i18n/index.js";
|
|
11
|
-
import { en as
|
|
11
|
+
import { en as b } from "../config/i18n/en/index.js";
|
|
12
12
|
import { ToasterTypeOptions as X } from "../enums/toaster.js";
|
|
13
13
|
import { useStripoApi as K } from "../services/stripoApi.js";
|
|
14
14
|
import Q from "../static/styles/customEditorStyle.css.js";
|
|
15
|
-
import { useEditorStore as
|
|
15
|
+
import { useEditorStore as k } from "../stores/editor.js";
|
|
16
16
|
import { buildMergeTagEntries as W, flattenDynamicContentList as Y } from "../utils/genericUtil.js";
|
|
17
17
|
import Z from "../package.json.js";
|
|
18
18
|
let n = null;
|
|
19
|
-
const
|
|
20
|
-
const { features: c, template: u, isFeatureEnabled:
|
|
19
|
+
const he = () => {
|
|
20
|
+
const { features: c, template: u, isFeatureEnabled: p } = H(), { handleError: m, showToaster: v } = G(), { getToken: B, getCustomFonts: M, getSyncModulesStatus: T } = K(), { handleEvent: F } = z(), { handleModuleAdd: A } = j(), { getStripoBlocksConfig: V } = O(), { getStripoNotifications: _ } = $(), f = () => n || (n = new Promise((r, s) => {
|
|
21
21
|
var d;
|
|
22
22
|
if (document.getElementById("UiEditorScript")) {
|
|
23
|
-
|
|
23
|
+
r();
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
const o = Z.guido,
|
|
27
|
-
e.id = "UiEditorScript", e.type = "module", e.src =
|
|
28
|
-
e.remove(), s(new Error(`Failed to load Stripo UIEditor script from S3: ${
|
|
26
|
+
const o = Z.guido, i = `https://email-static.useinsider.com/guido/${(d = o == null ? void 0 : o.stripo) == null ? void 0 : d.version}/UIEditor.js`, e = document.createElement("script");
|
|
27
|
+
e.id = "UiEditorScript", e.type = "module", e.src = i, e.onload = () => r(), e.onerror = () => {
|
|
28
|
+
e.remove(), s(new Error(`Failed to load Stripo UIEditor script from S3: ${i}`));
|
|
29
29
|
}, document.body.appendChild(e);
|
|
30
30
|
}), n.catch(() => {
|
|
31
31
|
n = null;
|
|
32
|
-
}), n),
|
|
32
|
+
}), n), D = async (r, s, o, a = [], i = !1) => {
|
|
33
33
|
var y, E, h, C;
|
|
34
|
-
const e =
|
|
35
|
-
await window.UIEditor.initEditor(
|
|
34
|
+
const e = k(), { html: d, css: R } = r, { baseBlocks: g, extensions: P } = await V(), S = ((y = c.value) == null ? void 0 : y.displayConditions) ?? !0, U = ((E = c.value) == null ? void 0 : E.modulesDisabled) ?? !1, I = !!d || (((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1), q = "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com";
|
|
35
|
+
w().importCss(), await window.UIEditor.initEditor(
|
|
36
36
|
document.querySelector("#guido-editor"),
|
|
37
37
|
{
|
|
38
38
|
metadata: s,
|
|
39
39
|
html: d,
|
|
40
|
-
css:
|
|
41
|
-
forceRecreate:
|
|
40
|
+
css: R,
|
|
41
|
+
forceRecreate: I,
|
|
42
42
|
locale: "en",
|
|
43
43
|
undoButtonSelector: "#guido__undo-button",
|
|
44
44
|
redoButtonSelector: "#guido__redo-button",
|
|
45
45
|
mobileViewButtonSelector: ".guido__view-option-selection-mobile",
|
|
46
46
|
desktopViewButtonSelector: ".guido__view-option-selection-desktop",
|
|
47
47
|
codeEditorButtonSelector: "#guido__code-button",
|
|
48
|
-
customAppearanceMergetags: !
|
|
48
|
+
customAppearanceMergetags: !p("liquidSyntax"),
|
|
49
49
|
customAppearanceMergetagsBorderColor: "#f1f3fe",
|
|
50
50
|
customAppearanceMergetagsBackgroundColor: "#f1f3fe",
|
|
51
51
|
customViewStyles: Q,
|
|
52
52
|
conditionsEnabled: S,
|
|
53
53
|
customConditionsEnabled: S,
|
|
54
54
|
enableXSSSecurity: !0,
|
|
55
|
-
modulesDisabled:
|
|
56
|
-
syncModulesEnabled:
|
|
55
|
+
modulesDisabled: U,
|
|
56
|
+
syncModulesEnabled: i,
|
|
57
57
|
messageSettingsEnabled: !0,
|
|
58
58
|
displayGmailAnnotations: !0,
|
|
59
59
|
displayHiddenPreheader: !1,
|
|
@@ -62,7 +62,7 @@ const Ce = () => {
|
|
|
62
62
|
displayUTM: !1,
|
|
63
63
|
selectElementAfterDrop: !0,
|
|
64
64
|
sameFontSizeForOutlook: !0,
|
|
65
|
-
allowedScriptSourceDomains:
|
|
65
|
+
allowedScriptSourceDomains: q,
|
|
66
66
|
...g ? { baseBlocks: g } : {},
|
|
67
67
|
editorFonts: {
|
|
68
68
|
showDefaultStandardFonts: !0,
|
|
@@ -74,7 +74,7 @@ const Ce = () => {
|
|
|
74
74
|
entries: W(
|
|
75
75
|
o.preselectedDynamicContentList,
|
|
76
76
|
Y((C = u.value) == null ? void 0 : C.dynamicContentList),
|
|
77
|
-
|
|
77
|
+
p("liquidSyntax")
|
|
78
78
|
)
|
|
79
79
|
}
|
|
80
80
|
],
|
|
@@ -83,17 +83,17 @@ const Ce = () => {
|
|
|
83
83
|
const l = await B();
|
|
84
84
|
t(l);
|
|
85
85
|
} catch (l) {
|
|
86
|
-
|
|
86
|
+
m(l, "Failed to refresh token");
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
89
|
onTemplateLoaded() {
|
|
90
90
|
try {
|
|
91
|
-
const {
|
|
92
|
-
|
|
91
|
+
const { activateCustomViewStyles: t, updateTimerInClonedTemplate: l } = L(), { injectFullStory: x } = N();
|
|
92
|
+
w().importCss(), t(), x(), l(), o.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
|
|
93
93
|
e.hasChanges = !1;
|
|
94
94
|
}, 1e3);
|
|
95
95
|
} catch (t) {
|
|
96
|
-
|
|
96
|
+
m(t, "Failed to load custom interface appearance");
|
|
97
97
|
}
|
|
98
98
|
},
|
|
99
99
|
onCodeEditorVisibilityChanged(t) {
|
|
@@ -108,34 +108,38 @@ const Ce = () => {
|
|
|
108
108
|
onDataChanged() {
|
|
109
109
|
e.hasChanges = !0, e.changeSeq += 1;
|
|
110
110
|
},
|
|
111
|
-
onEvent:
|
|
112
|
-
onModuleAdd:
|
|
113
|
-
notifications:
|
|
111
|
+
onEvent: F,
|
|
112
|
+
onModuleAdd: A,
|
|
113
|
+
notifications: _(),
|
|
114
|
+
// Stripo deselects the block on any click outside the canvas, so every surface
|
|
115
|
+
// that belongs to the block's own flow has to be listed here (SD-153273).
|
|
114
116
|
ignoreClickOutsideSelectors: [
|
|
115
117
|
"#guido-dynamic-content-modal",
|
|
116
118
|
".in-on-board-wrapper",
|
|
117
|
-
".in-drawer__container"
|
|
119
|
+
".in-drawer__container",
|
|
120
|
+
".in-modal-v2-wrapper",
|
|
121
|
+
".in-toasts-wrapper"
|
|
118
122
|
],
|
|
119
|
-
extensions:
|
|
123
|
+
extensions: P,
|
|
120
124
|
localePatch: J
|
|
121
125
|
}
|
|
122
126
|
);
|
|
123
127
|
};
|
|
124
|
-
return { initPlugin: async (
|
|
125
|
-
const a =
|
|
128
|
+
return { initPlugin: async (r, s, o) => {
|
|
129
|
+
const a = k();
|
|
126
130
|
try {
|
|
127
131
|
await f();
|
|
128
|
-
const [
|
|
132
|
+
const [i, e] = await Promise.all([
|
|
129
133
|
M(),
|
|
130
134
|
T()
|
|
131
135
|
]);
|
|
132
|
-
a.syncModulesEnabled = e, await
|
|
136
|
+
a.syncModulesEnabled = e, await D(r, s, o, i, e);
|
|
133
137
|
} catch {
|
|
134
|
-
a.loadingStatus = !1,
|
|
138
|
+
a.loadingStatus = !1, v({
|
|
135
139
|
type: X.Error,
|
|
136
|
-
message:
|
|
140
|
+
message: b["An error has occurred. Please report the error code to support."],
|
|
137
141
|
actionButton: {
|
|
138
|
-
text:
|
|
142
|
+
text: b["Reload page"],
|
|
139
143
|
onClick: () => window.location.reload()
|
|
140
144
|
}
|
|
141
145
|
});
|
|
@@ -146,5 +150,5 @@ const Ce = () => {
|
|
|
146
150
|
} };
|
|
147
151
|
};
|
|
148
152
|
export {
|
|
149
|
-
|
|
153
|
+
he as useStripo
|
|
150
154
|
};
|