@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.
Files changed (115) hide show
  1. package/dist/@types/generic.d.ts +13 -0
  2. package/dist/components/Guido.vue.d.ts +3 -2
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +99 -70
  5. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.d.ts +19 -0
  6. package/dist/components/organisms/extensions/recommendation/FilterItem.vue.js +28 -0
  7. package/dist/components/organisms/extensions/recommendation/FilterItem.vue2.js +38 -0
  8. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.d.ts +2 -0
  9. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue.js +17 -0
  10. package/dist/components/organisms/extensions/recommendation/FilterSelectionDrawer.vue2.js +37 -0
  11. package/dist/components/organisms/extensions/recommendation/Filters.vue.d.ts +2 -0
  12. package/dist/components/organisms/extensions/recommendation/Filters.vue.js +20 -0
  13. package/dist/components/organisms/extensions/recommendation/Filters.vue2.js +44 -0
  14. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue.d.ts +16 -0
  15. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue.js +17 -0
  16. package/dist/components/organisms/extensions/recommendation/LogicAdapter.vue2.js +27 -0
  17. package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue.d.ts +2 -0
  18. package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue.js +18 -0
  19. package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue2.js +16 -0
  20. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.d.ts +2 -0
  21. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +24 -0
  22. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +64 -0
  23. package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.d.ts +2 -0
  24. package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +18 -0
  25. package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +107 -0
  26. package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue.d.ts +2 -0
  27. package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue.js +18 -0
  28. package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue2.js +12 -0
  29. package/dist/components/wrappers/WpDrawer.vue.d.ts +6 -4
  30. package/dist/components/wrappers/WpDrawer.vue.js +6 -4
  31. package/dist/composables/useApiErrorTracking.d.ts +26 -0
  32. package/dist/composables/useApiErrorTracking.js +120 -0
  33. package/dist/composables/useErrorTracking.d.ts +30 -0
  34. package/dist/composables/useErrorTracking.js +98 -0
  35. package/dist/composables/useHttp.js +89 -52
  36. package/dist/composables/useStripo.js +160 -61
  37. package/dist/composables/useStripoErrorCategory.d.ts +26 -0
  38. package/dist/composables/useStripoErrorCategory.js +86 -0
  39. package/dist/composables/useStripoSlackNotifier.d.ts +8 -0
  40. package/dist/composables/useStripoSlackNotifier.js +47 -0
  41. package/dist/config/compiler/unsubscribeCompilerRules.js +42 -29
  42. package/dist/config/migrator/index.d.ts +1 -1
  43. package/dist/config/migrator/index.js +7 -6
  44. package/dist/config/migrator/unsubscribeMigrator.d.ts +1 -0
  45. package/dist/config/migrator/unsubscribeMigrator.js +124 -0
  46. package/dist/enums/defaults.js +6 -3
  47. package/dist/enums/extensions/recommendationBlock.d.ts +16 -0
  48. package/dist/enums/extensions/recommendationBlock.js +80 -0
  49. package/dist/enums/unsubscribe.d.ts +19 -0
  50. package/dist/enums/unsubscribe.js +39 -6
  51. package/dist/extensions/Blocks/Checkbox/control.js +35 -39
  52. package/dist/extensions/Blocks/RadioButton/control.js +33 -37
  53. package/dist/extensions/Blocks/RadioButton/template.js +6 -6
  54. package/dist/extensions/Blocks/Recommendation/block.d.ts +10 -0
  55. package/dist/extensions/Blocks/Recommendation/block.js +27 -0
  56. package/dist/extensions/Blocks/Recommendation/control.d.ts +29 -0
  57. package/dist/extensions/Blocks/Recommendation/control.js +277 -0
  58. package/dist/extensions/Blocks/Recommendation/extension.d.ts +2 -0
  59. package/dist/extensions/Blocks/Recommendation/extension.js +10 -0
  60. package/dist/extensions/Blocks/Recommendation/iconsRegistry.d.ts +4 -0
  61. package/dist/extensions/Blocks/Recommendation/iconsRegistry.js +51 -0
  62. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +19 -0
  63. package/dist/extensions/Blocks/Recommendation/settingsPanel.d.ts +4 -0
  64. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +32 -0
  65. package/dist/extensions/Blocks/Recommendation/store/recommendation.d.ts +555 -0
  66. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +266 -0
  67. package/dist/extensions/Blocks/Recommendation/template.d.ts +6 -0
  68. package/dist/extensions/Blocks/Recommendation/template.js +200 -0
  69. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.d.ts +7 -0
  70. package/dist/extensions/Blocks/Recommendation/utils/filterUtil.js +28 -0
  71. package/dist/extensions/Blocks/Unsubscribe/block.d.ts +32 -0
  72. package/dist/extensions/Blocks/Unsubscribe/block.js +131 -0
  73. package/dist/extensions/Blocks/Unsubscribe/control.d.ts +29 -0
  74. package/dist/extensions/Blocks/Unsubscribe/control.js +167 -0
  75. package/dist/extensions/Blocks/Unsubscribe/elements/preview.d.ts +11 -0
  76. package/dist/extensions/Blocks/Unsubscribe/elements/preview.js +42 -0
  77. package/dist/extensions/Blocks/Unsubscribe/extension.d.ts +2 -0
  78. package/dist/extensions/Blocks/Unsubscribe/extension.js +21 -0
  79. package/dist/extensions/Blocks/Unsubscribe/iconsRegistry.d.ts +4 -0
  80. package/dist/extensions/Blocks/Unsubscribe/iconsRegistry.js +21 -0
  81. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.d.ts +4 -0
  82. package/dist/extensions/Blocks/Unsubscribe/settingsPanel.js +35 -0
  83. package/dist/extensions/Blocks/Unsubscribe/styles.css.js +42 -0
  84. package/dist/extensions/Blocks/Unsubscribe/tagRegistry.d.ts +4 -0
  85. package/dist/extensions/Blocks/Unsubscribe/tagRegistry.js +10 -0
  86. package/dist/extensions/Blocks/Unsubscribe/template.d.ts +12 -0
  87. package/dist/extensions/Blocks/Unsubscribe/template.js +22 -0
  88. package/dist/extensions/Blocks/Unsubscribe/utils/constants.d.ts +9 -0
  89. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +11 -0
  90. package/dist/extensions/Blocks/Unsubscribe/utils/utils.d.ts +7 -0
  91. package/dist/extensions/Blocks/Unsubscribe/utils/utils.js +6 -0
  92. package/dist/extensions/Blocks/common-control.d.ts +66 -0
  93. package/dist/extensions/Blocks/common-control.js +102 -0
  94. package/dist/guido.css +1 -1
  95. package/dist/mock/api/recommendation.d.ts +2 -0
  96. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +83 -71
  97. package/dist/services/recommendationApi.d.ts +6 -0
  98. package/dist/services/recommendationApi.js +43 -0
  99. package/dist/services/slackNotificationService.d.ts +110 -0
  100. package/dist/services/slackNotificationService.js +167 -0
  101. package/dist/services/stripoApi.js +49 -19
  102. package/dist/services/stripoErrorDeduplicationService.d.ts +75 -0
  103. package/dist/services/stripoErrorDeduplicationService.js +91 -0
  104. package/dist/services/unsubscribeApi.d.ts +4 -0
  105. package/dist/services/unsubscribeApi.js +16 -0
  106. package/dist/stores/config.d.ts +96 -0
  107. package/dist/stores/config.js +17 -0
  108. package/dist/stores/editor.d.ts +21 -0
  109. package/dist/stores/editor.js +2 -1
  110. package/dist/stores/unsubscribe.d.ts +253 -5
  111. package/dist/stores/unsubscribe.js +126 -6
  112. package/dist/utils/genericUtil.d.ts +1 -0
  113. package/dist/utils/genericUtil.js +8 -7
  114. package/dist/utils/templatePreparation.js +17 -16
  115. package/package.json +2 -2
@@ -1,86 +1,123 @@
1
- import { getCsrfToken as H } from "../utils/genericUtil.js";
2
- import { ref as p, computed as T } from "vue";
3
- const k = (b = {}) => {
4
- const h = p(!1), a = p(null), u = p(null), g = T(() => h.value), y = T(() => a.value !== null), v = {
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": H()
20
+ "X-CSRF-TOKEN": S()
12
21
  },
13
- ...b
14
- }, w = (e, s) => {
15
- if (e.startsWith("http://") || e.startsWith("https://"))
16
- return e;
17
- const t = s || v.baseURL || "";
18
- return t.endsWith("/") && e.startsWith("/") ? `${t}${e.slice(1)}` : t.endsWith("/") || e.startsWith("/") ? `${t}${e}` : `${t}/${e}`;
19
- }, P = (e) => new Promise((s, t) => {
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
- t(new Error("Request timeout"));
22
- }, e);
23
- }), x = (e) => new Promise((s) => {
24
- setTimeout(s, e);
25
- }), i = async (e, s, t, D = {}) => {
26
- a.value = null, h.value = !0, u.value = new AbortController();
27
- const n = { ...v, ...D }, L = w(s, n.baseURL), c = {
28
- method: e,
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: u.value.signal,
41
+ signal: l.value.signal,
31
42
  ...n
32
43
  };
33
- t && ["POST", "PUT", "PATCH"].includes(e) && (t instanceof FormData ? (delete c.headers["Content-Type"], c.body = t) : c.body = JSON.stringify(t));
34
- const E = async (m = 0) => {
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(L, c)];
37
- n.timeout && o.push(P(n.timeout));
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}`, d = new Error(O);
41
- throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
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 f;
44
- const l = r.headers.get("content-type");
45
- return l != null && l.includes("application/json") ? f = await r.json() : l != null && l.includes("text/") ? f = await r.text() : f = await r.blob(), {
46
- data: f,
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 (m < (n.retry || 0) && !r)
54
- return await x(n.retryDelay || 1e3), E(m + 1);
55
- throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
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 E();
96
+ return await y();
60
97
  } finally {
61
- h.value = !1, u.value = null;
98
+ d.value = !1, l.value = null;
62
99
  }
63
- }, C = (e, s) => i("GET", e, void 0, s), $ = (e, s, t) => i("POST", e, s, t), R = (e, s, t) => i("PUT", e, s, t), U = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), W = (e) => {
64
- u.value && u.value.abort(e);
65
- }, q = () => {
66
- a.value = null;
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: g,
71
- error: T(() => a.value),
72
- hasError: y,
107
+ loading: P,
108
+ error: w(() => i.value),
109
+ hasError: k,
73
110
  // Methods
74
- request: i,
75
- get: C,
76
- post: $,
77
- put: R,
78
- patch: U,
79
- delete: A,
80
- cancel: W,
81
- clearError: q
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
- k as useHttp
122
+ M as useHttp
86
123
  };
@@ -1,26 +1,41 @@
1
- import { useActionsApi as f } from "./useActionsApi.js";
2
- import { useCustomInterfaceAppearance as S } from "./useCustomInterfaceAppearance.js";
3
- import { useStripoEventHandler as E } from "./useStripoEventHandler.js";
4
- import { useToaster as C } from "./useToaster.js";
5
- import { displayConditions as y } from "../enums/displayConditions.js";
6
- import h from "../extensions/Blocks/Checkbox/extension.js";
7
- import w from "../extensions/Blocks/CouponBlock/extension.js";
8
- import b from "../extensions/Blocks/RadioButton/extension.js";
9
- import k from "../extensions/DynamicContent/extension.js";
10
- import { useStripoApi as B } from "../services/stripoApi.js";
11
- import V from "../static/styles/customEditorStyle.css.js";
12
- import { useEditorStore as _ } from "../stores/editor.js";
13
- import { dynamicContentToMergeTags as F } from "../utils/genericUtil.js";
14
- const j = (s) => {
15
- const { handleError: d } = C(), { getToken: c, getCustomFonts: u } = B(), { handleEvent: l } = E(), m = (r, i = []) => {
16
- const t = _(), { html: e, css: a, forceRecreate: g } = r;
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: s,
21
- html: e,
35
+ metadata: o,
36
+ html: i,
22
37
  css: a,
23
- forceRecreate: g,
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: V,
48
+ customViewStyles: R,
34
49
  conditionsEnabled: !0,
35
50
  customConditionsEnabled: !0,
36
- conditionCategories: y,
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: i
58
+ customFonts: n
44
59
  },
45
60
  mergeTags: [
46
61
  {
47
- entries: F(s.preselectedDynamicContentList)
62
+ entries: H(o.preselectedDynamicContentList)
48
63
  }
49
64
  ],
50
- async onTokenRefreshRequest(o) {
65
+ async onTokenRefreshRequest(e) {
51
66
  try {
52
- const n = await c();
53
- o(n);
54
- } catch (n) {
55
- d(n, "Failed to refresh token");
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: o } = S(), { activateCustomViewStyles: n } = f();
61
- o(), n(), s.onReady(), t.isStripoInitialized = !0, t.loadingStatus = !1, setTimeout(() => {
62
- t.hasChanges = !1;
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 (o) {
65
- d(o, "Failed to load custom interface appearance");
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(o) {
69
- t.isCodeEditorOpen = o;
105
+ onCodeEditorVisibilityChanged(e) {
106
+ r.isCodeEditorOpen = e;
70
107
  },
71
- onEditorVisualModeChanged(o) {
72
- t.editorVisualMode = o.toLowerCase();
108
+ onEditorVisualModeChanged(e) {
109
+ r.editorVisualMode = e.toLowerCase();
73
110
  },
74
- onVersionHistoryVisibilityChanged(o) {
75
- t.isVersionHistoryOpen = o;
111
+ onVersionHistoryVisibilityChanged(e) {
112
+ r.isVersionHistoryOpen = e;
76
113
  },
77
114
  onDataChanged() {
78
- t.hasChanges = !0;
115
+ r.hasChanges = !0;
79
116
  },
80
- onEvent: l,
81
- ignoreClickOutsideSelectors: ["#guido-dynamic-content-modal", ".in-on-board-wrapper"],
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
- k,
84
- h,
85
- b,
86
- w
126
+ D,
127
+ x,
128
+ A,
129
+ M,
130
+ U,
131
+ F
87
132
  ]
88
133
  }
89
134
  );
90
- }, p = (r) => new Promise((i, t) => {
135
+ }, T = (m) => new Promise((n, r) => {
91
136
  if (document.getElementById("UiEditorScript")) {
92
- r(), i();
137
+ m(), n();
93
138
  return;
94
139
  }
95
- const e = document.createElement("script");
96
- e.id = "UiEditorScript", e.type = "module", e.src = "https://plugins.stripo.email/resources/uieditor/latest/UIEditor.js", e.onload = () => {
97
- r(), i();
98
- }, e.onerror = () => {
99
- const a = new Error("Failed to load Stripo UIEditor script");
100
- t(a);
101
- }, document.body.appendChild(e);
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 (r) => {
104
- await p(async () => {
105
- const i = await u();
106
- m(r, i);
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
- j as useStripo
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
+ };