@useinsider/guido 1.0.3-beta.49f18d1 → 1.0.3-beta.4a63a85

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 CHANGED
@@ -600,9 +600,6 @@ Create a `.env` file with the following variables: (You can get env variables fr
600
600
  VITE_STRIPO_PLUGIN_ID=your_plugin_id
601
601
  VITE_STRIPO_SECRET_KEY=your_secret_key
602
602
  VITE_STRIPO_ROLE=your_role
603
-
604
- # Playwright Test Configuration (Optional - for local debugging only)
605
- HEADED=false # Set to 'true' to run tests with visible browser
606
603
  ```
607
604
 
608
605
  ### Project Structure
@@ -1,6 +1,6 @@
1
- import { useToaster as g } from "./useToaster.js";
1
+ import { useToaster as w } from "./useToaster.js";
2
2
  const A = () => {
3
- const { handleError: l } = g(), n = (t = {}) => new Promise((e, a) => {
3
+ const { handleError: l } = w(), s = (e = {}) => new Promise((t, a) => {
4
4
  const i = { ...{
5
5
  minimize: !0,
6
6
  utmEntity: {
@@ -20,13 +20,13 @@ const A = () => {
20
20
  forceAmp: !1,
21
21
  resetDataSavedFlag: !1,
22
22
  disableLineHeightsReplace: !0
23
- }, ...t }, m = {
24
- callback: (s, c, p, u, d) => {
25
- s ? a(s) : e({
26
- html: c,
27
- ampHtml: p,
28
- ampErrors: u,
29
- displayConditions: d
23
+ }, ...e }, m = {
24
+ callback: (n, p, c, d, u) => {
25
+ n ? a(n) : t({
26
+ html: p,
27
+ ampHtml: c,
28
+ ampErrors: d,
29
+ displayConditions: u
30
30
  });
31
31
  },
32
32
  ...i
@@ -34,44 +34,53 @@ const A = () => {
34
34
  window.StripoEditorApi.actionsApi.compileEmail(m);
35
35
  });
36
36
  return {
37
- getCompiledEmail: n,
38
- getTemplateData: () => new Promise((t) => {
39
- const e = ({ html: a, css: o, width: i, height: r, utmParams: m, syncModulesIds: s }) => t({
37
+ getCompiledEmail: s,
38
+ getTemplateData: () => new Promise((e) => {
39
+ const t = ({ html: a, css: o, width: i, height: r, utmParams: m, syncModulesIds: n }) => e({
40
40
  html: a,
41
41
  css: o,
42
42
  width: i,
43
43
  height: r,
44
44
  utmParams: m,
45
- syncModulesIds: s
45
+ syncModulesIds: n
46
46
  });
47
- window.StripoEditorApi.actionsApi.getTemplateData(e);
47
+ window.StripoEditorApi.actionsApi.getTemplateData(t);
48
48
  }),
49
- activateCustomViewStyles: (t = !0) => {
50
- window.StripoEditorApi.actionsApi.activateCustomViewStyles(t);
49
+ activateCustomViewStyles: (e = !0) => {
50
+ window.StripoEditorApi.actionsApi.activateCustomViewStyles(e);
51
51
  },
52
- getPreviewData: async (t) => {
52
+ getPreviewData: async (e) => {
53
53
  try {
54
54
  const {
55
- html: e,
55
+ html: t,
56
56
  displayConditions: a,
57
57
  ampHtml: o = "",
58
58
  ampErrors: i = []
59
- } = await n({ minimize: !1, resetDataSavedFlag: !1, ...t });
59
+ } = await s({ minimize: !1, resetDataSavedFlag: !1, ...e });
60
60
  return {
61
- html: e,
61
+ html: t,
62
62
  ampHtml: o,
63
63
  ampErrors: i,
64
64
  displayConditions: a
65
65
  };
66
- } catch (e) {
67
- return l(e, "Error loading preview"), {
66
+ } catch (t) {
67
+ return l(t, "Error loading preview"), {
68
68
  html: "",
69
69
  ampHtml: "",
70
70
  ampErrors: [],
71
71
  displayConditions: []
72
72
  };
73
73
  }
74
- }
74
+ },
75
+ updateTimerInClonedTemplate: () => new Promise((e) => {
76
+ try {
77
+ window.StripoEditorApi.actionsApi.updateTimerInClonedTemplate((t, a) => {
78
+ t ? (l(t, "Failed to update timer in cloned template"), e(null)) : e(a || null);
79
+ });
80
+ } catch (t) {
81
+ l(t, "Failed to call updateTimerInClonedTemplate"), e(null);
82
+ }
83
+ })
75
84
  };
76
85
  };
77
86
  export {
@@ -1,15 +1,20 @@
1
- import { useSaveStart as i, useSaveComplete as m } from "./useGuidoActions.js";
2
- import { useTemplatePreparation as n } from "../utils/templatePreparation.js";
3
- import { useHtmlValidator as l } from "./useHtmlValidator.js";
4
- const f = () => {
5
- const e = i(), a = m(), { validateHtml: s } = l();
6
- return { save: async (o = !1) => {
7
- e();
8
- const { prepareTemplateDetails: r } = n(), t = await r();
9
- if (await s(t.compiledHtml, t.dynamicContentList, !0))
10
- return o || a(t), t;
1
+ import { useSaveStart as l, useSaveComplete as c } from "./useGuidoActions.js";
2
+ import { useTemplatePreparation as d } from "../utils/templatePreparation.js";
3
+ import { useHtmlValidator as p } from "./useHtmlValidator.js";
4
+ import { useTimerClone as u } from "./useTimerClone.js";
5
+ const g = () => {
6
+ const t = l(), a = c(), { validateHtml: r } = p(), { cloneTimersOnSave: i } = u();
7
+ return { save: async (s = !1) => {
8
+ t();
9
+ const { prepareTemplateDetails: o } = d(), e = await o();
10
+ if (!await r(e.compiledHtml, e.dynamicContentList, !0))
11
+ return;
12
+ const m = e.rawHtml.match(/esd-timer-id="(\d+)"/g);
13
+ e.rawHtml = await i(e.rawHtml);
14
+ const n = e.rawHtml.match(/esd-timer-id="(\d+)"/g);
15
+ return console.debug("[SAVE] Timer IDs - Original:", m, "New:", n), s || a(e), e;
11
16
  } };
12
17
  };
13
18
  export {
14
- f as useSave
19
+ g as useSave
15
20
  };
@@ -1,25 +1,26 @@
1
- import { useActionsApi as w } from "./useActionsApi.js";
2
- import { useBlocksConfig as b } from "./useBlocksConfig.js";
3
- import { useConfig as k } from "./useConfig.js";
4
- import { useCustomInterfaceAppearance as V } from "./useCustomInterfaceAppearance.js";
5
- import { useStripoEventHandler as _ } from "./useStripoEventHandler.js";
6
- import { useToaster as B } from "./useToaster.js";
7
- import { displayConditions as T } from "../enums/displayConditions.js";
8
- import { useStripoApi as A } from "../services/stripoApi.js";
9
- import F from "../static/styles/customEditorStyle.css.js";
10
- import { useEditorStore as M } from "../stores/editor.js";
11
- import { dynamicContentToMergeTags as U } from "../utils/genericUtil.js";
12
- import v from "../package.json.js";
13
- const J = (c) => {
14
- const { config: u } = k(), { handleError: l } = B(), { getToken: f, getCustomFonts: y } = A(), { handleEvent: S } = _(), { getStripoBlocksConfig: C } = b(), E = async (i, r = []) => {
15
- var m, g;
16
- const t = M(), { html: n, css: p, forceRecreate: a } = i, { baseBlocks: e, extensions: d } = await C();
1
+ import { useActionsApi as V } from "./useActionsApi.js";
2
+ import { useBlocksConfig as _ } from "./useBlocksConfig.js";
3
+ import { useConfig as A } from "./useConfig.js";
4
+ import { useCustomInterfaceAppearance as B } from "./useCustomInterfaceAppearance.js";
5
+ import { useStripoEventHandler as v } from "./useStripoEventHandler.js";
6
+ import { useTimerClone as F } from "./useTimerClone.js";
7
+ import { useToaster as I } from "./useToaster.js";
8
+ import { displayConditions as M } from "../enums/displayConditions.js";
9
+ import { useStripoApi as U } from "../services/stripoApi.js";
10
+ import D from "../static/styles/customEditorStyle.css.js";
11
+ import { useEditorStore as P } from "../stores/editor.js";
12
+ import { dynamicContentToMergeTags as H } from "../utils/genericUtil.js";
13
+ import O from "../package.json.js";
14
+ const Y = (c) => {
15
+ const { config: u } = A(), { handleError: p } = I(), { getToken: m, getCustomFonts: C } = U(), { handleEvent: S } = v(), { getStripoBlocksConfig: E } = _(), w = async (i, r = []) => {
16
+ var g, y;
17
+ const e = P(), { html: s, css: f, forceRecreate: a } = i, { baseBlocks: t, extensions: d } = await E();
17
18
  window.UIEditor.initEditor(
18
19
  document.querySelector("#guido-editor"),
19
20
  {
20
21
  metadata: c,
21
- html: n,
22
- css: p,
22
+ html: s,
23
+ css: f,
23
24
  forceRecreate: a,
24
25
  locale: "en",
25
26
  undoButtonSelector: "#guido__undo-button",
@@ -30,10 +31,10 @@ const J = (c) => {
30
31
  customAppearanceMergetags: !0,
31
32
  customAppearanceMergetagsBorderColor: "#f1f3fe",
32
33
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
33
- customViewStyles: F,
34
- conditionsEnabled: ((m = u.features) == null ? void 0 : m.displayConditions) ?? !0,
35
- customConditionsEnabled: ((g = u.features) == null ? void 0 : g.displayConditions) ?? !0,
36
- conditionCategories: T,
34
+ customViewStyles: D,
35
+ conditionsEnabled: ((g = u.features) == null ? void 0 : g.displayConditions) ?? !0,
36
+ customConditionsEnabled: ((y = u.features) == null ? void 0 : y.displayConditions) ?? !0,
37
+ conditionCategories: M,
37
38
  enableXSSSecurity: !0,
38
39
  messageSettingsEnabled: !0,
39
40
  displayGmailAnnotations: !0,
@@ -41,7 +42,7 @@ const J = (c) => {
41
42
  displayTitle: !1,
42
43
  displayUTM: !1,
43
44
  selectElementAfterDrop: !0,
44
- ...e ? { baseBlocks: e } : {},
45
+ ...t ? { baseBlocks: t } : {},
45
46
  editorFonts: {
46
47
  showDefaultStandardFonts: !0,
47
48
  showDefaultNotStandardFonts: !0,
@@ -49,38 +50,39 @@ const J = (c) => {
49
50
  },
50
51
  mergeTags: [
51
52
  {
52
- entries: U(c.preselectedDynamicContentList)
53
+ entries: H(c.preselectedDynamicContentList)
53
54
  }
54
55
  ],
55
56
  async onTokenRefreshRequest(o) {
56
57
  try {
57
- const s = await f();
58
- o(s);
59
- } catch (s) {
60
- l(s, "Failed to refresh token");
58
+ const n = await m();
59
+ o(n);
60
+ } catch (n) {
61
+ p(n, "Failed to refresh token");
61
62
  }
62
63
  },
63
64
  onTemplateLoaded() {
65
+ var o, n;
64
66
  try {
65
- const { importCss: o } = V(), { activateCustomViewStyles: s } = w();
66
- o(), s(), c.onReady(), t.isStripoInitialized = !0, t.loadingStatus = !1, setTimeout(() => {
67
- t.hasChanges = !1;
67
+ const { importCss: l } = B(), { activateCustomViewStyles: T, updateTimerInClonedTemplate: b } = V(), { updateTimersOnLoad: k } = F();
68
+ l(), T(), typeof ((n = (o = window.StripoEditorApi) == null ? void 0 : o.actionsApi) == null ? void 0 : n.updateTimerInClonedTemplate) == "function" ? b() : k(m), c.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
69
+ e.hasChanges = !1;
68
70
  }, 1e3);
69
- } catch (o) {
70
- l(o, "Failed to load custom interface appearance");
71
+ } catch (l) {
72
+ p(l, "Failed to load custom interface appearance");
71
73
  }
72
74
  },
73
75
  onCodeEditorVisibilityChanged(o) {
74
- t.isCodeEditorOpen = o;
76
+ e.isCodeEditorOpen = o;
75
77
  },
76
78
  onEditorVisualModeChanged(o) {
77
- t.editorVisualMode = o.toLowerCase();
79
+ e.editorVisualMode = o.toLowerCase();
78
80
  },
79
81
  onVersionHistoryVisibilityChanged(o) {
80
- t.isVersionHistoryOpen = o;
82
+ e.isVersionHistoryOpen = o;
81
83
  },
82
84
  onDataChanged() {
83
- t.hasChanges = !0;
85
+ e.hasChanges = !0;
84
86
  },
85
87
  onEvent: S,
86
88
  ignoreClickOutsideSelectors: [
@@ -91,26 +93,26 @@ const J = (c) => {
91
93
  extensions: d
92
94
  }
93
95
  );
94
- }, h = (i) => new Promise((r, t) => {
96
+ }, h = (i) => new Promise((r, e) => {
95
97
  var d;
96
98
  if (document.getElementById("UiEditorScript")) {
97
99
  i(), r();
98
100
  return;
99
101
  }
100
- const n = v.guido, a = `https://email-static.useinsider.com/guido/${(d = n == null ? void 0 : n.stripo) == null ? void 0 : d.version}/UIEditor.js`, e = document.createElement("script");
101
- e.id = "UiEditorScript", e.type = "module", e.src = a, e.onload = () => {
102
+ const s = O.guido, a = `https://email-static.useinsider.com/guido/${(d = s == null ? void 0 : s.stripo) == null ? void 0 : d.version}/UIEditor.js`, t = document.createElement("script");
103
+ t.id = "UiEditorScript", t.type = "module", t.src = a, t.onload = () => {
102
104
  i(), r();
103
- }, e.onerror = () => {
104
- t(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
105
- }, document.body.appendChild(e);
105
+ }, t.onerror = () => {
106
+ e(new Error(`Failed to load Stripo UIEditor script from S3: ${a}`));
107
+ }, document.body.appendChild(t);
106
108
  });
107
109
  return { initPlugin: async (i) => {
108
110
  await h(async () => {
109
- const r = await y();
110
- await E(i, r);
111
+ const r = await C();
112
+ await w(i, r);
111
113
  });
112
114
  } };
113
115
  };
114
116
  export {
115
- J as useStripo
117
+ Y as useStripo
116
118
  };
@@ -0,0 +1,75 @@
1
+ import { useToaster as C } from "./useToaster.js";
2
+ import { useStripoApi as L } from "../services/stripoApi.js";
3
+ const w = () => {
4
+ const { handleError: c } = C(), { getToken: T } = L(), d = (t) => /esd-timer-id="(\d+)"/.test(t), a = async (t, o) => {
5
+ try {
6
+ console.debug("[TIMER CLONE] Calling Stripo API to clone timers...");
7
+ const e = await fetch("https://plugins.stripo.email/api/v1/timers/clone", {
8
+ method: "POST",
9
+ headers: {
10
+ "ES-PLUGIN-AUTH": `Bearer ${o}`,
11
+ "Content-Type": "application/json"
12
+ },
13
+ body: JSON.stringify({ html: t })
14
+ });
15
+ if (console.debug("[TIMER CLONE] API response status:", e.status), !e.ok) {
16
+ const r = await e.text();
17
+ throw console.debug("[TIMER CLONE] API error:", r), new Error(`Stripo API error: ${e.status} ${e.statusText}`);
18
+ }
19
+ const n = await e.json();
20
+ return console.debug("[TIMER CLONE] Timers cloned successfully. Map:", n.timersMap), console.debug("[TIMER CLONE] Old HTML length:", t.length), console.debug("[TIMER CLONE] New HTML length:", n.html.length), n.html;
21
+ } catch (e) {
22
+ return console.debug("[TIMER CLONE] Error:", e), c(e, "Failed to clone timer IDs"), null;
23
+ }
24
+ };
25
+ return {
26
+ hasTimerBlocks: d,
27
+ cloneTimersInHtml: a,
28
+ cloneTimersOnSave: async (t) => {
29
+ if (!d(t))
30
+ return t;
31
+ console.debug("[TIMER CLONE] Cloning timers on save...");
32
+ const o = await T();
33
+ return o ? await a(t, o) || t : (console.debug("[TIMER CLONE] No auth token available, skipping"), t);
34
+ },
35
+ updateTimersOnLoad: async (t) => {
36
+ var o, e, n, r, l, u;
37
+ try {
38
+ console.debug("[TIMER CLONE] Starting timer update on template load...");
39
+ const s = (e = (o = window.UIEditor) == null ? void 0 : o.getHtml) == null ? void 0 : e.call(o);
40
+ if (!s) {
41
+ console.debug("[TIMER CLONE] No HTML found, skipping timer update");
42
+ return;
43
+ }
44
+ const E = d(s);
45
+ if (console.debug("[TIMER CLONE] Has timer blocks?", E), !E)
46
+ return;
47
+ const g = s.match(/esd-timer-id="(\d+)"/g);
48
+ console.debug("[TIMER CLONE] Current timer IDs:", g), console.debug("[TIMER CLONE] Getting auth token...");
49
+ const p = await t();
50
+ if (!p) {
51
+ console.debug("[TIMER CLONE] No auth token available, skipping timer update");
52
+ return;
53
+ }
54
+ const i = await a(s, p);
55
+ if (!i) {
56
+ console.debug("[TIMER CLONE] API returned no updated HTML");
57
+ return;
58
+ }
59
+ if (i === s) {
60
+ console.debug("[TIMER CLONE] HTML unchanged, no update needed");
61
+ return;
62
+ }
63
+ const m = i.match(/esd-timer-id="(\d+)"/g);
64
+ console.debug("[TIMER CLONE] New timer IDs:", m);
65
+ const I = ((r = (n = window.UIEditor) == null ? void 0 : n.getCss) == null ? void 0 : r.call(n)) || "";
66
+ console.debug("[TIMER CLONE] Updating editor with new HTML..."), (u = (l = window.StripoEditorApi) == null ? void 0 : l.actionsApi) != null && u.updateHtmlAndCss ? (window.StripoEditorApi.actionsApi.updateHtmlAndCss(i, I), console.debug("[TIMER CLONE] ✅ Editor updated successfully!")) : console.debug("[TIMER CLONE] updateHtmlAndCss method not available");
67
+ } catch (s) {
68
+ console.debug("[TIMER CLONE] Error updating timers:", s), c(s, "Failed to update timer blocks");
69
+ }
70
+ }
71
+ };
72
+ };
73
+ export {
74
+ w as useTimerClone
75
+ };
@@ -23,11 +23,11 @@ const e = {
23
23
  }, t = {
24
24
  promotional: 1,
25
25
  transactional: 2
26
- }, a = "email", o = "Guido User", s = t.promotional, n = 2, i = 13, u = {
26
+ }, a = "email", o = "Guido User", s = t.promotional, n = 2, i = {
27
27
  email: 60,
28
28
  architect: 49,
29
29
  unsubscribePages: 97
30
- }, r = [
30
+ }, u = [
31
31
  "alfredtesting",
32
32
  "electio",
33
33
  "eurekatest",
@@ -65,8 +65,7 @@ export {
65
65
  a as DefaultProductType,
66
66
  o as DefaultUsername,
67
67
  n as EditorType,
68
- i as MAX_DEFAULT_TEMPLATE_ID,
69
- u as ProductIds,
70
- r as TEST_PARTNER_LIST,
68
+ i as ProductIds,
69
+ u as TEST_PARTNER_LIST,
71
70
  t as TemplateTypes
72
71
  };
@@ -1,22 +1,21 @@
1
- import { useHttp as m } from "../composables/useHttp.js";
2
- import { useToaster as u } from "../composables/useToaster.js";
3
- import { MAX_DEFAULT_TEMPLATE_ID as i } from "../enums/defaults.js";
4
- const y = () => {
5
- const { get: a } = m(), { handleError: o } = u();
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();
6
5
  return {
7
6
  getToken: async () => {
8
7
  try {
9
- const t = Number(localStorage.getItem("ins-guido-test-instance")), { data: r } = await a(`/stripo/get-user-token?test=${t}`);
10
- return r.body.token;
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;
11
10
  } catch (t) {
12
11
  return o(t, "Failed to fetch token"), "";
13
12
  }
14
13
  },
15
14
  getCustomFonts: async () => {
16
15
  try {
17
- const { data: t = [] } = await a("/stripo/get-partner-custom-fonts");
18
- return t.map((r) => ({
19
- ...r,
16
+ const { data: t = [] } = await r("/stripo/get-partner-custom-fonts");
17
+ return t.map((e) => ({
18
+ ...e,
20
19
  active: !0
21
20
  }));
22
21
  } catch (t) {
@@ -30,26 +29,21 @@ const y = () => {
30
29
  forceRecreate: !0
31
30
  };
32
31
  try {
33
- const c = new URLSearchParams(window.location.search).get("default-template"), s = c ? parseInt(c) : 0, l = s >= 1 && s <= i ? s : 0, { data: e } = await a(
34
- `/stripo/default-template/${l}`
35
- );
36
- let n;
37
- if (typeof e == "string")
38
- n = JSON.parse(e);
39
- else if (e && typeof e == "object" && "html" in e && "css" in e)
40
- n = e;
41
- else
32
+ const { data: e } = await r("/stripo/default-template/0");
33
+ try {
34
+ return {
35
+ ...JSON.parse(e),
36
+ forceRecreate: !0
37
+ };
38
+ } catch {
42
39
  return t;
43
- return {
44
- ...n,
45
- forceRecreate: !0
46
- };
47
- } catch (r) {
48
- return o(r, "Failed to fetch default template"), t;
40
+ }
41
+ } catch (e) {
42
+ return o(e, "Failed to fetch default template"), t;
49
43
  }
50
44
  }
51
45
  };
52
46
  };
53
47
  export {
54
- y as useStripoApi
48
+ m as useStripoApi
55
49
  };
@@ -5,4 +5,5 @@ export declare const useActionsApi: () => {
5
5
  getTemplateData: () => Promise<TemplateData>;
6
6
  activateCustomViewStyles: (isActive?: boolean) => void;
7
7
  getPreviewData: (options?: CompileEmailOptions) => Promise<CompiledEmailResult>;
8
+ updateTimerInClonedTemplate: () => Promise<string | null>;
8
9
  };
@@ -0,0 +1,6 @@
1
+ export declare const useTimerClone: () => {
2
+ hasTimerBlocks: (html: string) => boolean;
3
+ cloneTimersInHtml: (html: string, authToken: string) => Promise<string | null>;
4
+ cloneTimersOnSave: (html: string) => Promise<string>;
5
+ updateTimersOnLoad: (getTokenFn: () => Promise<string>) => Promise<void>;
6
+ };
@@ -8,6 +8,5 @@ export declare const DefaultProductType = "email";
8
8
  export declare const DefaultUsername = "Guido User";
9
9
  export declare const DefaultMessageType: number;
10
10
  export declare const EditorType: number;
11
- export declare const MAX_DEFAULT_TEMPLATE_ID = 13;
12
11
  export declare const ProductIds: Record<string, number>;
13
12
  export declare const TEST_PARTNER_LIST: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "1.0.3-beta.49f18d1",
3
+ "version": "1.0.3-beta.4a63a85",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",