@useinsider/guido 3.7.0-beta.77d2633 → 3.7.0-beta.a6317a3
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/composables/useHtmlValidator.js +104 -98
- package/dist/composables/useSave.js +16 -17
- package/dist/enums/html-validator.js +13 -5
- package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +9 -9
- package/dist/extensions/Blocks/Unsubscribe/block.js +13 -13
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -4
- package/dist/src/enums/html-validator.d.ts +3 -0
- package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +2 -3
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +0 -1
- package/dist/stores/dynamic-content.js +1 -1
- package/package.json +1 -1
- package/dist/composables/validators/useUnsubscribeBlockValidator.js +0 -32
- package/dist/src/composables/useApiExample.d.ts +0 -63
- package/dist/src/composables/useRecommendation.test.d.ts +0 -1
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +0 -3
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendation/compositionMapper.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendation/extractors.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendation/parseLegacyConfig.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendation/settingsMapper.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendation/themeMapper.test.d.ts +0 -1
- package/dist/src/config/migrator/recommendationMigrator.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/services/configService.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/filterUtil.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMap.test.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/priceFormatter.test.d.ts +0 -1
- package/dist/src/stores/config.test.d.ts +0 -1
- package/dist/src/utils/ampErrorFilter.test.d.ts +0 -1
- package/dist/src/utils/htmlEscape.test.d.ts +0 -1
- package/dist/src/utils/templatePreparation.test.d.ts +0 -1
- package/dist/src/vitest.setup.d.ts +0 -0
|
@@ -1,166 +1,172 @@
|
|
|
1
|
-
import { useConfig as
|
|
2
|
-
import { TemplateTypes as
|
|
3
|
-
import { DISPLAY_CONDITIONS_REGEX as
|
|
1
|
+
import { useConfig as V } from "./useConfig.js";
|
|
2
|
+
import { TemplateTypes as M } from "../enums/defaults.js";
|
|
3
|
+
import { DISPLAY_CONDITIONS_REGEX as G, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as H, CampaignCouldNotBeSavedKey as P, CanNotMakeAnyChangesForRunningKey as X, DYNAMIC_CONTENT_TAG_REGEX as Y, ALLOWED_DYNAMIC_SYSTEM_TOKENS as $, VALID_DYNAMIC_VARIABLE_REGEX as q } from "../enums/html-validator.js";
|
|
4
4
|
import { ToasterTypeOptions as c } from "../enums/toaster.js";
|
|
5
|
-
import { itemsBlockDynamicVariables as
|
|
6
|
-
import { useRecommendationExtensionStore as
|
|
7
|
-
import { RecommendationRequiredFieldsKey as
|
|
8
|
-
import { useRecommendationStore as
|
|
9
|
-
import { base64EncodeWithSpecialChars as
|
|
10
|
-
import { useHttp as
|
|
11
|
-
import { useToaster as
|
|
12
|
-
import { useTranslations as
|
|
13
|
-
const
|
|
14
|
-
function
|
|
15
|
-
return [...
|
|
5
|
+
import { itemsBlockDynamicVariables as K } from "../extensions/Blocks/Items/enums/productEnums.js";
|
|
6
|
+
import { useRecommendationExtensionStore as j } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
7
|
+
import { RecommendationRequiredFieldsKey as z } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
|
|
8
|
+
import { useRecommendationStore as U } from "../stores/recommendation.js";
|
|
9
|
+
import { base64EncodeWithSpecialChars as Z } from "../utils/base64.js";
|
|
10
|
+
import { useHttp as J } from "./useHttp.js";
|
|
11
|
+
import { useToaster as Q } from "./useToaster.js";
|
|
12
|
+
import { useTranslations as ee } from "./useTranslations.js";
|
|
13
|
+
const te = /recommendation-id="(\d+)"/g;
|
|
14
|
+
function se(o) {
|
|
15
|
+
return [...o.matchAll(te)].map((d) => d[1]);
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
return
|
|
17
|
+
function ne(o, d) {
|
|
18
|
+
return d.some((f) => o.startsWith(`${f}_`));
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
function ie(o) {
|
|
21
|
+
return (o.match(Y) ?? []).filter((f) => {
|
|
22
|
+
const i = f.slice(2, -2), u = i.indexOf("|"), g = (u === -1 ? i : i.slice(0, u)).trim();
|
|
23
|
+
return $.includes(g) ? !1 : q.test(g) ? u !== -1 && i.slice(u + 1).trim() === "" : !0;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const ve = () => {
|
|
27
|
+
var h, v;
|
|
28
|
+
const { showToaster: o } = Q(), { post: d } = J(), { config: f } = V(), i = ee(), u = U(), g = j(), y = ((v = (h = f.value) == null ? void 0 : h.partner) == null ? void 0 : v.messageType) === M.transactional, A = async (e) => {
|
|
29
|
+
const t = await d(
|
|
24
30
|
"/newsletter/template-library/check-template-html-body",
|
|
25
|
-
{ html:
|
|
31
|
+
{ html: Z(e) }
|
|
26
32
|
), { status: n, message: l } = t.data;
|
|
27
|
-
return n ||
|
|
33
|
+
return n || o({
|
|
28
34
|
type: c.Alert,
|
|
29
|
-
message: n === void 0 ? l :
|
|
30
|
-
}),
|
|
35
|
+
message: n === void 0 ? l : i("newsletter.invalid-url-link-for-toaster")
|
|
36
|
+
}), i(P), l === i(X) && o({
|
|
31
37
|
type: c.Alert,
|
|
32
|
-
message:
|
|
38
|
+
message: i("newsletter.already-in-progress")
|
|
33
39
|
}), n;
|
|
34
|
-
},
|
|
40
|
+
}, S = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), b = (e) => ["if", "endif"].includes(e.toLowerCase()), I = (e, s) => {
|
|
35
41
|
const t = e.match(/({%(.*?)%})/g);
|
|
36
42
|
let n = !0;
|
|
37
|
-
return t !== null && !
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const [
|
|
41
|
-
|
|
43
|
+
return t !== null && !y && t.forEach((l) => {
|
|
44
|
+
const a = l.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
|
|
45
|
+
if (a && a.length > 0) {
|
|
46
|
+
const [r] = a;
|
|
47
|
+
S(r) && !s.includes(r) && (o({
|
|
42
48
|
type: c.Warning,
|
|
43
|
-
message:
|
|
49
|
+
message: i("custom-fields.invalid-custom-fields")
|
|
44
50
|
}), n = !1);
|
|
45
51
|
}
|
|
46
52
|
}), n;
|
|
47
|
-
},
|
|
48
|
-
const n = t ? await
|
|
49
|
-
return
|
|
50
|
-
}, x = (e) => e.length > 0 ? !0 : (
|
|
53
|
+
}, w = async (e, s, t) => {
|
|
54
|
+
const n = t ? await A(e) : !0;
|
|
55
|
+
return I(e, s) && n;
|
|
56
|
+
}, x = (e) => e.length > 0 ? !0 : (o({
|
|
51
57
|
type: c.Warning,
|
|
52
|
-
message:
|
|
53
|
-
}), !1),
|
|
58
|
+
message: i("newsletter.html-content-is-empty")
|
|
59
|
+
}), !1), T = (e) => {
|
|
54
60
|
const s = (e.match(/{/gm) || []).length, t = (e.match(/}/gm) || []).length;
|
|
55
|
-
return s > t &&
|
|
61
|
+
return s > t && o({
|
|
56
62
|
type: c.Warning,
|
|
57
|
-
message:
|
|
58
|
-
}), s < t &&
|
|
63
|
+
message: i("custom-fields.missing-closing-braces")
|
|
64
|
+
}), s < t && o({
|
|
59
65
|
type: c.Warning,
|
|
60
|
-
message:
|
|
66
|
+
message: i("custom-fields.missing-opening-braces")
|
|
61
67
|
}), s === t;
|
|
62
|
-
},
|
|
63
|
-
const s = e.
|
|
64
|
-
return s ||
|
|
68
|
+
}, k = (e) => {
|
|
69
|
+
const s = ie(e).length === 0;
|
|
70
|
+
return s || o({
|
|
65
71
|
type: c.Warning,
|
|
66
|
-
message:
|
|
72
|
+
message: i("custom-fields.invalid-custom-fields")
|
|
67
73
|
}), s;
|
|
68
|
-
},
|
|
74
|
+
}, _ = (e, s) => {
|
|
69
75
|
const t = e.match(/{{([a-zA-Z0-9_\s]*)}}/gm);
|
|
70
|
-
if (t && !
|
|
71
|
-
const n = new Set(s.map((
|
|
72
|
-
if (t.forEach((
|
|
73
|
-
const m =
|
|
74
|
-
(!n.has(m) || m === "") && !
|
|
75
|
-
}),
|
|
76
|
-
const
|
|
76
|
+
if (t && !y) {
|
|
77
|
+
const n = new Set(s.map((r) => r.toLowerCase())), l = se(e), a = [];
|
|
78
|
+
if (t.forEach((r) => {
|
|
79
|
+
const m = r.slice(2, -2).trim().toLowerCase();
|
|
80
|
+
(!n.has(m) || m === "") && !ne(m, l) && a.push(m);
|
|
81
|
+
}), a.length > 0) {
|
|
82
|
+
const r = `
|
|
77
83
|
<ul>
|
|
78
|
-
${
|
|
84
|
+
${a.map((m) => `<li>${m}</li>`).join("")}
|
|
79
85
|
</ul>
|
|
80
86
|
`;
|
|
81
|
-
return
|
|
87
|
+
return o({
|
|
82
88
|
type: c.Alert,
|
|
83
|
-
message:
|
|
89
|
+
message: i("custom-fields.invalid-custom-fields") + r
|
|
84
90
|
}), !1;
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
return !0;
|
|
88
|
-
},
|
|
94
|
+
}, N = (e) => {
|
|
89
95
|
const s = e.match(/{%(.*?)%}/g), t = [];
|
|
90
96
|
let n = !0;
|
|
91
97
|
if (s && s.forEach((l) => {
|
|
92
|
-
const
|
|
93
|
-
(!
|
|
98
|
+
const a = l.match(G), r = l.match(H), m = (a == null ? void 0 : a.join("")) || "";
|
|
99
|
+
(!a || l !== m) && !r && (o({
|
|
94
100
|
type: c.Alert,
|
|
95
|
-
message:
|
|
96
|
-
}), n = !1),
|
|
97
|
-
|
|
101
|
+
message: i("newsletter.display-conditions-invalid-syntax")
|
|
102
|
+
}), n = !1), a && a.forEach((p) => {
|
|
103
|
+
p.trim() === "=" && (o({
|
|
98
104
|
type: c.Alert,
|
|
99
|
-
message:
|
|
105
|
+
message: i("custom-conditions.wrong-equality-operators")
|
|
100
106
|
}), n = !1);
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
E
|
|
107
|
+
const C = p.match(/^[a-zA-Z]*$/g);
|
|
108
|
+
C && C.forEach((E) => {
|
|
109
|
+
b(E) && t.push(E);
|
|
104
110
|
});
|
|
105
111
|
});
|
|
106
112
|
}), t.length) {
|
|
107
|
-
const l = t.filter((
|
|
108
|
-
l.length !==
|
|
113
|
+
const l = t.filter((r) => r === "if"), a = t.filter((r) => r === "endif");
|
|
114
|
+
l.length !== a.length && (o({
|
|
109
115
|
type: c.Alert,
|
|
110
|
-
message:
|
|
116
|
+
message: i("custom-conditions.missing-if-endif-tag")
|
|
111
117
|
}), n = !1);
|
|
112
118
|
}
|
|
113
119
|
return n;
|
|
114
|
-
},
|
|
120
|
+
}, R = (e) => {
|
|
115
121
|
const s = (e.match(/{% /gm) || []).length, t = (e.match(/ %}/gm) || []).length, n = s === t;
|
|
116
|
-
return n ||
|
|
122
|
+
return n || o({
|
|
117
123
|
type: c.Warning,
|
|
118
|
-
message:
|
|
124
|
+
message: i("custom-conditions.no-space-after-braces")
|
|
119
125
|
}), n;
|
|
120
|
-
},
|
|
126
|
+
}, D = (e) => (e.match(/({%(.*?)%})/g) || []).filter((t) => t.includes("if")).map((t) => (t.match(/{{.*}}/gm) || []).length).reduce((t, n) => t + n, 0) > 0 ? (o({
|
|
121
127
|
type: c.Warning,
|
|
122
|
-
message:
|
|
123
|
-
}), !1) : !0,
|
|
128
|
+
message: i("custom-conditions.no-braces-inside-if-tag")
|
|
129
|
+
}), !1) : !0, F = () => g.hasInvalidBlock() ? (o({
|
|
124
130
|
type: c.Alert,
|
|
125
|
-
message:
|
|
126
|
-
}), !1) : !0, O = () =>
|
|
131
|
+
message: i(z)
|
|
132
|
+
}), !1) : !0, O = () => u.recommendationConfigs && Object.values(u.recommendationConfigs).find((s) => s.filters.find((t) => t.value === "")) !== void 0 ? (o({
|
|
127
133
|
type: c.Alert,
|
|
128
|
-
message:
|
|
129
|
-
}), !1) : !0,
|
|
134
|
+
message: i("newsletter.fill-all-necessary-fields")
|
|
135
|
+
}), !1) : !0, B = (e) => {
|
|
130
136
|
const s = /src="[^"]*\.(svg|pst)"/gm;
|
|
131
|
-
return e.match(s) === null ? !0 : (
|
|
137
|
+
return e.match(s) === null ? !0 : (o({
|
|
132
138
|
type: c.Alert,
|
|
133
|
-
message:
|
|
139
|
+
message: i("newsletter.invalid-image-type")
|
|
134
140
|
}), !1);
|
|
135
141
|
}, L = (e) => {
|
|
136
142
|
const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
|
|
137
|
-
return Array.from(n).find((
|
|
138
|
-
var
|
|
139
|
-
return !((
|
|
140
|
-
}) ? (
|
|
143
|
+
return Array.from(n).find((a) => {
|
|
144
|
+
var r;
|
|
145
|
+
return !((r = a.id) != null && r.trim());
|
|
146
|
+
}) ? (o({
|
|
141
147
|
type: c.Alert,
|
|
142
|
-
message:
|
|
148
|
+
message: i("unsubscribe-templates.select-checkbox-groups")
|
|
143
149
|
}), !1) : !0;
|
|
144
|
-
},
|
|
150
|
+
}, W = (e) => {
|
|
145
151
|
const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
|
|
146
|
-
return Array.from(n).find((
|
|
147
|
-
var
|
|
148
|
-
return !((
|
|
149
|
-
}) ? (
|
|
152
|
+
return Array.from(n).find((a) => {
|
|
153
|
+
var r;
|
|
154
|
+
return !((r = a.id) != null && r.trim());
|
|
155
|
+
}) ? (o({
|
|
150
156
|
type: c.Alert,
|
|
151
|
-
message:
|
|
157
|
+
message: i("unsubscribe-templates.select-radio-button-groups")
|
|
152
158
|
}), !1) : !0;
|
|
153
159
|
};
|
|
154
160
|
return { validateHtml: async (e, s, t = !1) => {
|
|
155
|
-
var
|
|
161
|
+
var a, r;
|
|
156
162
|
const n = [
|
|
157
163
|
...s.map((m) => m.value),
|
|
158
|
-
...
|
|
159
|
-
...((
|
|
164
|
+
...K,
|
|
165
|
+
...((r = (a = f.value) == null ? void 0 : a.template) == null ? void 0 : r.customFieldAttributes) ?? []
|
|
160
166
|
];
|
|
161
|
-
return await
|
|
167
|
+
return await w(e, n, t) && x(e) && T(e) && k(e) && _(e, n) && N(e) && R(e) && D(e) && F() && O() && B(e) && L(e) && W(e);
|
|
162
168
|
} };
|
|
163
169
|
};
|
|
164
170
|
export {
|
|
165
|
-
|
|
171
|
+
ve as useHtmlValidator
|
|
166
172
|
};
|
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
import { useActionsApi as x } from "./useActionsApi.js";
|
|
2
2
|
import { useConfig as y } from "./useConfig.js";
|
|
3
|
-
import { useSaveStart as w, useSaveComplete as
|
|
4
|
-
import { useSyncModuleExtractor as
|
|
5
|
-
import { useStripoApi as
|
|
6
|
-
import { useTemplatePreparation as
|
|
7
|
-
import { useHtmlValidator as
|
|
3
|
+
import { useSaveStart as w, useSaveComplete as C } from "./useGuidoActions.js";
|
|
4
|
+
import { useSyncModuleExtractor as E } from "./useSyncModuleExtractor.js";
|
|
5
|
+
import { useStripoApi as H } from "../services/stripoApi.js";
|
|
6
|
+
import { useTemplatePreparation as b } from "../utils/templatePreparation.js";
|
|
7
|
+
import { useHtmlValidator as q } from "./useHtmlValidator.js";
|
|
8
8
|
import { useCouponBlockValidator as L } from "./validators/useCouponBlockValidator.js";
|
|
9
9
|
import { useLiquidValidator as P } from "./validators/useLiquidValidator.js";
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var a;
|
|
10
|
+
const z = () => {
|
|
11
|
+
const o = w(), s = C(), { validateHtml: r } = q(), { validateLiquidSyntax: n } = P(), { validateCouponBlockTags: l } = L(), { callbacks: a, isFeatureEnabled: d } = y(), { extractSyncModuleData: u } = E(), { setSyncModuleUnsubscriptionPages: c } = H(), { editorSave: m } = x();
|
|
12
|
+
return { save: async (p = !1, f = !1) => {
|
|
13
|
+
var i;
|
|
15
14
|
o();
|
|
16
|
-
const { prepareTemplateDetails:
|
|
17
|
-
if (!l(t.compiledHtml)
|
|
15
|
+
const { prepareTemplateDetails: v } = b(), t = await v();
|
|
16
|
+
if (!l(t.compiledHtml))
|
|
18
17
|
return;
|
|
19
|
-
if (
|
|
18
|
+
if (d("liquidSyntax")) {
|
|
20
19
|
if (!await n(t.compiledHtml))
|
|
21
20
|
return;
|
|
22
21
|
} else if (!await r(t.compiledHtml, t.dynamicContentList, !0))
|
|
23
22
|
return;
|
|
24
|
-
if ((
|
|
23
|
+
if ((i = a.value) != null && i.externalValidation && !await a.value.externalValidation(t) || !await m())
|
|
25
24
|
return;
|
|
26
|
-
const { unsubscribePayload:
|
|
27
|
-
return await
|
|
25
|
+
const { unsubscribePayload: S, stripoModules: V } = u(t.rawHtml);
|
|
26
|
+
return await c(S), t.modules = V, p || s({ ...t, silent: f }), t;
|
|
28
27
|
} };
|
|
29
28
|
};
|
|
30
29
|
export {
|
|
31
|
-
|
|
30
|
+
z as useSave
|
|
32
31
|
};
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
const
|
|
1
|
+
const n = "newsletter.already-in-progress", e = "newsletter.campaign-could-not-be-saved", s = / (==|<=|>=|!=|>|<|in) | (if|elif|endif|else|and|or) |("[\S ]+")|('[\S ]+')|([^”\s\n]+)|(({%)|( %}))/gm, o = /{%( )*now( )(".*")( )*%}/gm, i = /\{\{[^{}]+\}\}/g, E = /^[A-Za-z0-9_.]+$/, _ = [
|
|
2
|
+
"ins-unsubscribe-link",
|
|
3
|
+
"ins-global-unsubscribe-link",
|
|
4
|
+
"ins-preferences-unsubscribe-link",
|
|
5
|
+
"@COUPON_CODE"
|
|
6
|
+
];
|
|
2
7
|
export {
|
|
3
|
-
|
|
4
|
-
e as
|
|
5
|
-
|
|
6
|
-
o as
|
|
8
|
+
_ as ALLOWED_DYNAMIC_SYSTEM_TOKENS,
|
|
9
|
+
e as CampaignCouldNotBeSavedKey,
|
|
10
|
+
n as CanNotMakeAnyChangesForRunningKey,
|
|
11
|
+
o as DISPLAY_CONDITIONS_EXCEPTIONS_REGEX,
|
|
12
|
+
s as DISPLAY_CONDITIONS_REGEX,
|
|
13
|
+
i as DYNAMIC_CONTENT_TAG_REGEX,
|
|
14
|
+
E as VALID_DYNAMIC_VARIABLE_REGEX
|
|
7
15
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const u = [
|
|
2
2
|
{
|
|
3
3
|
key: "locale",
|
|
4
4
|
getValue: (e) => e.language,
|
|
@@ -9,8 +9,8 @@ const o = [
|
|
|
9
9
|
getValue: (e) => e.currencySettings.value,
|
|
10
10
|
getAvailableOptions: (e) => e.currencyList.map((n) => n.text)
|
|
11
11
|
}
|
|
12
|
-
],
|
|
13
|
-
function
|
|
12
|
+
], s = "newsletter.recommendation-fill-required-fields";
|
|
13
|
+
function l(e, n, o = u) {
|
|
14
14
|
return o.filter((t) => {
|
|
15
15
|
var a;
|
|
16
16
|
if (t.condition && !t.condition(e))
|
|
@@ -22,12 +22,12 @@ function u(e, n) {
|
|
|
22
22
|
return r !== void 0 && !r.includes(i);
|
|
23
23
|
}).map((t) => t.key);
|
|
24
24
|
}
|
|
25
|
-
function
|
|
26
|
-
return
|
|
25
|
+
function c(e, n) {
|
|
26
|
+
return l(e, n).length === 0;
|
|
27
27
|
}
|
|
28
28
|
export {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
u as REQUIRED_RECOMMENDATION_FIELDS,
|
|
30
|
+
s as RecommendationRequiredFieldsKey,
|
|
31
|
+
l as getInvalidFields,
|
|
32
|
+
c as isConfigValid
|
|
33
33
|
};
|
|
@@ -5,11 +5,11 @@ import { useToaster as B } from "../../../composables/useToaster.js";
|
|
|
5
5
|
import { ToasterTypeOptions as S } from "../../../enums/toaster.js";
|
|
6
6
|
import { PAGE_TYPES as E } from "../../../enums/unsubscribe.js";
|
|
7
7
|
import { useUnsubscribeStore as a } from "../../../stores/unsubscribe.js";
|
|
8
|
-
import { Block as L, BlockCompositionType as f, ContextActionType as h, ModificationDescription as b, BlockType as
|
|
9
|
-
import { getDefaultTemplate as
|
|
10
|
-
import { DATA_ATTRIBUTES as i,
|
|
11
|
-
import { parsePageList as
|
|
12
|
-
const y = "unsubscribe-block",
|
|
8
|
+
import { Block as L, BlockCompositionType as f, ContextActionType as h, ModificationDescription as b, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
9
|
+
import { getDefaultTemplate as A } from "./template.js";
|
|
10
|
+
import { DATA_ATTRIBUTES as i, UNSUBSCRIBE_EVENTS as d } from "./utils/constants.js";
|
|
11
|
+
import { parsePageList as p } from "./utils/utils.js";
|
|
12
|
+
const y = "unsubscribe-block", m = 'a[data-unsubscribe-link="true"]', _ = ".unsubscribe-block-v2", I = "{{ins-unsubscribe-link}}", T = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", C = "Removing the unsubscribe text leaves an empty block, but an active unsubscribe link is required. Undo your last action to restore the text, or delete the unsubscribe block entirely.", N = {
|
|
13
13
|
[E.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
14
14
|
[E.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
15
15
|
};
|
|
@@ -42,7 +42,7 @@ class F extends L {
|
|
|
42
42
|
return this.api.translate("Unsubscribe Block Description");
|
|
43
43
|
}
|
|
44
44
|
getTemplate() {
|
|
45
|
-
return
|
|
45
|
+
return A();
|
|
46
46
|
}
|
|
47
47
|
getContextActionsIds() {
|
|
48
48
|
return [h.MOVE, h.REMOVE];
|
|
@@ -68,7 +68,7 @@ class F extends L {
|
|
|
68
68
|
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear();
|
|
69
69
|
}
|
|
70
70
|
_hasUnsubscribeLink(e) {
|
|
71
|
-
return "querySelector" in e ? !!e.querySelector(
|
|
71
|
+
return "querySelector" in e ? !!e.querySelector(m) : !1;
|
|
72
72
|
}
|
|
73
73
|
_readBlockId(e) {
|
|
74
74
|
return "getAttribute" in e ? e.getAttribute(i.BLOCK_ID) : null;
|
|
@@ -102,7 +102,7 @@ class F extends L {
|
|
|
102
102
|
let e = 0;
|
|
103
103
|
try {
|
|
104
104
|
const t = this.api.getDocumentRoot();
|
|
105
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
105
|
+
t && "querySelectorAll" in t && t.querySelectorAll(_).forEach((s) => {
|
|
106
106
|
if ("getAttribute" in s) {
|
|
107
107
|
const o = s.getAttribute(i.BLOCK_ID), u = o ? parseInt(o) : 0;
|
|
108
108
|
u > e && (e = u);
|
|
@@ -150,7 +150,7 @@ class F extends L {
|
|
|
150
150
|
try {
|
|
151
151
|
if (!this.currentNode)
|
|
152
152
|
return;
|
|
153
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${
|
|
153
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new b("Removed unsubscribe block due to cancel"));
|
|
154
154
|
} catch (e) {
|
|
155
155
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
156
156
|
}
|
|
@@ -161,7 +161,7 @@ class F extends L {
|
|
|
161
161
|
_updateBlock(e, t) {
|
|
162
162
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
163
163
|
return;
|
|
164
|
-
const r = this.currentNode.querySelector(
|
|
164
|
+
const r = this.currentNode.querySelector(m);
|
|
165
165
|
if (!r)
|
|
166
166
|
return;
|
|
167
167
|
const s = this._getMergeTag(e);
|
|
@@ -181,7 +181,7 @@ class F extends L {
|
|
|
181
181
|
}
|
|
182
182
|
_checkExistingBlocks() {
|
|
183
183
|
const e = a();
|
|
184
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
184
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(_).forEach((r) => {
|
|
185
185
|
if ("getAttribute" in r) {
|
|
186
186
|
const s = r.getAttribute(i.PAGE_TYPE);
|
|
187
187
|
if (s) {
|
|
@@ -197,7 +197,7 @@ class F extends L {
|
|
|
197
197
|
const t = e.getAttribute(i.PAGE_TYPE), r = e.getAttribute(i.PAGE_LIST);
|
|
198
198
|
if (!t || !r)
|
|
199
199
|
return;
|
|
200
|
-
const s = a(), o = Number(t), u =
|
|
200
|
+
const s = a(), o = Number(t), u = p(r);
|
|
201
201
|
await s.fetchTemplates(), s.setCollectionWithoutAutoSelection(o), s.loadSelectedTemplates(u);
|
|
202
202
|
}
|
|
203
203
|
_resetStoreState() {
|
|
@@ -209,7 +209,7 @@ class F extends L {
|
|
|
209
209
|
const t = e.getAttribute(i.PAGE_LIST);
|
|
210
210
|
if (!t)
|
|
211
211
|
return;
|
|
212
|
-
const r = a(), s =
|
|
212
|
+
const r = a(), s = p(t);
|
|
213
213
|
r.removeUnsubscribePages(s);
|
|
214
214
|
}
|
|
215
215
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
const s = {
|
|
2
2
|
SELECT: "unsubscribe:select",
|
|
3
3
|
CANCEL: "unsubscribe:cancel"
|
|
4
|
-
},
|
|
4
|
+
}, e = {
|
|
5
5
|
PAGE_TYPE: "data-unsubscribe-page-type",
|
|
6
6
|
PAGE_LIST: "data-unsubscribe-page-list",
|
|
7
7
|
BLOCK_ID: "data-unsubscribe-block-id"
|
|
8
|
-
}
|
|
8
|
+
};
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
c as UNSUBSCRIBE_BLOCK_SELECTOR,
|
|
10
|
+
e as DATA_ATTRIBUTES,
|
|
12
11
|
s as UNSUBSCRIBE_EVENTS
|
|
13
12
|
};
|
|
@@ -4,3 +4,6 @@ export declare const CampaignCouldNotBeSavedKey = "newsletter.campaign-could-not
|
|
|
4
4
|
export declare const DISPLAY_CONDITIONS_REGEX: RegExp;
|
|
5
5
|
export declare const DISPLAY_CONDITIONS_EXCEPTIONS_REGEX: RegExp;
|
|
6
6
|
export declare const REMOVE_CONDITIONS_REGEX: RegExp;
|
|
7
|
+
export declare const DYNAMIC_CONTENT_TAG_REGEX: RegExp;
|
|
8
|
+
export declare const VALID_DYNAMIC_VARIABLE_REGEX: RegExp;
|
|
9
|
+
export declare const ALLOWED_DYNAMIC_SYSTEM_TOKENS: string[];
|
|
@@ -8,7 +8,7 @@ export interface ExtensionStoreSlice {
|
|
|
8
8
|
languages: Languages;
|
|
9
9
|
currencyList: Currency[];
|
|
10
10
|
}
|
|
11
|
-
interface RequiredField {
|
|
11
|
+
export interface RequiredField {
|
|
12
12
|
key: string;
|
|
13
13
|
getValue: (config: PerBlockConfigs) => string;
|
|
14
14
|
getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
|
|
@@ -16,6 +16,5 @@ interface RequiredField {
|
|
|
16
16
|
}
|
|
17
17
|
export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
|
|
18
18
|
export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
|
|
19
|
-
export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice): string[];
|
|
19
|
+
export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
|
|
20
20
|
export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;
|
|
21
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.7.0-beta.
|
|
3
|
+
"version": "3.7.0-beta.a6317a3",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ToasterTypeOptions as i } from "../../enums/toaster.js";
|
|
2
|
-
import { PAGE_TYPES as n } from "../../enums/unsubscribe.js";
|
|
3
|
-
import { UNSUBSCRIBE_BLOCK_SELECTOR as u, DATA_ATTRIBUTES as l } from "../../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
4
|
-
import { useToaster as T } from "../useToaster.js";
|
|
5
|
-
import { useTranslations as E } from "../useTranslations.js";
|
|
6
|
-
const m = [
|
|
7
|
-
{
|
|
8
|
-
pageType: n.GLOBAL_UNSUBSCRIBE,
|
|
9
|
-
messageKey: "unsubscription-preference.duplicate-global-unsub"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
pageType: n.SUBSCRIPTION_PREFERENCE_CENTER,
|
|
13
|
-
messageKey: "unsubscription-preference.duplicate-pref-center"
|
|
14
|
-
}
|
|
15
|
-
], g = "unsubscription-preference.duplicate-both", y = () => {
|
|
16
|
-
const { showToaster: o } = T(), a = E();
|
|
17
|
-
return { validateUnsubscribeBlockUniqueness: (c) => {
|
|
18
|
-
const p = new DOMParser().parseFromString(c, "text/html"), t = /* @__PURE__ */ new Map();
|
|
19
|
-
p.querySelectorAll(u).forEach((e) => {
|
|
20
|
-
const r = Number(e.getAttribute(l.PAGE_TYPE));
|
|
21
|
-
t.set(r, (t.get(r) ?? 0) + 1);
|
|
22
|
-
});
|
|
23
|
-
const s = m.filter((e) => (t.get(e.pageType) ?? 0) > 1).map((e) => e.messageKey);
|
|
24
|
-
return s.length ? (o({
|
|
25
|
-
type: i.Alert,
|
|
26
|
-
message: a(s.length > 1 ? g : s[0])
|
|
27
|
-
}), !1) : !0;
|
|
28
|
-
} };
|
|
29
|
-
};
|
|
30
|
-
export {
|
|
31
|
-
y as useUnsubscribeBlockValidator
|
|
32
|
-
};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
interface User {
|
|
2
|
-
id: number;
|
|
3
|
-
name: string;
|
|
4
|
-
email: string;
|
|
5
|
-
}
|
|
6
|
-
export declare const useApiExample: () => {
|
|
7
|
-
loading: import("vue").ComputedRef<boolean>;
|
|
8
|
-
error: import("vue").ComputedRef<{
|
|
9
|
-
message: string;
|
|
10
|
-
status?: number | undefined;
|
|
11
|
-
statusText?: string | undefined;
|
|
12
|
-
response?: {
|
|
13
|
-
readonly headers: {
|
|
14
|
-
append: (name: string, value: string) => void;
|
|
15
|
-
delete: (name: string) => void;
|
|
16
|
-
get: (name: string) => string | null;
|
|
17
|
-
getSetCookie: () => string[];
|
|
18
|
-
has: (name: string) => boolean;
|
|
19
|
-
set: (name: string, value: string) => void;
|
|
20
|
-
forEach: (callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any) => void;
|
|
21
|
-
entries: () => IterableIterator<[string, string]>;
|
|
22
|
-
keys: () => IterableIterator<string>;
|
|
23
|
-
values: () => IterableIterator<string>;
|
|
24
|
-
[Symbol.iterator]: () => IterableIterator<[string, string]>;
|
|
25
|
-
};
|
|
26
|
-
readonly ok: boolean;
|
|
27
|
-
readonly redirected: boolean;
|
|
28
|
-
readonly status: number;
|
|
29
|
-
readonly statusText: string;
|
|
30
|
-
readonly type: ResponseType;
|
|
31
|
-
readonly url: string;
|
|
32
|
-
clone: () => Response;
|
|
33
|
-
readonly body: {
|
|
34
|
-
readonly locked: boolean;
|
|
35
|
-
cancel: (reason?: any) => Promise<void>;
|
|
36
|
-
getReader: {
|
|
37
|
-
(options: {
|
|
38
|
-
mode: "byob";
|
|
39
|
-
}): ReadableStreamBYOBReader;
|
|
40
|
-
(): ReadableStreamDefaultReader<Uint8Array>;
|
|
41
|
-
(options?: ReadableStreamGetReaderOptions): ReadableStreamReader<Uint8Array>;
|
|
42
|
-
};
|
|
43
|
-
pipeThrough: <T>(transform: ReadableWritablePair<T, Uint8Array>, options?: StreamPipeOptions) => ReadableStream<T>;
|
|
44
|
-
pipeTo: (destination: WritableStream<Uint8Array>, options?: StreamPipeOptions) => Promise<void>;
|
|
45
|
-
tee: () => [ReadableStream<Uint8Array>, ReadableStream<Uint8Array>];
|
|
46
|
-
} | null;
|
|
47
|
-
readonly bodyUsed: boolean;
|
|
48
|
-
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
49
|
-
blob: () => Promise<Blob>;
|
|
50
|
-
formData: () => Promise<FormData>;
|
|
51
|
-
json: () => Promise<any>;
|
|
52
|
-
text: () => Promise<string>;
|
|
53
|
-
} | undefined;
|
|
54
|
-
} | null>;
|
|
55
|
-
hasError: import("vue").ComputedRef<boolean>;
|
|
56
|
-
fetchUsers: () => Promise<User[]>;
|
|
57
|
-
createUser: (userData: Omit<User, "id">) => Promise<User>;
|
|
58
|
-
updateUser: (id: number, userData: Partial<User>) => Promise<User>;
|
|
59
|
-
deleteUser: (id: number) => Promise<void>;
|
|
60
|
-
uploadFile: (file: File) => Promise<string>;
|
|
61
|
-
clearError: () => void;
|
|
62
|
-
};
|
|
63
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
File without changes
|