@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.
Files changed (130) hide show
  1. package/README.md +3 -144
  2. package/dist/components/Guido.vue.js +10 -12
  3. package/dist/components/Guido.vue2.js +101 -84
  4. package/dist/components/organisms/header/LeftSlot.vue.js +1 -1
  5. package/dist/components/organisms/header/LeftSlot.vue2.js +15 -16
  6. package/dist/components/organisms/header/RightSlot.vue.js +11 -11
  7. package/dist/components/organisms/header/RightSlot.vue2.js +22 -23
  8. package/dist/components/organisms/onboarding/NewVersionPopup.vue.js +9 -9
  9. package/dist/components/organisms/onboarding/NewVersionPopup.vue2.js +17 -30
  10. package/dist/components/organisms/onboarding/OnboardingWrapper.vue.js +10 -12
  11. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -19
  12. package/dist/composables/useApiErrorTracking.js +120 -0
  13. package/dist/composables/useErrorTracking.js +98 -0
  14. package/dist/composables/useGuidoActions.js +9 -19
  15. package/dist/composables/useHttp.js +89 -52
  16. package/dist/composables/useStripo.js +163 -66
  17. package/dist/composables/useStripoErrorCategory.js +86 -0
  18. package/dist/composables/useStripoSlackNotifier.js +47 -0
  19. package/dist/config/compiler/unsubscribeCompilerRules.js +28 -33
  20. package/dist/config/migrator/index.js +6 -7
  21. package/dist/enums/defaults.js +8 -16
  22. package/dist/enums/onboarding.js +1 -2
  23. package/dist/enums/unsubscribe.js +25 -27
  24. package/dist/extensions/Blocks/Checkbox/extension.js +2 -2
  25. package/dist/extensions/Blocks/CouponBlock/extension.js +2 -2
  26. package/dist/extensions/Blocks/Recommendation/block.js +3 -6
  27. package/dist/extensions/Blocks/Recommendation/control.js +65 -109
  28. package/dist/extensions/Blocks/Recommendation/extension.js +7 -18
  29. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +21 -159
  30. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +1 -1
  31. package/dist/extensions/Blocks/Recommendation/template.js +200 -0
  32. package/dist/extensions/Blocks/common-control.js +43 -125
  33. package/dist/extensions/DynamicContent/dynamic-content-modal.js +19 -25
  34. package/dist/extensions/DynamicContent/dynamic-content.js +33 -128
  35. package/dist/guido.css +1 -1
  36. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +100 -312
  37. package/dist/package.json.js +1 -1
  38. package/dist/services/slackNotificationService.js +167 -0
  39. package/dist/services/stripoApi.js +49 -19
  40. package/dist/services/stripoErrorDeduplicationService.js +91 -0
  41. package/dist/src/@types/generic.d.ts +6 -42
  42. package/dist/src/components/Guido.vue.d.ts +3 -4
  43. package/dist/src/components/organisms/onboarding/NewVersionPopup.vue.d.ts +1 -3
  44. package/dist/src/components/organisms/onboarding/OnboardingWrapper.vue.d.ts +1 -3
  45. package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
  46. package/dist/src/composables/useApiErrorTracking.d.ts +26 -0
  47. package/dist/src/composables/useErrorTracking.d.ts +30 -0
  48. package/dist/src/composables/useGuidoActions.d.ts +0 -9
  49. package/dist/src/composables/useStripoErrorCategory.d.ts +26 -0
  50. package/dist/src/composables/useStripoSlackNotifier.d.ts +8 -0
  51. package/dist/src/enums/onboarding.d.ts +0 -1
  52. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -1
  53. package/dist/src/extensions/Blocks/Recommendation/control.d.ts +2 -11
  54. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -1
  55. package/dist/src/extensions/Blocks/Recommendation/template.d.ts +6 -0
  56. package/dist/src/extensions/Blocks/common-control.d.ts +0 -21
  57. package/dist/src/extensions/DynamicContent/dynamic-content-modal.d.ts +2 -9
  58. package/dist/src/extensions/DynamicContent/dynamic-content.d.ts +2 -52
  59. package/dist/src/services/slackNotificationService.d.ts +110 -0
  60. package/dist/src/services/stripoErrorDeduplicationService.d.ts +75 -0
  61. package/dist/src/stores/config.d.ts +2 -10
  62. package/dist/src/stores/dynamic-content.d.ts +3 -3
  63. package/dist/src/stores/editor.d.ts +1 -1
  64. package/dist/src/stores/onboarding.d.ts +1 -1
  65. package/dist/src/stores/preview.d.ts +1 -1
  66. package/dist/src/stores/recommendation.d.ts +1 -1
  67. package/dist/src/stores/save-as-template.d.ts +1 -1
  68. package/dist/src/stores/toaster.d.ts +1 -1
  69. package/dist/src/stores/unsubscribe.d.ts +1 -1
  70. package/dist/src/stores/version-history.d.ts +1 -1
  71. package/dist/src/utils/dateUtil.d.ts +0 -21
  72. package/dist/src/utils/genericUtil.d.ts +0 -1
  73. package/dist/static/styles/components/narrow-panel.css.js +0 -10
  74. package/dist/static/styles/components/wide-panel.css.js +4 -0
  75. package/dist/static/styles/customEditorStyle.css.js +0 -19
  76. package/dist/stores/config.js +5 -5
  77. package/dist/stores/dynamic-content.js +2 -2
  78. package/dist/stores/editor.js +1 -1
  79. package/dist/stores/onboarding.js +27 -27
  80. package/dist/stores/preview.js +1 -1
  81. package/dist/stores/recommendation.js +3 -3
  82. package/dist/stores/save-as-template.js +2 -2
  83. package/dist/stores/toaster.js +1 -1
  84. package/dist/stores/unsubscribe.js +1 -1
  85. package/dist/stores/version-history.js +4 -4
  86. package/dist/utils/dateUtil.js +3 -24
  87. package/dist/utils/genericUtil.js +9 -20
  88. package/package.json +3 -3
  89. package/dist/composables/useBlocksConfig.js +0 -49
  90. package/dist/config/migrator/recommendationMigrator.js +0 -293
  91. package/dist/enums/date.js +0 -6
  92. package/dist/extensions/Blocks/Recommendation/cardCompositionControl.js +0 -193
  93. package/dist/extensions/Blocks/Recommendation/constants.js +0 -14
  94. package/dist/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.js +0 -68
  95. package/dist/extensions/Blocks/Recommendation/controls/index.js +0 -272
  96. package/dist/extensions/Blocks/Recommendation/controls/nameTextTrimControl.js +0 -74
  97. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscountTextAfterControl.js +0 -71
  98. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscountTextBeforeControl.js +0 -71
  99. package/dist/extensions/Blocks/Recommendation/controls/omnibusPriceTextAfterControl.js +0 -71
  100. package/dist/extensions/Blocks/Recommendation/controls/omnibusPriceTextBeforeControl.js +0 -71
  101. package/dist/extensions/Blocks/Recommendation/controls/priceHideControl.js +0 -60
  102. package/dist/extensions/Blocks/Recommendation/controls/priceInlineLayoutControl.js +0 -160
  103. package/dist/extensions/Blocks/Recommendation/controls/spacingControl.js +0 -188
  104. package/dist/extensions/Blocks/Recommendation/templates/blockTemplate.js +0 -184
  105. package/dist/extensions/Blocks/Recommendation/templates/migrationTemplate.js +0 -189
  106. package/dist/extensions/Blocks/Recommendation/templates/templateUtils.js +0 -209
  107. package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +0 -25
  108. package/dist/extensions/Blocks/controlFactories.js +0 -234
  109. package/dist/src/composables/useBlocksConfig.d.ts +0 -11
  110. package/dist/src/config/migrator/recommendationMigrator.d.ts +0 -1
  111. package/dist/src/enums/date.d.ts +0 -4
  112. package/dist/src/extensions/Blocks/Recommendation/cardCompositionControl.d.ts +0 -79
  113. package/dist/src/extensions/Blocks/Recommendation/constants.d.ts +0 -91
  114. package/dist/src/extensions/Blocks/Recommendation/controls/cardBackgroundColorControl.d.ts +0 -25
  115. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +0 -71
  116. package/dist/src/extensions/Blocks/Recommendation/controls/nameTextTrimControl.d.ts +0 -16
  117. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscountTextAfterControl.d.ts +0 -15
  118. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscountTextBeforeControl.d.ts +0 -15
  119. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPriceTextAfterControl.d.ts +0 -15
  120. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPriceTextBeforeControl.d.ts +0 -15
  121. package/dist/src/extensions/Blocks/Recommendation/controls/priceHideControl.d.ts +0 -16
  122. package/dist/src/extensions/Blocks/Recommendation/controls/priceInlineLayoutControl.d.ts +0 -50
  123. package/dist/src/extensions/Blocks/Recommendation/controls/spacingControl.d.ts +0 -60
  124. package/dist/src/extensions/Blocks/Recommendation/templates/blockTemplate.d.ts +0 -16
  125. package/dist/src/extensions/Blocks/Recommendation/templates/migrationTemplate.d.ts +0 -16
  126. package/dist/src/extensions/Blocks/Recommendation/templates/templateUtils.d.ts +0 -52
  127. package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +0 -19
  128. package/dist/src/extensions/Blocks/controlFactories.d.ts +0 -95
  129. package/dist/src/utils/environmentUtil.d.ts +0 -5
  130. 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 { useHttp as a } from "../composables/useHttp.js";
2
- import { useToaster as s } from "../composables/useToaster.js";
3
- const m = () => {
4
- const { get: r } = a(), { handleError: o } = s();
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 r(`/stripo/get-user-token?test=${t}`);
9
- return e.body.token;
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 o(t, "Failed to fetch token"), "";
22
+ return n(t, "Failed to fetch token"), "";
12
23
  }
13
24
  },
14
25
  getCustomFonts: async () => {
15
26
  try {
16
- const { data: t = [] } = await r("/stripo/get-partner-custom-fonts");
17
- return t.map((e) => ({
18
- ...e,
19
- active: !0
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 o(t, "Failed to fetch custom fonts"), [];
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 r("/stripo/default-template/0");
52
+ const { data: e } = await s("/stripo/default-template");
33
53
  try {
34
54
  return {
35
- ...JSON.parse(e),
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 o(e, "Failed to fetch default template"), t;
72
+ return n(e, "Failed to fetch default template"), t;
43
73
  }
44
74
  }
45
75
  };
46
76
  };
47
77
  export {
48
- m as useStripoApi
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 BaseDynamicContent = {
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, PositionData, TemplateConfig } from '@@/Types/generic';
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, position?: PositionData | undefined) => void;
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,2 +1 @@
1
1
  export declare const SERVICE_HOVER_SELECTORS: string[];
2
- export declare const ACADEMY_LINK = "https://academy.useinsider.com/docs/email-drag-drop-editor";
@@ -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;