@useinsider/guido 1.0.3-beta.ce4cdcb → 1.0.3-beta.cedc8cb
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/@types/generic.d.ts +13 -0
- package/dist/components/Guido.vue.d.ts +3 -2
- package/dist/components/Guido.vue.js +4 -4
- package/dist/components/Guido.vue2.js +99 -70
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +19 -0
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +28 -0
- package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +38 -0
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.d.ts +2 -0
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +17 -0
- package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +37 -0
- package/dist/components/organisms/extensions/recommendation/Filters.vue.d.ts +2 -0
- package/dist/components/organisms/extensions/recommendation/Filters.vue.js +20 -0
- package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +44 -0
- package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue.d.ts +16 -0
- package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue.js +17 -0
- package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +27 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue.d.ts +2 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue.js +18 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue2.js +16 -0
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.d.ts +2 -0
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +24 -0
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +64 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.d.ts +2 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +18 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +107 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue.d.ts +2 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue.js +18 -0
- package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue2.js +12 -0
- package/dist/components/wrappers/WpDrawer.vue.d.ts +6 -4
- package/dist/components/wrappers/WpDrawer.vue.js +6 -4
- package/dist/composables/useApiErrorTracking.d.ts +26 -0
- package/dist/composables/useApiErrorTracking.js +120 -0
- package/dist/composables/useErrorTracking.d.ts +30 -0
- package/dist/composables/useErrorTracking.js +98 -0
- package/dist/composables/useHttp.js +89 -52
- package/dist/composables/useStripo.js +160 -61
- package/dist/composables/useStripoErrorCategory.d.ts +26 -0
- package/dist/composables/useStripoErrorCategory.js +86 -0
- package/dist/composables/useStripoSlackNotifier.d.ts +8 -0
- package/dist/composables/useStripoSlackNotifier.js +47 -0
- package/dist/config/compiler/unsubscribeCompilerRules.js +42 -29
- package/dist/config/migrator/index.d.ts +1 -1
- package/dist/config/migrator/index.js +7 -6
- package/dist/config/migrator/unsubscribeMigrator.d.ts +1 -0
- package/dist/config/migrator/unsubscribeMigrator.js +124 -0
- package/dist/enums/defaults.js +6 -3
- package/dist/enums/extensions/recommendationBlock.d.ts +16 -0
- package/dist/enums/extensions/recommendationBlock.js +80 -0
- package/dist/enums/unsubscribe.d.ts +19 -0
- package/dist/enums/unsubscribe.js +39 -6
- package/dist/extensions/Blocks/Checkbox/control.js +35 -39
- package/dist/extensions/Blocks/RadioButton/control.js +33 -37
- package/dist/extensions/Blocks/RadioButton/template.js +6 -6
- package/dist/extensions/Blocks/Recommendation/block.d.ts +10 -0
- package/dist/extensions/Blocks/Recommendation/block.js +27 -0
- package/dist/extensions/Blocks/Recommendation/control.d.ts +29 -0
- package/dist/extensions/Blocks/Recommendation/control.js +277 -0
- package/dist/extensions/Blocks/Recommendation/extension.d.ts +2 -0
- package/dist/extensions/Blocks/Recommendation/extension.js +10 -0
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.d.ts +4 -0
- package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +51 -0
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +19 -0
- package/dist/extensions/Blocks/Recommendation/settingsPanel.d.ts +4 -0
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +32 -0
- package/dist/extensions/Blocks/Recommendation/store/recommendation.d.ts +555 -0
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +266 -0
- package/dist/extensions/Blocks/Recommendation/template.d.ts +6 -0
- package/dist/extensions/Blocks/Recommendation/template.js +200 -0
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.d.ts +7 -0
- package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +28 -0
- package/dist/extensions/Blocks/Unsubscribe/block.d.ts +32 -0
- package/dist/extensions/Blocks/Unsubscribe/block.js +131 -0
- package/dist/extensions/Blocks/Unsubscribe/control.d.ts +29 -0
- package/dist/extensions/Blocks/Unsubscribe/control.js +167 -0
- package/dist/extensions/Blocks/Unsubscribe/elements/preview.d.ts +11 -0
- package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +42 -0
- package/dist/extensions/Blocks/Unsubscribe/extension.d.ts +2 -0
- package/dist/extensions/Blocks/Unsubscribe/extension.js +21 -0
- package/dist/extensions/Blocks/Unsubscribe/iconsRegistry.d.ts +4 -0
- package/dist/extensions/Blocks/Unsubscribe/iconsRegistry.js +21 -0
- package/dist/extensions/Blocks/Unsubscribe/settingsPanel.d.ts +4 -0
- package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +35 -0
- package/dist/extensions/Blocks/Unsubscribe/styles.css.js +42 -0
- package/dist/extensions/Blocks/Unsubscribe/tagRegistry.d.ts +4 -0
- package/dist/extensions/Blocks/Unsubscribe/tagRegistry.js +10 -0
- package/dist/extensions/Blocks/Unsubscribe/template.d.ts +12 -0
- package/dist/extensions/Blocks/Unsubscribe/template.js +22 -0
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.d.ts +9 -0
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +11 -0
- package/dist/extensions/Blocks/Unsubscribe/utils/utils.d.ts +7 -0
- package/dist/extensions/Blocks/Unsubscribe/utils/utils.js +6 -0
- package/dist/extensions/Blocks/common-control.d.ts +66 -0
- package/dist/extensions/Blocks/common-control.js +102 -0
- package/dist/guido.css +1 -1
- package/dist/mock/api/recommendation.d.ts +2 -0
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +83 -71
- package/dist/services/recommendationApi.d.ts +6 -0
- package/dist/services/recommendationApi.js +43 -0
- package/dist/services/slackNotificationService.d.ts +110 -0
- package/dist/services/slackNotificationService.js +167 -0
- package/dist/services/stripoApi.js +49 -19
- package/dist/services/stripoErrorDeduplicationService.d.ts +75 -0
- package/dist/services/stripoErrorDeduplicationService.js +91 -0
- package/dist/services/unsubscribeApi.d.ts +4 -0
- package/dist/services/unsubscribeApi.js +16 -0
- package/dist/stores/config.d.ts +96 -0
- package/dist/stores/config.js +17 -0
- package/dist/stores/editor.d.ts +21 -0
- package/dist/stores/editor.js +2 -1
- package/dist/stores/unsubscribe.d.ts +253 -5
- package/dist/stores/unsubscribe.js +126 -6
- package/dist/utils/genericUtil.d.ts +1 -0
- package/dist/utils/genericUtil.js +8 -7
- package/dist/utils/templatePreparation.js +17 -16
- package/package.json +2 -2
|
@@ -1,86 +1,123 @@
|
|
|
1
|
-
import { getCsrfToken as
|
|
2
|
-
import { ref as
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { getCsrfToken as S } from "../utils/genericUtil.js";
|
|
2
|
+
import { ref as h, computed as w } from "vue";
|
|
3
|
+
let b;
|
|
4
|
+
const g = async () => {
|
|
5
|
+
if (!b)
|
|
6
|
+
try {
|
|
7
|
+
const { useApiErrorTracking: E } = await import("./useApiErrorTracking.js");
|
|
8
|
+
b = E();
|
|
9
|
+
} catch {
|
|
10
|
+
}
|
|
11
|
+
return b;
|
|
12
|
+
}, M = (E = {}) => {
|
|
13
|
+
const d = h(!1), i = h(null), l = h(null), P = w(() => d.value), k = w(() => i.value !== null), v = {
|
|
5
14
|
baseURL: "",
|
|
6
15
|
timeout: 1e4,
|
|
7
16
|
retry: 0,
|
|
8
17
|
retryDelay: 1e3,
|
|
9
18
|
headers: {
|
|
10
19
|
"Content-Type": "application/json",
|
|
11
|
-
"X-CSRF-TOKEN":
|
|
20
|
+
"X-CSRF-TOKEN": S()
|
|
12
21
|
},
|
|
13
|
-
...
|
|
14
|
-
},
|
|
15
|
-
if (
|
|
16
|
-
return
|
|
17
|
-
const
|
|
18
|
-
return
|
|
19
|
-
},
|
|
22
|
+
...E
|
|
23
|
+
}, C = (t, s) => {
|
|
24
|
+
if (t.startsWith("http://") || t.startsWith("https://"))
|
|
25
|
+
return t;
|
|
26
|
+
const e = s || v.baseURL || "";
|
|
27
|
+
return e.endsWith("/") && t.startsWith("/") ? `${e}${t.slice(1)}` : e.endsWith("/") || t.startsWith("/") ? `${e}${t}` : `${e}/${t}`;
|
|
28
|
+
}, A = (t) => new Promise((s, e) => {
|
|
20
29
|
setTimeout(() => {
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
}),
|
|
24
|
-
setTimeout(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
e(new Error("Request timeout"));
|
|
31
|
+
}, t);
|
|
32
|
+
}), $ = (t) => new Promise((s) => {
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
s();
|
|
35
|
+
}, t);
|
|
36
|
+
}), c = async (t, s, e, L = {}) => {
|
|
37
|
+
i.value = null, d.value = !0, l.value = new AbortController();
|
|
38
|
+
const n = { ...v, ...L }, T = C(s, n.baseURL), m = {
|
|
39
|
+
method: t,
|
|
29
40
|
headers: { ...n.headers },
|
|
30
|
-
signal:
|
|
41
|
+
signal: l.value.signal,
|
|
31
42
|
...n
|
|
32
43
|
};
|
|
33
|
-
|
|
34
|
-
const
|
|
44
|
+
e && ["POST", "PUT", "PATCH"].includes(t) && (e instanceof FormData ? (delete m.headers["Content-Type"], m.body = e) : m.body = JSON.stringify(e));
|
|
45
|
+
const y = async (f = 0) => {
|
|
35
46
|
try {
|
|
36
|
-
const o = [fetch(
|
|
37
|
-
n.timeout && o.push(
|
|
47
|
+
const o = [fetch(T, m)];
|
|
48
|
+
n.timeout && o.push(A(n.timeout));
|
|
38
49
|
const r = await Promise.race(o);
|
|
39
50
|
if (!r.ok) {
|
|
40
|
-
const O = `HTTP Error: ${r.status} ${r.statusText}`,
|
|
41
|
-
|
|
51
|
+
const O = `HTTP Error: ${r.status} ${r.statusText}`, p = new Error(O);
|
|
52
|
+
p.status = r.status, p.statusText = r.statusText, p.response = r;
|
|
53
|
+
const x = await g();
|
|
54
|
+
throw x && x.captureHttpError(p, T, {
|
|
55
|
+
method: t,
|
|
56
|
+
statusCode: r.status,
|
|
57
|
+
statusText: r.statusText
|
|
58
|
+
}), p;
|
|
42
59
|
}
|
|
43
|
-
let
|
|
44
|
-
const
|
|
45
|
-
return
|
|
46
|
-
data:
|
|
60
|
+
let a;
|
|
61
|
+
const u = r.headers.get("content-type");
|
|
62
|
+
return u != null && u.includes("application/json") ? a = await r.json() : u != null && u.includes("text/") ? a = await r.text() : a = await r.blob(), {
|
|
63
|
+
data: a,
|
|
47
64
|
status: r.status,
|
|
48
65
|
statusText: r.statusText,
|
|
49
66
|
headers: r.headers
|
|
50
67
|
};
|
|
51
68
|
} catch (o) {
|
|
52
69
|
const r = o instanceof Error && o.name === "AbortError";
|
|
53
|
-
if (
|
|
54
|
-
return await
|
|
55
|
-
|
|
70
|
+
if (f < (n.retry || 0) && !r)
|
|
71
|
+
return await $(n.retryDelay || 1e3), y(f + 1);
|
|
72
|
+
if (o instanceof Error)
|
|
73
|
+
if (o.name === "AbortError")
|
|
74
|
+
i.value = { message: "Request was cancelled" };
|
|
75
|
+
else {
|
|
76
|
+
i.value = { message: o.message };
|
|
77
|
+
const a = await g();
|
|
78
|
+
a && a.captureNetworkError(o, T, {
|
|
79
|
+
method: t,
|
|
80
|
+
attemptNumber: f + 1,
|
|
81
|
+
timeoutMs: n.timeout
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
i.value = o;
|
|
86
|
+
const a = await g();
|
|
87
|
+
a && o instanceof Error && a.captureNetworkError(o, T, {
|
|
88
|
+
method: t,
|
|
89
|
+
attemptNumber: f + 1
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
throw o;
|
|
56
93
|
}
|
|
57
94
|
};
|
|
58
95
|
try {
|
|
59
|
-
return await
|
|
96
|
+
return await y();
|
|
60
97
|
} finally {
|
|
61
|
-
|
|
98
|
+
d.value = !1, l.value = null;
|
|
62
99
|
}
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
},
|
|
66
|
-
|
|
100
|
+
}, R = (t, s) => c("GET", t, void 0, s), U = (t, s, e) => c("POST", t, s, e), N = (t, s, e) => c("PUT", t, s, e), W = (t, s, e) => c("PATCH", t, s, e), q = (t, s) => c("DELETE", t, void 0, s), D = (t) => {
|
|
101
|
+
l.value && l.value.abort(t);
|
|
102
|
+
}, H = () => {
|
|
103
|
+
i.value = null;
|
|
67
104
|
};
|
|
68
105
|
return {
|
|
69
106
|
// State
|
|
70
|
-
loading:
|
|
71
|
-
error:
|
|
72
|
-
hasError:
|
|
107
|
+
loading: P,
|
|
108
|
+
error: w(() => i.value),
|
|
109
|
+
hasError: k,
|
|
73
110
|
// Methods
|
|
74
|
-
request:
|
|
75
|
-
get:
|
|
76
|
-
post:
|
|
77
|
-
put:
|
|
78
|
-
patch:
|
|
79
|
-
delete:
|
|
80
|
-
cancel:
|
|
81
|
-
clearError:
|
|
111
|
+
request: c,
|
|
112
|
+
get: R,
|
|
113
|
+
post: U,
|
|
114
|
+
put: N,
|
|
115
|
+
patch: W,
|
|
116
|
+
delete: q,
|
|
117
|
+
cancel: D,
|
|
118
|
+
clearError: H
|
|
82
119
|
};
|
|
83
120
|
};
|
|
84
121
|
export {
|
|
85
|
-
|
|
122
|
+
M as useHttp
|
|
86
123
|
};
|
|
@@ -1,26 +1,41 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useCustomInterfaceAppearance as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { useActionsApi as C } from "./useActionsApi.js";
|
|
2
|
+
import { useCustomInterfaceAppearance as _ } from "./useCustomInterfaceAppearance.js";
|
|
3
|
+
import { useErrorTracking as w } from "./useErrorTracking.js";
|
|
4
|
+
import { useStripoErrorCategory as b } from "./useStripoErrorCategory.js";
|
|
5
|
+
import { useStripoEventHandler as k } from "./useStripoEventHandler.js";
|
|
6
|
+
import { useStripoSlackNotifier as v } from "./useStripoSlackNotifier.js";
|
|
7
|
+
import { useToaster as B } from "./useToaster.js";
|
|
8
|
+
import { displayConditions as V } from "../enums/displayConditions.js";
|
|
9
|
+
import x from "../extensions/Blocks/Checkbox/extension.js";
|
|
10
|
+
import F from "../extensions/Blocks/CouponBlock/extension.js";
|
|
11
|
+
import A from "../extensions/Blocks/RadioButton/extension.js";
|
|
12
|
+
import M from "../extensions/Blocks/Recommendation/extension.js";
|
|
13
|
+
import U from "../extensions/Blocks/Unsubscribe/extension.js";
|
|
14
|
+
import D from "../extensions/DynamicContent/extension.js";
|
|
15
|
+
import { useStripoApi as P } from "../services/stripoApi.js";
|
|
16
|
+
import R from "../static/styles/customEditorStyle.css.js";
|
|
17
|
+
import { useEditorStore as z } from "../stores/editor.js";
|
|
18
|
+
import { dynamicContentToMergeTags as H } from "../utils/genericUtil.js";
|
|
19
|
+
const no = (o) => {
|
|
20
|
+
const { handleError: g } = B(), { getToken: S, getCustomFonts: y } = P(), { handleEvent: E } = k(), { captureStripoError: c, withTimeout: f } = w(), { shouldCaptureSentry: u } = b(), { notifySlack: p } = v(), h = (m, n = []) => {
|
|
21
|
+
const r = z(), { html: i, css: a, forceRecreate: d } = m, l = (e) => {
|
|
22
|
+
const t = e instanceof Error ? e : new Error(String(e)), s = "stripo_runtime_error", I = u(s);
|
|
23
|
+
c(t, s, {
|
|
24
|
+
emailId: o.emailId,
|
|
25
|
+
userId: o.userId
|
|
26
|
+
}, I), p(
|
|
27
|
+
t.message,
|
|
28
|
+
s,
|
|
29
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
30
|
+
);
|
|
31
|
+
};
|
|
17
32
|
window.UIEditor.initEditor(
|
|
18
33
|
document.querySelector("#guido-editor"),
|
|
19
34
|
{
|
|
20
|
-
metadata:
|
|
21
|
-
html:
|
|
35
|
+
metadata: o,
|
|
36
|
+
html: i,
|
|
22
37
|
css: a,
|
|
23
|
-
forceRecreate:
|
|
38
|
+
forceRecreate: d,
|
|
24
39
|
locale: "en",
|
|
25
40
|
undoButtonSelector: "#guido__undo-button",
|
|
26
41
|
redoButtonSelector: "#guido__redo-button",
|
|
@@ -30,83 +45,167 @@ const j = (s) => {
|
|
|
30
45
|
customAppearanceMergetags: !0,
|
|
31
46
|
customAppearanceMergetagsBorderColor: "#f1f3fe",
|
|
32
47
|
customAppearanceMergetagsBackgroundColor: "#f1f3fe",
|
|
33
|
-
customViewStyles:
|
|
48
|
+
customViewStyles: R,
|
|
34
49
|
conditionsEnabled: !0,
|
|
35
50
|
customConditionsEnabled: !0,
|
|
36
|
-
conditionCategories:
|
|
51
|
+
conditionCategories: V,
|
|
37
52
|
enableXSSSecurity: !0,
|
|
38
53
|
messageSettingsEnabled: !1,
|
|
39
54
|
selectBlockAfterDropFromSettingsPanel: !0,
|
|
40
55
|
editorFonts: {
|
|
41
56
|
showDefaultStandardFonts: !0,
|
|
42
57
|
showDefaultNotStandardFonts: !0,
|
|
43
|
-
customFonts:
|
|
58
|
+
customFonts: n
|
|
44
59
|
},
|
|
45
60
|
mergeTags: [
|
|
46
61
|
{
|
|
47
|
-
entries:
|
|
62
|
+
entries: H(o.preselectedDynamicContentList)
|
|
48
63
|
}
|
|
49
64
|
],
|
|
50
|
-
async onTokenRefreshRequest(
|
|
65
|
+
async onTokenRefreshRequest(e) {
|
|
51
66
|
try {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
const t = await f(
|
|
68
|
+
S(),
|
|
69
|
+
1e4,
|
|
70
|
+
// 10 second timeout
|
|
71
|
+
"token_refresh",
|
|
72
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
73
|
+
);
|
|
74
|
+
e(t);
|
|
75
|
+
} catch (t) {
|
|
76
|
+
const s = "token_refresh", I = u(s);
|
|
77
|
+
c(t, s, {
|
|
78
|
+
templateId: o.emailId,
|
|
79
|
+
userId: o.userId
|
|
80
|
+
}, I), p(
|
|
81
|
+
"Token refresh operation failed",
|
|
82
|
+
s,
|
|
83
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
84
|
+
), g(t, "Failed to refresh token");
|
|
56
85
|
}
|
|
57
86
|
},
|
|
58
87
|
onTemplateLoaded() {
|
|
59
88
|
try {
|
|
60
|
-
const { importCss:
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
const { importCss: e } = _(), { activateCustomViewStyles: t } = C();
|
|
90
|
+
e(), t(), o.onReady(), r.isStripoInitialized = !0, r.loadingStatus = !1, setTimeout(() => {
|
|
91
|
+
r.hasChanges = !1;
|
|
63
92
|
}, 1e3);
|
|
64
|
-
} catch (
|
|
65
|
-
|
|
93
|
+
} catch (e) {
|
|
94
|
+
const t = "template_loaded", s = u(t);
|
|
95
|
+
c(e, t, {
|
|
96
|
+
templateId: o.emailId,
|
|
97
|
+
userId: o.userId
|
|
98
|
+
}, s), p(
|
|
99
|
+
"Template loading operation failed",
|
|
100
|
+
t,
|
|
101
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
102
|
+
), g(e, "Failed to load custom interface appearance");
|
|
66
103
|
}
|
|
67
104
|
},
|
|
68
|
-
onCodeEditorVisibilityChanged(
|
|
69
|
-
|
|
105
|
+
onCodeEditorVisibilityChanged(e) {
|
|
106
|
+
r.isCodeEditorOpen = e;
|
|
70
107
|
},
|
|
71
|
-
onEditorVisualModeChanged(
|
|
72
|
-
|
|
108
|
+
onEditorVisualModeChanged(e) {
|
|
109
|
+
r.editorVisualMode = e.toLowerCase();
|
|
73
110
|
},
|
|
74
|
-
onVersionHistoryVisibilityChanged(
|
|
75
|
-
|
|
111
|
+
onVersionHistoryVisibilityChanged(e) {
|
|
112
|
+
r.isVersionHistoryOpen = e;
|
|
76
113
|
},
|
|
77
114
|
onDataChanged() {
|
|
78
|
-
|
|
115
|
+
r.hasChanges = !0;
|
|
79
116
|
},
|
|
80
|
-
onEvent:
|
|
81
|
-
|
|
117
|
+
onEvent: E,
|
|
118
|
+
// Error handler for Stripo runtime errors (CORS, plugin issues, etc.)
|
|
119
|
+
onError: l,
|
|
120
|
+
ignoreClickOutsideSelectors: [
|
|
121
|
+
"#guido-dynamic-content-modal",
|
|
122
|
+
".in-on-board-wrapper",
|
|
123
|
+
".in-drawer__container"
|
|
124
|
+
],
|
|
82
125
|
extensions: [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
126
|
+
D,
|
|
127
|
+
x,
|
|
128
|
+
A,
|
|
129
|
+
M,
|
|
130
|
+
U,
|
|
131
|
+
F
|
|
87
132
|
]
|
|
88
133
|
}
|
|
89
134
|
);
|
|
90
|
-
},
|
|
135
|
+
}, T = (m) => new Promise((n, r) => {
|
|
91
136
|
if (document.getElementById("UiEditorScript")) {
|
|
92
|
-
|
|
137
|
+
m(), n();
|
|
93
138
|
return;
|
|
94
139
|
}
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
140
|
+
const i = document.createElement("script");
|
|
141
|
+
i.id = "UiEditorScript", i.type = "module", i.src = "https://plugins.stripo.email/resources/uieditor/latest/UIEditor.js";
|
|
142
|
+
const a = setTimeout(() => {
|
|
143
|
+
const d = new Error("Timeout loading Stripo UIEditor script (30s)"), l = "plugin_load_timeout", e = u(l);
|
|
144
|
+
c(d, l, {
|
|
145
|
+
scriptSrc: i.src,
|
|
146
|
+
emailId: o.emailId,
|
|
147
|
+
userId: o.userId
|
|
148
|
+
}, e), p(
|
|
149
|
+
`Stripo plugin failed to load (timeout): ${i.src}`,
|
|
150
|
+
l,
|
|
151
|
+
{ emailId: o.emailId, userId: o.userId, reason: "timeout" }
|
|
152
|
+
), r(d);
|
|
153
|
+
}, 3e4);
|
|
154
|
+
i.onload = () => {
|
|
155
|
+
clearTimeout(a), m(), n();
|
|
156
|
+
}, i.onerror = (d) => {
|
|
157
|
+
clearTimeout(a);
|
|
158
|
+
const l = new Error("Failed to load Stripo UIEditor script"), e = d instanceof Event ? d.type : String(d), t = "plugin_load_error", s = u(t);
|
|
159
|
+
c(l, t, {
|
|
160
|
+
scriptSrc: i.src,
|
|
161
|
+
event: e,
|
|
162
|
+
emailId: o.emailId,
|
|
163
|
+
userId: o.userId
|
|
164
|
+
}, s), p(
|
|
165
|
+
`Stripo plugin failed to load: ${e}`,
|
|
166
|
+
t,
|
|
167
|
+
{ emailId: o.emailId, userId: o.userId, scriptSrc: i.src }
|
|
168
|
+
), r(l);
|
|
169
|
+
}, document.body.appendChild(i);
|
|
102
170
|
});
|
|
103
|
-
return { initPlugin: async (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
171
|
+
return { initPlugin: async (m) => {
|
|
172
|
+
try {
|
|
173
|
+
await T(async () => {
|
|
174
|
+
try {
|
|
175
|
+
const n = await f(
|
|
176
|
+
y(),
|
|
177
|
+
5e3,
|
|
178
|
+
// 5 second timeout for fonts
|
|
179
|
+
"load_custom_fonts",
|
|
180
|
+
{ emailId: o.emailId }
|
|
181
|
+
);
|
|
182
|
+
h(m, n);
|
|
183
|
+
} catch (n) {
|
|
184
|
+
const r = "init_editor", i = u(r);
|
|
185
|
+
throw c(n, r, {
|
|
186
|
+
templateId: o.emailId,
|
|
187
|
+
userId: o.userId,
|
|
188
|
+
hasTemplate: !!m.html
|
|
189
|
+
}, i), p(
|
|
190
|
+
"Editor initialization failed",
|
|
191
|
+
r,
|
|
192
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
193
|
+
), n;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
} catch (n) {
|
|
197
|
+
const r = "init_plugin", i = u(r);
|
|
198
|
+
throw c(n, r, {
|
|
199
|
+
templateId: o.emailId,
|
|
200
|
+
userId: o.userId
|
|
201
|
+
}, i), p(
|
|
202
|
+
"Plugin initialization failed",
|
|
203
|
+
r,
|
|
204
|
+
{ emailId: o.emailId, userId: o.userId }
|
|
205
|
+
), n;
|
|
206
|
+
}
|
|
108
207
|
} };
|
|
109
208
|
};
|
|
110
209
|
export {
|
|
111
|
-
|
|
210
|
+
no as useStripo
|
|
112
211
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error categorization system for Stripo integration
|
|
3
|
+
* Determines whether errors should be logged to Sentry/FullStory, Slack, or both
|
|
4
|
+
*
|
|
5
|
+
* Note: Error type names use snake_case (e.g., plugin_load_error) to match
|
|
6
|
+
* error type strings used throughout the codebase. This is intentional and
|
|
7
|
+
* required for the categorization system to work correctly.
|
|
8
|
+
*/
|
|
9
|
+
export type ErrorSeverity = 'critical' | 'warning' | 'info';
|
|
10
|
+
export type ErrorCaptureLevel = 'sentry_and_slack' | 'slack_only' | 'sentry_only';
|
|
11
|
+
export interface ErrorCategory {
|
|
12
|
+
type: string;
|
|
13
|
+
severity: ErrorSeverity;
|
|
14
|
+
captureLevel: ErrorCaptureLevel;
|
|
15
|
+
description: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Categorize an error based on its type
|
|
19
|
+
* Returns the error category with capture level and severity
|
|
20
|
+
*/
|
|
21
|
+
export declare const useStripoErrorCategory: () => {
|
|
22
|
+
getErrorCategory: (errorType: string) => ErrorCategory;
|
|
23
|
+
shouldCaptureSentry: (errorType: string) => boolean;
|
|
24
|
+
shouldNotifySlack: (errorType: string) => boolean;
|
|
25
|
+
addErrorCategory: (category: ErrorCategory) => void;
|
|
26
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const i = {
|
|
2
|
+
// Critical errors: Log to Sentry + Alert Slack
|
|
3
|
+
plugin_load_error: {
|
|
4
|
+
type: "plugin_load_error",
|
|
5
|
+
severity: "critical",
|
|
6
|
+
captureLevel: "sentry_and_slack",
|
|
7
|
+
description: "Stripo UIEditor.js script failed to load"
|
|
8
|
+
},
|
|
9
|
+
plugin_load_timeout: {
|
|
10
|
+
type: "plugin_load_timeout",
|
|
11
|
+
severity: "critical",
|
|
12
|
+
captureLevel: "sentry_and_slack",
|
|
13
|
+
description: "Stripo script loading exceeded timeout threshold"
|
|
14
|
+
},
|
|
15
|
+
authentication_error: {
|
|
16
|
+
type: "authentication_error",
|
|
17
|
+
severity: "critical",
|
|
18
|
+
captureLevel: "sentry_and_slack",
|
|
19
|
+
description: "Token or authentication failure"
|
|
20
|
+
},
|
|
21
|
+
// Handled errors: Alert Slack but DON'T log to Sentry/FullStory
|
|
22
|
+
cors_error: {
|
|
23
|
+
type: "cors_error",
|
|
24
|
+
severity: "warning",
|
|
25
|
+
captureLevel: "slack_only",
|
|
26
|
+
description: "CORS policy blocked resource (can be caught before Sentry)"
|
|
27
|
+
},
|
|
28
|
+
// Runtime errors: Log to Sentry but DON'T alert Slack
|
|
29
|
+
stripo_runtime_error: {
|
|
30
|
+
type: "stripo_runtime_error",
|
|
31
|
+
severity: "warning",
|
|
32
|
+
captureLevel: "sentry_only",
|
|
33
|
+
description: "Runtime error from Stripo editor"
|
|
34
|
+
},
|
|
35
|
+
init_editor: {
|
|
36
|
+
type: "init_editor",
|
|
37
|
+
severity: "warning",
|
|
38
|
+
captureLevel: "sentry_only",
|
|
39
|
+
description: "Editor initialization failure"
|
|
40
|
+
},
|
|
41
|
+
init_plugin: {
|
|
42
|
+
type: "init_plugin",
|
|
43
|
+
severity: "warning",
|
|
44
|
+
captureLevel: "sentry_only",
|
|
45
|
+
description: "Plugin initialization failure"
|
|
46
|
+
},
|
|
47
|
+
token_refresh: {
|
|
48
|
+
type: "token_refresh",
|
|
49
|
+
severity: "warning",
|
|
50
|
+
captureLevel: "sentry_only",
|
|
51
|
+
description: "Token refresh operation failed"
|
|
52
|
+
},
|
|
53
|
+
template_loaded: {
|
|
54
|
+
type: "template_loaded",
|
|
55
|
+
severity: "warning",
|
|
56
|
+
captureLevel: "sentry_only",
|
|
57
|
+
description: "Template loading operation failed"
|
|
58
|
+
}
|
|
59
|
+
}, l = () => {
|
|
60
|
+
const t = (e) => {
|
|
61
|
+
const r = i[e];
|
|
62
|
+
return r || {
|
|
63
|
+
type: e,
|
|
64
|
+
severity: "warning",
|
|
65
|
+
captureLevel: "sentry_only",
|
|
66
|
+
description: "Unknown error type"
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
getErrorCategory: t,
|
|
71
|
+
shouldCaptureSentry: (e) => {
|
|
72
|
+
const r = t(e);
|
|
73
|
+
return ["sentry_and_slack", "sentry_only"].includes(r.captureLevel);
|
|
74
|
+
},
|
|
75
|
+
shouldNotifySlack: (e) => {
|
|
76
|
+
const r = t(e);
|
|
77
|
+
return ["sentry_and_slack", "slack_only"].includes(r.captureLevel);
|
|
78
|
+
},
|
|
79
|
+
addErrorCategory: (e) => {
|
|
80
|
+
i[e.type] = e;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
export {
|
|
85
|
+
l as useStripoErrorCategory
|
|
86
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack notifications for Stripo errors
|
|
3
|
+
* Uses error categorization to determine which errors should trigger Slack alerts
|
|
4
|
+
* Prevents duplicate alerts within the same session
|
|
5
|
+
*/
|
|
6
|
+
export declare const useStripoSlackNotifier: () => {
|
|
7
|
+
notifySlack: (errorMessage: string, errorType: string, additionalContext?: Record<string, unknown>) => Promise<boolean>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useStripoErrorCategory as g } from "./useStripoErrorCategory.js";
|
|
2
|
+
import { getSlackNotificationService as f } from "../services/slackNotificationService.js";
|
|
3
|
+
import { getStripoErrorDeduplicationService as u } from "../services/stripoErrorDeduplicationService.js";
|
|
4
|
+
const w = () => {
|
|
5
|
+
const c = f(), s = u(), { shouldNotifySlack: a, getErrorCategory: l } = g();
|
|
6
|
+
return {
|
|
7
|
+
notifySlack: async (o, t, r) => {
|
|
8
|
+
const e = l(t), i = a(t) || e.captureLevel === "sentry_only", S = {
|
|
9
|
+
critical: "critical",
|
|
10
|
+
warning: "high",
|
|
11
|
+
info: "low"
|
|
12
|
+
};
|
|
13
|
+
let n = o;
|
|
14
|
+
i && (n += `
|
|
15
|
+
|
|
16
|
+
_Also logged to Sentry/FullStory for analysis_`);
|
|
17
|
+
const p = {
|
|
18
|
+
title: `Stripo ${t.replace(/_/g, " ").toUpperCase()}`,
|
|
19
|
+
message: n,
|
|
20
|
+
errorType: t,
|
|
21
|
+
severity: S[e.severity] || "high",
|
|
22
|
+
context: {
|
|
23
|
+
...r,
|
|
24
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25
|
+
environment: "production",
|
|
26
|
+
captureLevel: e.captureLevel,
|
|
27
|
+
description: e.description,
|
|
28
|
+
loggedToSentry: i
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return s.trackError({
|
|
32
|
+
errorType: t,
|
|
33
|
+
errorMessage: o,
|
|
34
|
+
errorCategory: e.severity,
|
|
35
|
+
context: {
|
|
36
|
+
...r,
|
|
37
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38
|
+
environment: "production"
|
|
39
|
+
},
|
|
40
|
+
reportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
41
|
+
}) ? c.sendErrorNotification(p) : !1;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
w as useStripoSlackNotifier
|
|
47
|
+
};
|