@useinsider/guido 1.0.3-beta.dfb1fcf → 1.0.3-beta.e1adf59
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 +3 -144
- package/dist/components/Guido.vue.js +10 -12
- package/dist/components/Guido.vue2.js +101 -84
- package/dist/components/organisms/header/LeftSlot.vue.js +1 -1
- package/dist/components/organisms/header/LeftSlot.vue2.js +15 -16
- package/dist/components/organisms/header/RightSlot.vue.js +11 -11
- package/dist/components/organisms/header/RightSlot.vue2.js +22 -23
- package/dist/components/organisms/onboarding/NewVersionPopup.vue.js +9 -9
- package/dist/components/organisms/onboarding/NewVersionPopup.vue2.js +17 -30
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue.js +10 -12
- package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -19
- package/dist/composables/useApiErrorTracking.js +120 -0
- package/dist/composables/useErrorTracking.js +98 -0
- package/dist/composables/useGuidoActions.js +9 -19
- package/dist/composables/useHttp.js +89 -52
- package/dist/composables/useStripo.js +163 -66
- package/dist/composables/useStripoErrorCategory.js +86 -0
- package/dist/composables/useStripoSlackNotifier.js +47 -0
- package/dist/config/compiler/unsubscribeCompilerRules.js +28 -33
- package/dist/config/migrator/index.js +6 -7
- package/dist/enums/defaults.js +8 -16
- package/dist/enums/onboarding.js +1 -2
- package/dist/enums/unsubscribe.js +25 -27
- package/dist/extensions/Blocks/Checkbox/extension.js +2 -2
- package/dist/extensions/Blocks/CouponBlock/extension.js +2 -2
- package/dist/extensions/Blocks/Recommendation/block.js +3 -6
- package/dist/extensions/Blocks/Recommendation/control.js +65 -109
- package/dist/extensions/Blocks/Recommendation/extension.js +7 -18
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +21 -159
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +1 -1
- package/dist/extensions/Blocks/Recommendation/template.js +200 -0
- package/dist/extensions/Blocks/common-control.js +43 -125
- package/dist/extensions/DynamicContent/dynamic-content-modal.js +19 -25
- package/dist/extensions/DynamicContent/dynamic-content.js +33 -128
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +100 -312
- package/dist/package.json.js +1 -1
- package/dist/services/slackNotificationService.js +167 -0
- package/dist/services/stripoApi.js +49 -19
- package/dist/services/stripoErrorDeduplicationService.js +91 -0
- package/dist/src/@types/generic.d.ts +6 -42
- package/dist/src/components/Guido.vue.d.ts +3 -4
- package/dist/src/components/organisms/onboarding/NewVersionPopup.vue.d.ts +1 -3
- package/dist/src/components/organisms/onboarding/OnboardingWrapper.vue.d.ts +1 -3
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useApiErrorTracking.d.ts +26 -0
- package/dist/src/composables/useErrorTracking.d.ts +30 -0
- package/dist/src/composables/useGuidoActions.d.ts +0 -9
- package/dist/src/composables/useStripoErrorCategory.d.ts +26 -0
- package/dist/src/composables/useStripoSlackNotifier.d.ts +8 -0
- package/dist/src/enums/onboarding.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/control.d.ts +2 -11
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/template.d.ts +6 -0
- package/dist/src/extensions/Blocks/common-control.d.ts +0 -21
- package/dist/src/extensions/DynamicContent/dynamic-content-modal.d.ts +2 -9
- package/dist/src/extensions/DynamicContent/dynamic-content.d.ts +2 -52
- package/dist/src/services/slackNotificationService.d.ts +110 -0
- package/dist/src/services/stripoErrorDeduplicationService.d.ts +75 -0
- package/dist/src/stores/config.d.ts +2 -10
- package/dist/src/stores/dynamic-content.d.ts +3 -3
- package/dist/src/stores/editor.d.ts +1 -1
- package/dist/src/stores/onboarding.d.ts +1 -1
- package/dist/src/stores/preview.d.ts +1 -1
- package/dist/src/stores/recommendation.d.ts +1 -1
- package/dist/src/stores/save-as-template.d.ts +1 -1
- package/dist/src/stores/toaster.d.ts +1 -1
- package/dist/src/stores/unsubscribe.d.ts +1 -1
- package/dist/src/stores/version-history.d.ts +1 -1
- package/dist/src/utils/dateUtil.d.ts +0 -21
- package/dist/src/utils/genericUtil.d.ts +0 -1
- package/dist/static/styles/components/narrow-panel.css.js +0 -10
- package/dist/static/styles/components/wide-panel.css.js +4 -0
- package/dist/static/styles/customEditorStyle.css.js +0 -19
- package/dist/stores/config.js +5 -5
- package/dist/stores/dynamic-content.js +2 -2
- package/dist/stores/editor.js +1 -1
- package/dist/stores/onboarding.js +27 -27
- package/dist/stores/preview.js +1 -1
- package/dist/stores/recommendation.js +3 -3
- package/dist/stores/save-as-template.js +2 -2
- package/dist/stores/toaster.js +1 -1
- package/dist/stores/unsubscribe.js +1 -1
- package/dist/stores/version-history.js +4 -4
- package/dist/utils/dateUtil.js +3 -24
- package/dist/utils/genericUtil.js +9 -20
- package/package.json +3 -3
- package/dist/composables/useBlocksConfig.js +0 -49
- package/dist/config/migrator/recommendationMigrator.js +0 -293
- package/dist/enums/date.js +0 -6
- package/dist/extensions/Blocks/Recommendation/cardCompositionControl.js +0 -193
- package/dist/extensions/Blocks/Recommendation/constants.js +0 -14
- package/dist/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.js +0 -68
- package/dist/extensions/Blocks/Recommendation/controls/index.js +0 -272
- package/dist/extensions/Blocks/Recommendation/controls/nameTextTrimControl.js +0 -74
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscountTextAfterControl.js +0 -71
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscountTextBeforeControl.js +0 -71
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPriceTextAfterControl.js +0 -71
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPriceTextBeforeControl.js +0 -71
- package/dist/extensions/Blocks/Recommendation/controls/priceHideControl.js +0 -60
- package/dist/extensions/Blocks/Recommendation/controls/priceInlineLayoutControl.js +0 -160
- package/dist/extensions/Blocks/Recommendation/controls/spacingControl.js +0 -188
- package/dist/extensions/Blocks/Recommendation/templates/blockTemplate.js +0 -184
- package/dist/extensions/Blocks/Recommendation/templates/migrationTemplate.js +0 -189
- package/dist/extensions/Blocks/Recommendation/templates/templateUtils.js +0 -209
- package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +0 -25
- package/dist/extensions/Blocks/controlFactories.js +0 -234
- package/dist/src/composables/useBlocksConfig.d.ts +0 -11
- package/dist/src/config/migrator/recommendationMigrator.d.ts +0 -1
- package/dist/src/enums/date.d.ts +0 -4
- package/dist/src/extensions/Blocks/Recommendation/cardCompositionControl.d.ts +0 -79
- package/dist/src/extensions/Blocks/Recommendation/constants.d.ts +0 -91
- package/dist/src/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.d.ts +0 -25
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +0 -71
- package/dist/src/extensions/Blocks/Recommendation/controls/nameTextTrimControl.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscountTextAfterControl.d.ts +0 -15
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscountTextBeforeControl.d.ts +0 -15
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPriceTextAfterControl.d.ts +0 -15
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPriceTextBeforeControl.d.ts +0 -15
- package/dist/src/extensions/Blocks/Recommendation/controls/priceHideControl.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/controls/priceInlineLayoutControl.d.ts +0 -50
- package/dist/src/extensions/Blocks/Recommendation/controls/spacingControl.d.ts +0 -60
- package/dist/src/extensions/Blocks/Recommendation/templates/blockTemplate.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/templates/migrationTemplate.d.ts +0 -16
- package/dist/src/extensions/Blocks/Recommendation/templates/templateUtils.d.ts +0 -52
- package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -19
- package/dist/src/extensions/Blocks/controlFactories.d.ts +0 -95
- package/dist/src/utils/environmentUtil.d.ts +0 -5
- package/dist/utils/environmentUtil.js +0 -4
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var h = (t, e, r) => e in t ? d(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
+
var i = (t, e, r) => h(t, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
+
class u {
|
|
5
|
+
constructor(e, r) {
|
|
6
|
+
i(this, "webhookUrl");
|
|
7
|
+
i(this, "channel");
|
|
8
|
+
i(this, "defaultUsername");
|
|
9
|
+
i(this, "enabled");
|
|
10
|
+
this.webhookUrl = e || void 0 || "", this.channel = (r == null ? void 0 : r.channel) || "#errors", this.defaultUsername = (r == null ? void 0 : r.username) || "Guido Error Bot", this.enabled = (r == null ? void 0 : r.enabled) !== !1, this.webhookUrl || (console.warn("[SlackNotificationService] Webhook URL not configured, Slack notifications disabled"), this.enabled = !1);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Send an error notification to Slack
|
|
14
|
+
*/
|
|
15
|
+
async sendErrorNotification(e) {
|
|
16
|
+
if (!this.enabled || !this.webhookUrl)
|
|
17
|
+
return !1;
|
|
18
|
+
try {
|
|
19
|
+
const r = this.buildErrorPayload(e), a = await fetch(this.webhookUrl, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: {
|
|
22
|
+
"Content-Type": "application/json"
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify(r)
|
|
25
|
+
});
|
|
26
|
+
return a.ok ? !0 : (console.error("[SlackNotificationService] Failed to send Slack notification:", a.statusText), !1);
|
|
27
|
+
} catch (r) {
|
|
28
|
+
return console.error("[SlackNotificationService] Error sending Slack notification:", r), !1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Send a critical error that requires immediate attention
|
|
33
|
+
*/
|
|
34
|
+
async sendCriticalError(e, r, a) {
|
|
35
|
+
return this.sendErrorNotification({
|
|
36
|
+
title: e,
|
|
37
|
+
message: r,
|
|
38
|
+
errorType: "critical",
|
|
39
|
+
severity: "critical",
|
|
40
|
+
context: a,
|
|
41
|
+
timestamp: Date.now()
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Send a CORS error notification
|
|
46
|
+
*/
|
|
47
|
+
async sendCorsErrorNotification(e, r) {
|
|
48
|
+
return this.sendCriticalError(
|
|
49
|
+
"CORS Error in Stripo Email Editor",
|
|
50
|
+
"Failed to load Stripo resources due to CORS restrictions",
|
|
51
|
+
{
|
|
52
|
+
resourceUrl: e,
|
|
53
|
+
...r,
|
|
54
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Send a plugin load error notification
|
|
60
|
+
*/
|
|
61
|
+
async sendPluginLoadErrorNotification(e, r) {
|
|
62
|
+
return this.sendCriticalError(
|
|
63
|
+
"Stripo Plugin Failed to Load",
|
|
64
|
+
`Email editor initialization failed: ${e}`,
|
|
65
|
+
{
|
|
66
|
+
...r,
|
|
67
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build Slack message payload from error notification
|
|
73
|
+
*/
|
|
74
|
+
buildErrorPayload(e) {
|
|
75
|
+
const a = {
|
|
76
|
+
critical: "#E74C3C",
|
|
77
|
+
// Red
|
|
78
|
+
high: "#E67E22",
|
|
79
|
+
// Orange
|
|
80
|
+
medium: "#F39C12",
|
|
81
|
+
// Yellow
|
|
82
|
+
low: "#3498DB"
|
|
83
|
+
// Blue
|
|
84
|
+
}[e.severity] || "#95A5A6", l = [
|
|
85
|
+
{
|
|
86
|
+
title: "Error Type",
|
|
87
|
+
value: e.errorType,
|
|
88
|
+
short: !0
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
title: "Severity",
|
|
92
|
+
value: e.severity.toUpperCase(),
|
|
93
|
+
short: !0
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
title: "Timestamp",
|
|
97
|
+
value: e.timestamp ? new Date(e.timestamp).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
98
|
+
short: !0
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
e.context && Object.entries(e.context).forEach(([n, c]) => {
|
|
102
|
+
l.length < 20 && l.push({
|
|
103
|
+
title: this.formatFieldTitle(n),
|
|
104
|
+
value: this.formatFieldValue(c),
|
|
105
|
+
short: !0
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
const s = {
|
|
109
|
+
color: a,
|
|
110
|
+
title: e.title,
|
|
111
|
+
text: e.message,
|
|
112
|
+
fields: l,
|
|
113
|
+
footer: "Guido Error Tracking",
|
|
114
|
+
ts: Math.floor((e.timestamp || Date.now()) / 1e3)
|
|
115
|
+
};
|
|
116
|
+
return e.stackTrace && (s.text = `${e.message}
|
|
117
|
+
\`\`\`${e.stackTrace}\`\`\``), {
|
|
118
|
+
channel: this.channel,
|
|
119
|
+
username: this.defaultUsername,
|
|
120
|
+
// eslint-disable-next-line camelcase
|
|
121
|
+
icon_emoji: ":warning:",
|
|
122
|
+
attachments: [s]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Format field title for Slack (e.g., emailId -> Email ID)
|
|
127
|
+
*/
|
|
128
|
+
formatFieldTitle(e) {
|
|
129
|
+
return e.replace(/([A-Z])/g, " $1").replace(/^./, (r) => r.toUpperCase()).trim();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Format field value for Slack display
|
|
133
|
+
*/
|
|
134
|
+
formatFieldValue(e) {
|
|
135
|
+
return e == null ? "(empty)" : typeof e == "object" ? JSON.stringify(e).slice(0, 500) : String(e).slice(0, 500);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if notifications are enabled
|
|
139
|
+
*/
|
|
140
|
+
isEnabled() {
|
|
141
|
+
return this.enabled;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Update webhook URL
|
|
145
|
+
*/
|
|
146
|
+
setWebhookUrl(e) {
|
|
147
|
+
this.webhookUrl = e, this.enabled = !!e;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Update channel
|
|
151
|
+
*/
|
|
152
|
+
setChannel(e) {
|
|
153
|
+
this.channel = e;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Enable/disable notifications
|
|
157
|
+
*/
|
|
158
|
+
setEnabled(e) {
|
|
159
|
+
this.enabled = e && !!this.webhookUrl;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
let o = null;
|
|
163
|
+
const S = () => (o || (o = new u()), o);
|
|
164
|
+
export {
|
|
165
|
+
u as SlackNotificationService,
|
|
166
|
+
S as getSlackNotificationService
|
|
167
|
+
};
|
|
@@ -1,25 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { useApiErrorTracking as i } from "../composables/useApiErrorTracking.js";
|
|
2
|
+
import { useHttp as c } from "../composables/useHttp.js";
|
|
3
|
+
import { useToaster as p } from "../composables/useToaster.js";
|
|
4
|
+
const h = () => {
|
|
5
|
+
const { get: s } = c(), { handleError: n } = p(), { withParsingErrorTracking: a } = i();
|
|
5
6
|
return {
|
|
6
7
|
getToken: async () => {
|
|
7
8
|
try {
|
|
8
|
-
const t = Number(localStorage.getItem("ins-guido-test-instance")), { data: e } = await
|
|
9
|
-
return
|
|
9
|
+
const t = Number(localStorage.getItem("ins-guido-test-instance")), { data: e } = await s(`/stripo/get-user-token?test=${t}`);
|
|
10
|
+
return a(
|
|
11
|
+
() => {
|
|
12
|
+
var o;
|
|
13
|
+
if (!((o = e == null ? void 0 : e.body) != null && o.token))
|
|
14
|
+
throw new Error("Invalid token response: missing token in response body");
|
|
15
|
+
return e.body.token;
|
|
16
|
+
},
|
|
17
|
+
"/stripo/get-user-token",
|
|
18
|
+
e,
|
|
19
|
+
{ endpoint: "/stripo/get-user-token", operation: "getToken" }
|
|
20
|
+
);
|
|
10
21
|
} catch (t) {
|
|
11
|
-
return
|
|
22
|
+
return n(t, "Failed to fetch token"), "";
|
|
12
23
|
}
|
|
13
24
|
},
|
|
14
25
|
getCustomFonts: async () => {
|
|
15
26
|
try {
|
|
16
|
-
const { data: t = [] } = await
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
const { data: t = [] } = await s("/stripo/get-partner-custom-fonts");
|
|
28
|
+
return a(
|
|
29
|
+
() => {
|
|
30
|
+
if (!Array.isArray(t))
|
|
31
|
+
throw new Error("Invalid fonts response: expected array");
|
|
32
|
+
return t.map((r) => ({
|
|
33
|
+
...r,
|
|
34
|
+
active: !0
|
|
35
|
+
}));
|
|
36
|
+
},
|
|
37
|
+
"/stripo/get-partner-custom-fonts",
|
|
38
|
+
t,
|
|
39
|
+
{ endpoint: "/stripo/get-partner-custom-fonts", operation: "getCustomFonts" }
|
|
40
|
+
);
|
|
21
41
|
} catch (t) {
|
|
22
|
-
return
|
|
42
|
+
return n(t, "Failed to fetch custom fonts"), [];
|
|
23
43
|
}
|
|
24
44
|
},
|
|
25
45
|
getDefaultTemplate: async () => {
|
|
@@ -29,21 +49,31 @@ const m = () => {
|
|
|
29
49
|
forceRecreate: !0
|
|
30
50
|
};
|
|
31
51
|
try {
|
|
32
|
-
const { data: e } = await
|
|
52
|
+
const { data: e } = await s("/stripo/default-template");
|
|
33
53
|
try {
|
|
34
54
|
return {
|
|
35
|
-
...
|
|
55
|
+
...a(
|
|
56
|
+
() => {
|
|
57
|
+
const o = JSON.parse(e);
|
|
58
|
+
if (!o.html)
|
|
59
|
+
throw new Error("Invalid template response: missing html field");
|
|
60
|
+
return o;
|
|
61
|
+
},
|
|
62
|
+
"/stripo/default-template",
|
|
63
|
+
e,
|
|
64
|
+
{ endpoint: "/stripo/default-template", operation: "getDefaultTemplate" }
|
|
65
|
+
),
|
|
36
66
|
forceRecreate: !0
|
|
37
67
|
};
|
|
38
|
-
} catch {
|
|
39
|
-
return t;
|
|
68
|
+
} catch (r) {
|
|
69
|
+
return r instanceof Error && !r.message.includes("Invalid template") && n(r, "Failed to parse template as JSON"), t;
|
|
40
70
|
}
|
|
41
71
|
} catch (e) {
|
|
42
|
-
return
|
|
72
|
+
return n(e, "Failed to fetch default template"), t;
|
|
43
73
|
}
|
|
44
74
|
}
|
|
45
75
|
};
|
|
46
76
|
};
|
|
47
77
|
export {
|
|
48
|
-
|
|
78
|
+
h as useStripoApi
|
|
49
79
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var c = Object.defineProperty;
|
|
2
|
+
var a = (e, r, t) => r in e ? c(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
|
|
3
|
+
var n = (e, r, t) => a(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
class s {
|
|
5
|
+
constructor() {
|
|
6
|
+
n(this, "reportedErrors", /* @__PURE__ */ new Set());
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Track an error locally to prevent duplicate Slack alerts
|
|
10
|
+
* Only sends Slack alert once per unique error within the same session
|
|
11
|
+
*/
|
|
12
|
+
trackError(r) {
|
|
13
|
+
const t = this.getDeduplicationKey(r);
|
|
14
|
+
return this.reportedErrors.has(t) ? !1 : (this.reportedErrors.add(t), !0);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Track plugin load error locally (CORS, script failure, timeout)
|
|
18
|
+
*/
|
|
19
|
+
trackPluginLoadError(r, t) {
|
|
20
|
+
return this.trackError({
|
|
21
|
+
errorType: "plugin_load_error",
|
|
22
|
+
errorMessage: r,
|
|
23
|
+
errorCategory: "critical",
|
|
24
|
+
context: {
|
|
25
|
+
...t,
|
|
26
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27
|
+
environment: "production"
|
|
28
|
+
},
|
|
29
|
+
reportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Track CORS error locally
|
|
34
|
+
*/
|
|
35
|
+
trackCorsError(r, t) {
|
|
36
|
+
return this.trackError({
|
|
37
|
+
errorType: "cors_error",
|
|
38
|
+
errorMessage: r,
|
|
39
|
+
errorCategory: "handled",
|
|
40
|
+
context: {
|
|
41
|
+
...t,
|
|
42
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43
|
+
environment: "production"
|
|
44
|
+
},
|
|
45
|
+
reportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Track authentication error locally (token refresh failure)
|
|
50
|
+
* Tracks it, but Slack notifier decides whether to alert based on token expiration
|
|
51
|
+
*/
|
|
52
|
+
trackAuthenticationError(r, t) {
|
|
53
|
+
return this.trackError({
|
|
54
|
+
errorType: "authentication_error",
|
|
55
|
+
errorMessage: r,
|
|
56
|
+
errorCategory: "critical",
|
|
57
|
+
context: {
|
|
58
|
+
...t,
|
|
59
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
60
|
+
environment: "production"
|
|
61
|
+
},
|
|
62
|
+
reportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Generate unique deduplication key for error
|
|
67
|
+
* Format: "errorType:emailId:userId" to allow same error on different emails
|
|
68
|
+
*/
|
|
69
|
+
getDeduplicationKey(r) {
|
|
70
|
+
const t = r.context.emailId || "unknown", i = r.context.userId || "unknown";
|
|
71
|
+
return `${r.errorType}:${t}:${i}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Clear tracked errors (for testing or session reset)
|
|
75
|
+
*/
|
|
76
|
+
clearTrackedErrors() {
|
|
77
|
+
this.reportedErrors.clear();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get count of errors tracked in this session
|
|
81
|
+
*/
|
|
82
|
+
getTrackedErrorCount() {
|
|
83
|
+
return this.reportedErrors.size;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
let o = null;
|
|
87
|
+
const u = () => (o || (o = new s()), o);
|
|
88
|
+
export {
|
|
89
|
+
s as StripoErrorDeduplicationService,
|
|
90
|
+
u as getStripoErrorDeduplicationService
|
|
91
|
+
};
|
|
@@ -6,71 +6,36 @@ type Features = {
|
|
|
6
6
|
dynamicContent?: boolean;
|
|
7
7
|
saveAsTemplate?: boolean;
|
|
8
8
|
versionHistory?: boolean;
|
|
9
|
-
testMessage?: boolean;
|
|
10
|
-
displayConditions?: boolean;
|
|
11
9
|
};
|
|
12
10
|
type Partner = {
|
|
13
11
|
partnerName: string;
|
|
14
12
|
productType: number;
|
|
15
13
|
messageType: number;
|
|
16
14
|
};
|
|
17
|
-
export type GuidoBlockType = 'amp-accordion' | 'amp-carousel' | 'amp-form-controls' | 'banner-block' | 'button-block' | 'html-block' | 'image-block' | 'menu-block' | 'social-block' | 'spacer-block' | 'text-block' | 'timer-block' | 'video-block';
|
|
18
|
-
export type GuidoCustomBlockType = 'dynamic-content' | 'checkbox-block' | 'radio-button-block' | 'recommendation-block' | 'unsubscribe-block' | 'coupon-block' | 'items-block';
|
|
19
|
-
type BlocksConfig = {
|
|
20
|
-
excludeDefaults?: GuidoBlockType[];
|
|
21
|
-
includeCustoms?: GuidoCustomBlockType[];
|
|
22
|
-
};
|
|
23
15
|
export type GuidoConfig = {
|
|
24
16
|
translationsPath: string;
|
|
25
17
|
htmlCompilerRules?: CompilerRule[];
|
|
26
18
|
ignoreDefaultHtmlCompilerRules?: boolean;
|
|
27
19
|
useHeader?: boolean;
|
|
28
20
|
emailHeader: EmailHeader;
|
|
29
|
-
migrationDate: number;
|
|
30
21
|
partner?: Partner;
|
|
31
22
|
extensions?: Extensions;
|
|
32
23
|
features?: Features;
|
|
33
|
-
blocks?: BlocksConfig;
|
|
34
|
-
backButtonLabel?: string;
|
|
35
24
|
};
|
|
36
25
|
export type TemplateConfig = {
|
|
37
26
|
preselectedDynamicContentList?: DynamicContent[];
|
|
38
27
|
selectedUnsubscribePages?: number[];
|
|
39
28
|
variationId?: string;
|
|
40
29
|
};
|
|
41
|
-
export type
|
|
30
|
+
export type DynamicContent = {
|
|
42
31
|
value: string;
|
|
32
|
+
text: string;
|
|
43
33
|
fallback?: string;
|
|
44
34
|
format?: {
|
|
45
35
|
key: string;
|
|
46
36
|
value: string;
|
|
47
37
|
};
|
|
48
38
|
};
|
|
49
|
-
export type DynamicContent = BaseDynamicContent & {
|
|
50
|
-
text: string;
|
|
51
|
-
};
|
|
52
|
-
export type MergeTag = BaseDynamicContent & {
|
|
53
|
-
label: string;
|
|
54
|
-
selStart?: number;
|
|
55
|
-
selEnd?: number;
|
|
56
|
-
hidden?: boolean;
|
|
57
|
-
};
|
|
58
|
-
export type PositionData = {
|
|
59
|
-
x: number;
|
|
60
|
-
y: number;
|
|
61
|
-
width?: number;
|
|
62
|
-
height?: number;
|
|
63
|
-
};
|
|
64
|
-
export type DynamicContentEvent = {
|
|
65
|
-
attribute: DynamicContent;
|
|
66
|
-
position?: PositionData;
|
|
67
|
-
};
|
|
68
|
-
export type MergeTagClickEvent = {
|
|
69
|
-
position: PositionData;
|
|
70
|
-
element: HTMLElement;
|
|
71
|
-
tagValue: string | null;
|
|
72
|
-
tagLabel: string | null;
|
|
73
|
-
};
|
|
74
39
|
export interface EmailHeader {
|
|
75
40
|
senderName: string;
|
|
76
41
|
subject: string;
|
|
@@ -86,13 +51,12 @@ export interface TooltipOptions {
|
|
|
86
51
|
};
|
|
87
52
|
preventXss?: boolean;
|
|
88
53
|
}
|
|
54
|
+
export type MergeTag = {
|
|
55
|
+
label: string;
|
|
56
|
+
value: string;
|
|
57
|
+
};
|
|
89
58
|
export type TextValueObject = {
|
|
90
59
|
text: string;
|
|
91
60
|
value: string;
|
|
92
61
|
};
|
|
93
|
-
export interface L10n {
|
|
94
|
-
locale?: string;
|
|
95
|
-
timezone?: string;
|
|
96
|
-
time?: number;
|
|
97
|
-
}
|
|
98
62
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DynamicContent, GuidoConfig,
|
|
1
|
+
import type { DynamicContent, GuidoConfig, TemplateConfig } from '@@/Types/generic';
|
|
2
2
|
import type { SavedTemplateDetails } from '@@/Types/stripo';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
templateId: string;
|
|
@@ -11,6 +11,7 @@ type __VLS_Props = {
|
|
|
11
11
|
css?: string;
|
|
12
12
|
guidoConfig: GuidoConfig;
|
|
13
13
|
templateConfig?: TemplateConfig;
|
|
14
|
+
traceId?: string;
|
|
14
15
|
};
|
|
15
16
|
declare const _default: import("vue").DefineComponent<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
16
17
|
dynamicContent: {
|
|
@@ -20,14 +21,12 @@ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToOption<__
|
|
|
20
21
|
hasChanges: import("vue").ComputedRef<boolean>;
|
|
21
22
|
saveSilent: () => Promise<SavedTemplateDetails | undefined> | undefined;
|
|
22
23
|
}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {
|
|
23
|
-
"dynamic-content:open": (detail: DynamicContent | null
|
|
24
|
+
"dynamic-content:open": (detail: DynamicContent | null) => void;
|
|
24
25
|
back: () => void;
|
|
25
26
|
"save:start": () => void;
|
|
26
27
|
"save:complete": (data: Omit<SavedTemplateDetails, "forceRecreate">) => void;
|
|
27
28
|
"on-change": (hasChanges: boolean) => void;
|
|
28
29
|
ready: () => void;
|
|
29
|
-
"onboarding:finished": () => void;
|
|
30
|
-
"test-email:click": () => void;
|
|
31
30
|
}, string, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToOption<__VLS_Props>>>, {}>;
|
|
32
31
|
export default _default;
|
|
33
32
|
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {
|
|
2
|
-
"onboarding-finished": () => void;
|
|
3
|
-
}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
4
2
|
export default _default;
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {
|
|
2
|
-
"onboarding-finished": () => void;
|
|
3
|
-
}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
|
|
4
2
|
export default _default;
|
|
@@ -32,8 +32,8 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<
|
|
|
32
32
|
closeOnOutsideClick: boolean;
|
|
33
33
|
footerStatus: boolean;
|
|
34
34
|
}>>>, {
|
|
35
|
-
size: "small" | "medium" | "large";
|
|
36
35
|
description: string;
|
|
36
|
+
size: "small" | "medium" | "large";
|
|
37
37
|
closeOnOutsideClick: boolean;
|
|
38
38
|
footerButtonOptions: FooterButtonGroup;
|
|
39
39
|
closeButtonStatus: boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HttpError, HttpResponse } from '@@/Composables/useHttp';
|
|
2
|
+
/**
|
|
3
|
+
* API error context with request/response details
|
|
4
|
+
*/
|
|
5
|
+
export interface ApiErrorContext {
|
|
6
|
+
endpoint: string;
|
|
7
|
+
method?: string;
|
|
8
|
+
statusCode?: number;
|
|
9
|
+
statusText?: string;
|
|
10
|
+
errorType?: 'http_error' | 'network_error' | 'parsing_error' | 'timeout';
|
|
11
|
+
attemptNumber?: number;
|
|
12
|
+
retryable?: boolean;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tracks API failures including HTTP errors, network issues, and data parsing failures
|
|
17
|
+
* Integrates with the main error tracking system (Sentry + FullStory)
|
|
18
|
+
*/
|
|
19
|
+
export declare const useApiErrorTracking: () => {
|
|
20
|
+
captureHttpError: (error: HttpError, endpoint: string, options?: Omit<ApiErrorContext, "endpoint">) => ApiErrorContext;
|
|
21
|
+
captureNetworkError: (error: Error, endpoint: string, options?: Omit<ApiErrorContext, "endpoint">) => ApiErrorContext;
|
|
22
|
+
captureParsingError: (error: unknown, endpoint: string, responseData?: unknown, options?: Omit<ApiErrorContext, "endpoint">) => ApiErrorContext;
|
|
23
|
+
captureTimeoutError: (endpoint: string, timeoutMs: number, options?: Omit<ApiErrorContext, "endpoint">) => ApiErrorContext;
|
|
24
|
+
withApiErrorTracking: <T>(apiCall: () => Promise<HttpResponse<T>>, endpoint: string, method?: string, options?: Omit<ApiErrorContext, "endpoint">) => Promise<HttpResponse<T>>;
|
|
25
|
+
withParsingErrorTracking: <T>(parser: () => T, endpoint: string, rawResponse?: unknown, options?: Omit<ApiErrorContext, "endpoint">) => T;
|
|
26
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Error context for error tracking and correlation
|
|
4
|
+
*/
|
|
5
|
+
export interface ErrorContext {
|
|
6
|
+
component?: string;
|
|
7
|
+
operation?: string;
|
|
8
|
+
templateId?: string;
|
|
9
|
+
userId?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Error tracking service for capturing and reporting errors
|
|
14
|
+
* Integrates with Sentry and FullStory for comprehensive error tracking
|
|
15
|
+
*/
|
|
16
|
+
export declare const useErrorTracking: () => {
|
|
17
|
+
traceId: string;
|
|
18
|
+
errorCount: Readonly<Ref<number>>;
|
|
19
|
+
lastError: Readonly<Ref<Error | null>>;
|
|
20
|
+
captureError: (error: Error, context?: ErrorContext) => ErrorContext;
|
|
21
|
+
captureStripoError: (error: unknown, operation: string, additionalContext?: Record<string, unknown>, shouldLogToSentry?: boolean) => ErrorContext;
|
|
22
|
+
captureTimeoutError: (operation: string, timeoutMs: number, additionalContext?: Record<string, unknown>) => ErrorContext;
|
|
23
|
+
createTimeoutPromise: <T>(ms: number, operation: string, additionalContext?: Record<string, unknown>) => Promise<T>;
|
|
24
|
+
withTimeout: <T>(promise: Promise<T>, ms: number, operation: string, additionalContext?: Record<string, unknown>) => Promise<T>;
|
|
25
|
+
getErrorSummary: () => {
|
|
26
|
+
errorCount: number;
|
|
27
|
+
lastError: Error | null;
|
|
28
|
+
};
|
|
29
|
+
resetErrorTracking: () => void;
|
|
30
|
+
};
|
|
@@ -3,11 +3,9 @@ import type { InjectionKey } from 'vue';
|
|
|
3
3
|
export type BackHandler = () => void;
|
|
4
4
|
export type SaveStartHandler = () => void;
|
|
5
5
|
export type SaveCompleteHandler = (template: Omit<SavedTemplateDetails, 'forceRecreate'>) => void;
|
|
6
|
-
export type TestEmailClickHandler = () => void;
|
|
7
6
|
export declare const BACK_KEY: InjectionKey<BackHandler>;
|
|
8
7
|
export declare const SAVE_START_KEY: InjectionKey<SaveStartHandler>;
|
|
9
8
|
export declare const SAVE_COMPLETE_KEY: InjectionKey<SaveCompleteHandler>;
|
|
10
|
-
export declare const TEST_EMAIL_CLICK_KEY: InjectionKey<TestEmailClickHandler>;
|
|
11
9
|
/**
|
|
12
10
|
* Provides Guido action handlers to child components
|
|
13
11
|
*/
|
|
@@ -15,7 +13,6 @@ export declare const provideGuidoActions: (actions: {
|
|
|
15
13
|
onBack: BackHandler;
|
|
16
14
|
onSaveStart: SaveStartHandler;
|
|
17
15
|
onSaveComplete: SaveCompleteHandler;
|
|
18
|
-
onTestEmailClick: TestEmailClickHandler;
|
|
19
16
|
}) => void;
|
|
20
17
|
/**
|
|
21
18
|
* Provides individual Guido action handlers
|
|
@@ -38,11 +35,6 @@ export declare const useSaveStart: () => SaveStartHandler;
|
|
|
38
35
|
* @returns Save complete function
|
|
39
36
|
*/
|
|
40
37
|
export declare const useSaveComplete: () => SaveCompleteHandler;
|
|
41
|
-
/**
|
|
42
|
-
* Hook to use the test email click handler
|
|
43
|
-
* @returns Test email click function
|
|
44
|
-
*/
|
|
45
|
-
export declare const useTestEmailClick: () => TestEmailClickHandler;
|
|
46
38
|
/**
|
|
47
39
|
* Convenience hook to get all Guido actions
|
|
48
40
|
* @returns Object containing all action handlers
|
|
@@ -51,5 +43,4 @@ export declare const useGuidoActions: () => {
|
|
|
51
43
|
back: BackHandler;
|
|
52
44
|
saveStart: SaveStartHandler;
|
|
53
45
|
saveComplete: SaveCompleteHandler;
|
|
54
|
-
testEmailClick: TestEmailClickHandler;
|
|
55
46
|
};
|
|
@@ -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,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
|
+
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Block, BlockCompositionType } from '@stripoinc/ui-editor-extensions';
|
|
2
2
|
export declare const BLOCK_ID = "recommendation-block";
|
|
3
3
|
export declare class RecommendationBlock extends Block {
|
|
4
|
-
constructor();
|
|
5
4
|
getId(): string;
|
|
6
5
|
getIcon(): string;
|
|
7
6
|
getBlockCompositionType(): BlockCompositionType;
|
|
@@ -17,19 +17,10 @@ export declare class RecommendationBlockControl extends CommonControl {
|
|
|
17
17
|
_getProductLayout(): string;
|
|
18
18
|
_getFilterStatus(): string;
|
|
19
19
|
_getShuffleProducts(): string;
|
|
20
|
+
_getResponsive(): string;
|
|
21
|
+
_onFilterChange(value: boolean): void;
|
|
20
22
|
_onFilterSelectClick(): void;
|
|
21
23
|
_onDataChange(item: string, value: string | number | string[]): void;
|
|
22
|
-
/**
|
|
23
|
-
* Get the current card composition from block data attribute or use default
|
|
24
|
-
*/
|
|
25
|
-
_getCardComposition(): string[];
|
|
26
|
-
_regenerateProductRows(): void;
|
|
27
|
-
/**
|
|
28
|
-
* Reapply spacing values after product regeneration
|
|
29
|
-
* This ensures spacing persists when products are regenerated
|
|
30
|
-
*/
|
|
31
|
-
_reapplySpacing(): void;
|
|
32
|
-
_debouncedRegenerateProductRows: import("@vueuse/shared").PromisifyFn<() => void>;
|
|
33
24
|
_onCurrencyConfigChange(item: string, value: string | number): void;
|
|
34
25
|
_onCurrencyChange(value: string): void;
|
|
35
26
|
_setProductIdsVisibility(): void;
|