@useinsider/guido 3.18.2-beta.83b62a8 → 3.18.2-beta.8ef3138
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 +0 -20
- package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +34 -34
- package/dist/composables/useGuidoStateBridge.js +24 -29
- package/dist/composables/useHttp.js +24 -22
- package/dist/composables/useStripo.js +7 -7
- package/dist/library.js +13 -15
- package/dist/services/templateLibraryApi.js +17 -14
- package/dist/src/composables/useGuidoStateBridge.d.ts +7 -11
- package/dist/src/library.d.ts +0 -2
- package/dist/src/public/trackingIds.d.ts +2 -6
- package/dist/src/stores/editor.d.ts +0 -25
- package/dist/src/stores/guido-email-editor.d.ts +27 -27
- package/dist/src/utils/genericUtil.d.ts +6 -0
- package/dist/stores/editor.js +0 -4
- package/dist/stores/guido-email-editor.js +4 -0
- package/dist/utils/genericUtil.js +45 -39
- package/dist/utils/templatePreparation.js +37 -36
- package/package.json +1 -5
- package/dist/public/editorState.js +0 -4
- package/dist/src/public/editorState.d.ts +0 -14
package/README.md
CHANGED
|
@@ -561,26 +561,6 @@ import {
|
|
|
561
561
|
import '@useinsider/guido/style';
|
|
562
562
|
```
|
|
563
563
|
|
|
564
|
-
### Subpath entries
|
|
565
|
-
|
|
566
|
-
Two surfaces also ship as their own entry points. Importing one pulls in only its
|
|
567
|
-
own dependencies, so a consumer that needs the store or the tracking-id helpers
|
|
568
|
-
never loads the editor:
|
|
569
|
-
|
|
570
|
-
```typescript
|
|
571
|
-
// Live editor state, published by the editor into the host's shared Pinia instance.
|
|
572
|
-
// Store id `guidoEmailEditor` is the cross-app contract — read it, do not redeclare it.
|
|
573
|
-
import { useGuidoEmailEditorStore } from '@useinsider/guido/editor-state';
|
|
574
|
-
import type { GuidoEmailEditorState } from '@useinsider/guido/editor-state';
|
|
575
|
-
|
|
576
|
-
// Persistent link ids for the click heatmap.
|
|
577
|
-
import { assignTrackingIds, TRACK_ID_ATTRIBUTE } from '@useinsider/guido/tracking-ids';
|
|
578
|
-
import type { TrackingIdResult } from '@useinsider/guido/tracking-ids';
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
Both are re-exported from the root barrel as well; the subpath is what keeps the
|
|
582
|
-
editor out of the consumer's module graph.
|
|
583
|
-
|
|
584
564
|
---
|
|
585
565
|
|
|
586
566
|
## Constants
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import
|
|
3
|
-
import { useTranslations as
|
|
1
|
+
import { defineComponent as _, ref as c, computed as h, watch as C, toRef as N, nextTick as O } from "vue";
|
|
2
|
+
import b from "../../wrappers/WpDrawer.vue.js";
|
|
3
|
+
import { useTranslations as D } from "../../../composables/useTranslations.js";
|
|
4
4
|
import { useTemplateNameValidator as x } from "../../../composables/validators/saveAsTemplate.js";
|
|
5
5
|
import { useTemplateLibraryApi as B } from "../../../services/templateLibraryApi.js";
|
|
6
|
-
import { useEditorStore as
|
|
7
|
-
import { useSaveAsTemplateStore as
|
|
8
|
-
import { InMultiSelect as
|
|
9
|
-
import { useDebounceFn as
|
|
10
|
-
const
|
|
6
|
+
import { useEditorStore as k } from "../../../stores/editor.js";
|
|
7
|
+
import { useSaveAsTemplateStore as I } from "../../../stores/save-as-template.js";
|
|
8
|
+
import { InMultiSelect as M, InBasicTextInput as V } from "@useinsider/design-system-vue";
|
|
9
|
+
import { useDebounceFn as E } from "../../../node_modules/@vueuse/shared/index.js";
|
|
10
|
+
const J = /* @__PURE__ */ _({
|
|
11
11
|
__name: "SaveAsTemplateDrawer",
|
|
12
|
-
setup(
|
|
13
|
-
const
|
|
12
|
+
setup(R) {
|
|
13
|
+
const s = D(), o = k(), t = I(), { createTemplate: m } = B(), a = c(!1), n = c(!1), r = c(""), f = h(() => ({
|
|
14
14
|
primaryButton: {
|
|
15
15
|
styling: "solid",
|
|
16
16
|
type: "primary",
|
|
17
|
-
labelText:
|
|
17
|
+
labelText: s(a.value ? "newsletter.saving" : "products.save"),
|
|
18
18
|
loadingStatus: a.value,
|
|
19
19
|
disabledStatus: t.skeletonStatus
|
|
20
20
|
},
|
|
21
21
|
cancelOrBackButton: {
|
|
22
22
|
styling: "ghost",
|
|
23
23
|
type: "secondary",
|
|
24
|
-
labelText:
|
|
24
|
+
labelText: s("products.cancel"),
|
|
25
25
|
disabledStatus: a.value
|
|
26
26
|
}
|
|
27
|
-
})),
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
const e =
|
|
31
|
-
return
|
|
32
|
-
}, v =
|
|
33
|
-
t.templateName = e, await
|
|
34
|
-
}, 500),
|
|
35
|
-
|
|
36
|
-
},
|
|
27
|
+
})), p = () => {
|
|
28
|
+
r.value = "", o.isSaveAsTemplateDrawerOpen = !1;
|
|
29
|
+
}, l = async () => {
|
|
30
|
+
const e = N(t, "templateName"), { success: i, errorMessage: A } = await x(e).validate();
|
|
31
|
+
return r.value = A, i;
|
|
32
|
+
}, v = E(async (e) => {
|
|
33
|
+
t.templateName = e, await l();
|
|
34
|
+
}, 500), S = async (e) => {
|
|
35
|
+
n.value = !0, await t.addCategory(e), n.value = !1;
|
|
36
|
+
}, T = (e) => {
|
|
37
37
|
t.selectedCategories = e;
|
|
38
|
-
},
|
|
38
|
+
}, g = (e) => {
|
|
39
39
|
e && (t.selectedCategories = e);
|
|
40
|
-
},
|
|
40
|
+
}, y = () => {
|
|
41
41
|
t.selectedCategories = [];
|
|
42
42
|
}, w = async () => {
|
|
43
|
-
if (a.value = !0, !await
|
|
43
|
+
if (a.value = !0, !await l()) {
|
|
44
44
|
a.value = !1;
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
a.value = !1,
|
|
49
|
-
},
|
|
50
|
-
|
|
47
|
+
const i = await m();
|
|
48
|
+
a.value = !1, i && p();
|
|
49
|
+
}, u = () => {
|
|
50
|
+
O(() => {
|
|
51
51
|
const e = document.querySelector("input#guido__template-name-input");
|
|
52
52
|
e == null || e.focus();
|
|
53
53
|
});
|
|
54
54
|
}, d = async () => {
|
|
55
|
-
t.$reset(), await t.fetchCategories(), t.skeletonStatus = !1,
|
|
55
|
+
t.$reset(), await t.fetchCategories(), t.skeletonStatus = !1, u();
|
|
56
56
|
};
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
}), { __sfc: !0, trans:
|
|
57
|
+
return C(() => o.isSaveAsTemplateDrawerOpen, (e) => {
|
|
58
|
+
e && d();
|
|
59
|
+
}), { __sfc: !0, trans: s, editorStore: o, saveAsTemplateStore: t, createTemplate: m, isSaving: a, isAddingOption: n, templateNameError: r, footerButtonGroupOptions: f, closeModal: p, validateTemplateName: l, handleTemplateName: v, handleAddOption: S, handleCategoryChange: T, handleSelectAllOptions: g, handleResetAllOptions: y, saveTemplate: w, focusToInput: u, initializeDrawer: d, WpDrawer: b, InBasicTextInput: V, InMultiSelect: M };
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
export {
|
|
63
|
-
|
|
63
|
+
J as default
|
|
64
64
|
};
|
|
@@ -1,59 +1,54 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useEditorLock as
|
|
1
|
+
import { useActionsApi as b } from "./useActionsApi.js";
|
|
2
|
+
import { useEditorLock as v } from "./useEditorLock.js";
|
|
3
3
|
import { useConfigStore as T } from "../stores/config.js";
|
|
4
4
|
import { useEditorStore as w } from "../stores/editor.js";
|
|
5
5
|
import { useGuidoEmailEditorStore as y } from "../stores/guido-email-editor.js";
|
|
6
|
-
import { watch as
|
|
7
|
-
const
|
|
8
|
-
const i = w(), u = y(),
|
|
9
|
-
let o = null,
|
|
10
|
-
const
|
|
6
|
+
import { watch as a, onUnmounted as B } from "vue";
|
|
7
|
+
const C = 500, L = () => {
|
|
8
|
+
const i = w(), u = y(), l = T(), { getTemplateData: d } = b(), { runExclusive: m, isEditorBusy: p } = v();
|
|
9
|
+
let o = null, s = !1;
|
|
10
|
+
const n = () => {
|
|
11
11
|
o && (clearTimeout(o), o = null);
|
|
12
|
-
},
|
|
13
|
-
|
|
12
|
+
}, c = (t) => {
|
|
13
|
+
n(), o = setTimeout(() => {
|
|
14
14
|
o = null, t();
|
|
15
|
-
},
|
|
15
|
+
}, C);
|
|
16
16
|
}, e = async () => {
|
|
17
|
-
var t,
|
|
18
|
-
if (!(
|
|
17
|
+
var t, r;
|
|
18
|
+
if (!(s || !i.isStripoInitialized)) {
|
|
19
19
|
if (p()) {
|
|
20
|
-
|
|
20
|
+
c(() => void e());
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
try {
|
|
24
|
-
const { html: E, css:
|
|
25
|
-
if (
|
|
24
|
+
const { html: E, css: g } = await m(d), I = ((r = (t = l.config) == null ? void 0 : t.identity) == null ? void 0 : r.templateId) ?? "";
|
|
25
|
+
if (s)
|
|
26
26
|
return;
|
|
27
27
|
u.$patch({
|
|
28
28
|
html: E ?? "",
|
|
29
|
-
css:
|
|
30
|
-
templateId:
|
|
29
|
+
css: g ?? "",
|
|
30
|
+
templateId: I,
|
|
31
31
|
lastUpdatedAt: Date.now()
|
|
32
32
|
});
|
|
33
33
|
} catch {
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
}, f = () =>
|
|
36
|
+
}, f = () => c(() => void e()), h = a(
|
|
37
37
|
() => i.isStripoInitialized,
|
|
38
38
|
(t) => {
|
|
39
39
|
t && e();
|
|
40
40
|
},
|
|
41
41
|
{ immediate: !0 }
|
|
42
|
-
), S =
|
|
43
|
-
() => i.changeSeq,
|
|
44
|
-
() => {
|
|
45
|
-
i.isStripoInitialized && f();
|
|
46
|
-
}
|
|
47
|
-
), g = c(
|
|
42
|
+
), S = a(
|
|
48
43
|
() => i.hasChanges,
|
|
49
|
-
(t,
|
|
50
|
-
|
|
44
|
+
(t, r) => {
|
|
45
|
+
i.isStripoInitialized && (t ? f() : r && (n(), e()));
|
|
51
46
|
}
|
|
52
47
|
);
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
B(() => {
|
|
49
|
+
s = !0, n(), h(), S();
|
|
55
50
|
});
|
|
56
51
|
};
|
|
57
52
|
export {
|
|
58
|
-
|
|
53
|
+
L as useGuidoStateBridge
|
|
59
54
|
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { getCsrfToken as
|
|
2
|
-
import { ref as
|
|
3
|
-
const
|
|
4
|
-
const
|
|
1
|
+
import { getCsrfToken as O } from "../utils/genericUtil.js";
|
|
2
|
+
import { ref as m, computed as T } from "vue";
|
|
3
|
+
const X = (b = {}) => {
|
|
4
|
+
const p = m(!1), a = m(null), u = m(null), g = T(() => p.value), y = T(() => a.value !== null), v = {
|
|
5
5
|
baseURL: "",
|
|
6
6
|
timeout: 1e4,
|
|
7
7
|
retry: 0,
|
|
8
8
|
retryDelay: 1e3,
|
|
9
9
|
headers: {
|
|
10
10
|
"Content-Type": "application/json",
|
|
11
|
-
"X-CSRF-TOKEN":
|
|
11
|
+
"X-CSRF-TOKEN": O(),
|
|
12
|
+
Accept: "application/json",
|
|
13
|
+
"X-Requested-With": "XMLHttpRequest"
|
|
12
14
|
},
|
|
13
15
|
...b
|
|
14
16
|
}, w = (e, s) => {
|
|
@@ -22,22 +24,22 @@ const k = (b = {}) => {
|
|
|
22
24
|
}, e);
|
|
23
25
|
}), x = (e) => new Promise((s) => {
|
|
24
26
|
setTimeout(s, e);
|
|
25
|
-
}), i = async (e, s, t,
|
|
26
|
-
a.value = null,
|
|
27
|
-
const n = { ...v, ...
|
|
27
|
+
}), i = async (e, s, t, L = {}) => {
|
|
28
|
+
a.value = null, p.value = !0, u.value = new AbortController();
|
|
29
|
+
const n = { ...v, ...L }, D = w(s, n.baseURL), c = {
|
|
28
30
|
method: e,
|
|
29
31
|
headers: { ...n.headers },
|
|
30
32
|
signal: u.value.signal,
|
|
31
33
|
...n
|
|
32
34
|
};
|
|
33
35
|
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 (
|
|
36
|
+
const E = async (h = 0) => {
|
|
35
37
|
try {
|
|
36
|
-
const o = [fetch(
|
|
38
|
+
const o = [fetch(D, c)];
|
|
37
39
|
n.timeout && o.push(P(n.timeout));
|
|
38
40
|
const r = await Promise.race(o);
|
|
39
41
|
if (!r.ok) {
|
|
40
|
-
const
|
|
42
|
+
const H = `HTTP Error: ${r.status} ${r.statusText}`, d = new Error(H);
|
|
41
43
|
throw d.status = r.status, d.statusText = r.statusText, d.response = r, d;
|
|
42
44
|
}
|
|
43
45
|
let f;
|
|
@@ -50,19 +52,19 @@ const k = (b = {}) => {
|
|
|
50
52
|
};
|
|
51
53
|
} catch (o) {
|
|
52
54
|
const r = o instanceof Error && o.name === "AbortError";
|
|
53
|
-
if (
|
|
54
|
-
return await x(n.retryDelay || 1e3), E(
|
|
55
|
+
if (h < (n.retry || 0) && !r)
|
|
56
|
+
return await x(n.retryDelay || 1e3), E(h + 1);
|
|
55
57
|
throw o instanceof Error ? o.name === "AbortError" ? a.value = { message: "Request was cancelled" } : a.value = { message: o.message } : a.value = o, o;
|
|
56
58
|
}
|
|
57
59
|
};
|
|
58
60
|
try {
|
|
59
61
|
return await E();
|
|
60
62
|
} finally {
|
|
61
|
-
|
|
63
|
+
p.value = !1, u.value = null;
|
|
62
64
|
}
|
|
63
|
-
}, C = (e, s) => i("GET", e, void 0, s),
|
|
65
|
+
}, C = (e, s) => i("GET", e, void 0, s), R = (e, s, t) => i("POST", e, s, t), $ = (e, s, t) => i("PUT", e, s, t), q = (e, s, t) => i("PATCH", e, s, t), A = (e, s) => i("DELETE", e, void 0, s), U = (e) => {
|
|
64
66
|
u.value && u.value.abort(e);
|
|
65
|
-
},
|
|
67
|
+
}, W = () => {
|
|
66
68
|
a.value = null;
|
|
67
69
|
};
|
|
68
70
|
return {
|
|
@@ -73,14 +75,14 @@ const k = (b = {}) => {
|
|
|
73
75
|
// Methods
|
|
74
76
|
request: i,
|
|
75
77
|
get: C,
|
|
76
|
-
post:
|
|
77
|
-
put:
|
|
78
|
-
patch:
|
|
78
|
+
post: R,
|
|
79
|
+
put: $,
|
|
80
|
+
patch: q,
|
|
79
81
|
delete: A,
|
|
80
|
-
cancel:
|
|
81
|
-
clearError:
|
|
82
|
+
cancel: U,
|
|
83
|
+
clearError: W
|
|
82
84
|
};
|
|
83
85
|
};
|
|
84
86
|
export {
|
|
85
|
-
|
|
87
|
+
X as useHttp
|
|
86
88
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useBlocksConfig as
|
|
3
|
-
import { useConfig as
|
|
1
|
+
import { useActionsApi as L } from "./useActionsApi.js";
|
|
2
|
+
import { useBlocksConfig as O } from "./useBlocksConfig.js";
|
|
3
|
+
import { useConfig as q } from "./useConfig.js";
|
|
4
4
|
import { useCustomInterfaceAppearance as H } from "./useCustomInterfaceAppearance.js";
|
|
5
5
|
import { useFullStoryBridge as N } from "./useFullStoryBridge.js";
|
|
6
6
|
import { useModuleRepair as j } from "./useModuleRepair.js";
|
|
@@ -17,7 +17,7 @@ import { buildMergeTagEntries as W, flattenDynamicContentList as Y } from "../ut
|
|
|
17
17
|
import Z from "../package.json.js";
|
|
18
18
|
let n = null;
|
|
19
19
|
const Ce = () => {
|
|
20
|
-
const { features: c, template: u, isFeatureEnabled: m } =
|
|
20
|
+
const { features: c, template: u, isFeatureEnabled: m } = q(), { handleError: p, showToaster: k } = G(), { getToken: B, getCustomFonts: M, getSyncModulesStatus: T } = K(), { handleEvent: v } = z(), { handleModuleAdd: F } = j(), { getStripoBlocksConfig: A } = O(), { getStripoNotifications: V } = $(), f = () => n || (n = new Promise((i, s) => {
|
|
21
21
|
var d;
|
|
22
22
|
if (document.getElementById("UiEditorScript")) {
|
|
23
23
|
i();
|
|
@@ -88,8 +88,8 @@ const Ce = () => {
|
|
|
88
88
|
},
|
|
89
89
|
onTemplateLoaded() {
|
|
90
90
|
try {
|
|
91
|
-
const { importCss: t } = H(), { activateCustomViewStyles: l, updateTimerInClonedTemplate: I } =
|
|
92
|
-
t(), l(),
|
|
91
|
+
const { importCss: t } = H(), { activateCustomViewStyles: l, updateTimerInClonedTemplate: I } = L(), { injectFullStory: x } = N();
|
|
92
|
+
t(), l(), x(), I(), o.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
|
|
93
93
|
e.hasChanges = !1;
|
|
94
94
|
}, 1e3);
|
|
95
95
|
} catch (t) {
|
|
@@ -106,7 +106,7 @@ const Ce = () => {
|
|
|
106
106
|
e.isVersionHistoryOpen = t;
|
|
107
107
|
},
|
|
108
108
|
onDataChanged() {
|
|
109
|
-
e.hasChanges = !0
|
|
109
|
+
e.hasChanges = !0;
|
|
110
110
|
},
|
|
111
111
|
onEvent: v,
|
|
112
112
|
onModuleAdd: F,
|
package/dist/library.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { default as
|
|
2
|
-
import { MessageType as
|
|
1
|
+
import { default as e } from "./components/Guido.vue.js";
|
|
2
|
+
import { MessageType as f, ProductType as s } from "./@types/config/schemas.js";
|
|
3
3
|
import "./@types/config/defaults.js";
|
|
4
|
-
import { getValidationErrors as
|
|
5
|
-
import { assignTrackingIds as
|
|
6
|
-
import { useGuidoEmailEditorStore as C } from "./stores/guido-email-editor.js";
|
|
4
|
+
import { getValidationErrors as d, isValidConfig as p, parseConfig as g, parseConfigSafe as n, validateConfig as l } from "./@types/config/validator.js";
|
|
5
|
+
import { assignTrackingIds as T, readTrackFloor as c, readTrackSeq as x } from "./utils/linkTrackingIds.js";
|
|
7
6
|
export {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
e as Guido,
|
|
8
|
+
f as MessageType,
|
|
9
|
+
s as ProductType,
|
|
10
|
+
T as assignTrackingIds,
|
|
11
|
+
d as getValidationErrors,
|
|
13
12
|
p as isValidConfig,
|
|
14
13
|
g as parseConfig,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
n as validateConfig
|
|
14
|
+
n as parseConfigSafe,
|
|
15
|
+
c as readTrackFloor,
|
|
16
|
+
x as readTrackSeq,
|
|
17
|
+
l as validateConfig
|
|
20
18
|
};
|
|
@@ -4,13 +4,14 @@ import { useToaster as C } from "../composables/useToaster.js";
|
|
|
4
4
|
import { useTranslations as h } from "../composables/useTranslations.js";
|
|
5
5
|
import { useLiquidValidator as S } from "../composables/validators/useLiquidValidator.js";
|
|
6
6
|
import { EditorType as v } from "../enums/defaults.js";
|
|
7
|
-
import { ToasterTypeOptions as
|
|
8
|
-
import { useRecommendationExtensionStore as
|
|
9
|
-
import { useSaveAsTemplateStore as
|
|
7
|
+
import { ToasterTypeOptions as x } from "../enums/toaster.js";
|
|
8
|
+
import { useRecommendationExtensionStore as E } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
9
|
+
import { useSaveAsTemplateStore as N } from "../stores/save-as-template.js";
|
|
10
10
|
import { base64EncodeWithSpecialChars as r } from "../utils/base64.js";
|
|
11
|
+
import { isPlainObject as P } from "../utils/genericUtil.js";
|
|
11
12
|
import { useTemplatePreparation as A } from "../utils/templatePreparation.js";
|
|
12
|
-
const
|
|
13
|
-
const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax:
|
|
13
|
+
const B = () => {
|
|
14
|
+
const { get: n, post: m } = b(), { handleError: o, showToaster: l } = C(), { config: c, isFeatureEnabled: p } = w(), { validateLiquidSyntax: f } = S(), u = h();
|
|
14
15
|
return {
|
|
15
16
|
getCategories: async () => {
|
|
16
17
|
try {
|
|
@@ -40,10 +41,10 @@ const j = () => {
|
|
|
40
41
|
createTemplate: async () => {
|
|
41
42
|
var e, t, d, y;
|
|
42
43
|
try {
|
|
43
|
-
const { prepareTemplateDetails: i } = A(), s =
|
|
44
|
-
if (p("liquidSyntax") && !await
|
|
44
|
+
const { prepareTemplateDetails: i } = A(), s = N(), a = await i();
|
|
45
|
+
if (p("liquidSyntax") && !await f(a.compiledHtml))
|
|
45
46
|
return !1;
|
|
46
|
-
const
|
|
47
|
+
const T = {
|
|
47
48
|
name: s.getTemplateName,
|
|
48
49
|
categories: s.getSelectedCategoryIds,
|
|
49
50
|
productId: ((t = (e = c.value) == null ? void 0 : e.partner) == null ? void 0 : t.productType) || 0,
|
|
@@ -54,7 +55,7 @@ const j = () => {
|
|
|
54
55
|
unsubscriptionPreferencePageStatus: !1,
|
|
55
56
|
unsubscriptionPreferencePages: [],
|
|
56
57
|
recommendationCampaignUrls: r(
|
|
57
|
-
|
|
58
|
+
E().recommendationCampaignUrls
|
|
58
59
|
),
|
|
59
60
|
recommendationConfigs: r({}),
|
|
60
61
|
isGuido: !0,
|
|
@@ -66,16 +67,18 @@ const j = () => {
|
|
|
66
67
|
css: a.css,
|
|
67
68
|
dynamicContentList: a.dynamicContentList
|
|
68
69
|
})
|
|
69
|
-
}, { data:
|
|
70
|
+
}, { data: g } = await m(
|
|
70
71
|
"/newsletter/template-library/create-template",
|
|
71
|
-
|
|
72
|
+
T
|
|
72
73
|
);
|
|
73
|
-
|
|
74
|
+
if (!P(g))
|
|
75
|
+
throw new Error("Unexpected create-template response");
|
|
76
|
+
return g.type === "alert" ? (l({
|
|
74
77
|
message: u(
|
|
75
78
|
"newsletter.template-library-save-alert",
|
|
76
79
|
{ templateName: s.getTemplateName }
|
|
77
80
|
),
|
|
78
|
-
type:
|
|
81
|
+
type: x.Error
|
|
79
82
|
}), !1) : (l({
|
|
80
83
|
message: u(
|
|
81
84
|
"newsletter.template-library-save-success",
|
|
@@ -90,5 +93,5 @@ const j = () => {
|
|
|
90
93
|
};
|
|
91
94
|
};
|
|
92
95
|
export {
|
|
93
|
-
|
|
96
|
+
B as useTemplateLibraryApi
|
|
94
97
|
};
|
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Outbound bridge — publishes the current editor's html/css to the shared
|
|
3
|
-
* Pinia store `guidoEmailEditor
|
|
4
|
-
* time and
|
|
3
|
+
* Pinia store `guidoEmailEditor` so cortex-fe can read it at chat-stream
|
|
4
|
+
* submit time and forward it as `clientState.editor`. This is what enables
|
|
5
5
|
* sub-case 1.3 (refine an already-loaded template via the email-agent).
|
|
6
6
|
*
|
|
7
7
|
* The bridge writes on three triggers:
|
|
8
8
|
*
|
|
9
9
|
* 1. Stripo finishes initializing — first snapshot.
|
|
10
|
-
* 2.
|
|
11
|
-
*
|
|
10
|
+
* 2. Editor `hasChanges` flips to true — debounced 500 ms so a streaming
|
|
11
|
+
* Stripo edit doesn't thrash the store.
|
|
12
12
|
* 3. Editor `hasChanges` flips back to false (post-save / autosave) —
|
|
13
13
|
* immediate, since this is the canonical "saved" snapshot.
|
|
14
14
|
*
|
|
15
15
|
* `getTemplateData()` is a Stripo iframe call; it must not run before
|
|
16
16
|
* `isStripoInitialized` is true. The bridge guards against that.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* and
|
|
20
|
-
*
|
|
21
|
-
* Readers are not optional any more, so treat the publish timing as part of
|
|
22
|
-
* the contract: the store ships as `@useinsider/guido/editor-state`, and
|
|
23
|
-
* email-fe imports it to scan the live html for its Array of Objects lock.
|
|
24
|
-
* Weakening a trigger here silently breaks that lock in the consumer.
|
|
18
|
+
* If cortex-fe isn't loaded the store still gets written — that's fine;
|
|
19
|
+
* the store has zero overhead and any future reader will find consistent
|
|
20
|
+
* state. The bridge is a one-way pipe with no consumer dependency.
|
|
25
21
|
*/
|
|
26
22
|
export declare const useGuidoStateBridge: () => void;
|
package/dist/src/library.d.ts
CHANGED
|
@@ -2,7 +2,5 @@ export { default as Guido } from './components/Guido.vue';
|
|
|
2
2
|
export type { GuidoConfig, GuidoConfigInput, IdentityConfig, PartnerConfig, TemplateConfig, TemplateMigrationConfig, LegacyRecommendationConfig, EditorConfig, UIConfig, FeaturesConfig, BlocksConfig, CompilerConfig, DynamicContent, EmailHeader, DefaultBlockType, CustomBlockType, ValidationResult, ValidationError, } from './@types/config';
|
|
3
3
|
export { validateConfig, parseConfig, parseConfigSafe, isValidConfig, getValidationErrors, MessageType, ProductType, } from './@types/config';
|
|
4
4
|
export { assignTrackingIds, readTrackFloor, readTrackSeq } from './public/trackingIds';
|
|
5
|
-
export { useGuidoEmailEditorStore } from './public/editorState';
|
|
6
|
-
export type { GuidoEmailEditorState } from './public/editorState';
|
|
7
5
|
export type { StripoEventType } from './@types/events';
|
|
8
6
|
export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, DynamicContentNode, DynamicContentList, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
|
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
* Importing from here pulls in nothing else, so the editor never enters a
|
|
5
5
|
* consumer's module graph. Re-export surface only: this is the contract,
|
|
6
6
|
* `utils/linkTrackingIds` is the implementation and stays free to move.
|
|
7
|
-
*
|
|
8
|
-
* Relative, not the `@@/Utils/` alias: vue-tsc copies the specifier into the emitted
|
|
9
|
-
* .d.ts verbatim, and a consumer's TypeScript cannot resolve our alias table. A relative
|
|
10
|
-
* path resolves against dist/src/, so the published types actually load.
|
|
11
7
|
*/
|
|
12
|
-
export { assignTrackingIds, readTrackFloor, readTrackSeq, TRACK_ID_ATTRIBUTE, TRACK_SEQ_ATTRIBUTE, } from '
|
|
13
|
-
export type { TrackingIdResult } from '
|
|
8
|
+
export { assignTrackingIds, readTrackFloor, readTrackSeq, TRACK_ID_ATTRIBUTE, TRACK_SEQ_ATTRIBUTE, } from '@@/Utils/linkTrackingIds';
|
|
9
|
+
export type { TrackingIdResult } from '@@/Utils/linkTrackingIds';
|
|
@@ -6,7 +6,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
6
6
|
isPreviewModeOpen: boolean;
|
|
7
7
|
editorVisualMode: string;
|
|
8
8
|
hasChanges: boolean;
|
|
9
|
-
changeSeq: number;
|
|
10
9
|
isStripoInitialized: boolean;
|
|
11
10
|
templateId: string;
|
|
12
11
|
syncModulesEnabled: boolean;
|
|
@@ -20,7 +19,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
20
19
|
isPreviewModeOpen: boolean;
|
|
21
20
|
editorVisualMode: string;
|
|
22
21
|
hasChanges: boolean;
|
|
23
|
-
changeSeq: number;
|
|
24
22
|
isStripoInitialized: boolean;
|
|
25
23
|
templateId: string;
|
|
26
24
|
syncModulesEnabled: boolean;
|
|
@@ -33,7 +31,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
33
31
|
isPreviewModeOpen: boolean;
|
|
34
32
|
editorVisualMode: string;
|
|
35
33
|
hasChanges: boolean;
|
|
36
|
-
changeSeq: number;
|
|
37
34
|
isStripoInitialized: boolean;
|
|
38
35
|
templateId: string;
|
|
39
36
|
syncModulesEnabled: boolean;
|
|
@@ -47,7 +44,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
47
44
|
isPreviewModeOpen: boolean;
|
|
48
45
|
editorVisualMode: string;
|
|
49
46
|
hasChanges: boolean;
|
|
50
|
-
changeSeq: number;
|
|
51
47
|
isStripoInitialized: boolean;
|
|
52
48
|
templateId: string;
|
|
53
49
|
syncModulesEnabled: boolean;
|
|
@@ -60,7 +56,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
60
56
|
isPreviewModeOpen: boolean;
|
|
61
57
|
editorVisualMode: string;
|
|
62
58
|
hasChanges: boolean;
|
|
63
|
-
changeSeq: number;
|
|
64
59
|
isStripoInitialized: boolean;
|
|
65
60
|
templateId: string;
|
|
66
61
|
syncModulesEnabled: boolean;
|
|
@@ -74,7 +69,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
74
69
|
isPreviewModeOpen: boolean;
|
|
75
70
|
editorVisualMode: string;
|
|
76
71
|
hasChanges: boolean;
|
|
77
|
-
changeSeq: number;
|
|
78
72
|
isStripoInitialized: boolean;
|
|
79
73
|
templateId: string;
|
|
80
74
|
syncModulesEnabled: boolean;
|
|
@@ -87,7 +81,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
87
81
|
isPreviewModeOpen: boolean;
|
|
88
82
|
editorVisualMode: string;
|
|
89
83
|
hasChanges: boolean;
|
|
90
|
-
changeSeq: number;
|
|
91
84
|
isStripoInitialized: boolean;
|
|
92
85
|
templateId: string;
|
|
93
86
|
syncModulesEnabled: boolean;
|
|
@@ -101,7 +94,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
101
94
|
isPreviewModeOpen: boolean;
|
|
102
95
|
editorVisualMode: string;
|
|
103
96
|
hasChanges: boolean;
|
|
104
|
-
changeSeq: number;
|
|
105
97
|
isStripoInitialized: boolean;
|
|
106
98
|
templateId: string;
|
|
107
99
|
syncModulesEnabled: boolean;
|
|
@@ -114,7 +106,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
114
106
|
isPreviewModeOpen: boolean;
|
|
115
107
|
editorVisualMode: string;
|
|
116
108
|
hasChanges: boolean;
|
|
117
|
-
changeSeq: number;
|
|
118
109
|
isStripoInitialized: boolean;
|
|
119
110
|
templateId: string;
|
|
120
111
|
syncModulesEnabled: boolean;
|
|
@@ -128,7 +119,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
128
119
|
isPreviewModeOpen: boolean;
|
|
129
120
|
editorVisualMode: string;
|
|
130
121
|
hasChanges: boolean;
|
|
131
|
-
changeSeq: number;
|
|
132
122
|
isStripoInitialized: boolean;
|
|
133
123
|
templateId: string;
|
|
134
124
|
syncModulesEnabled: boolean;
|
|
@@ -141,7 +131,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
141
131
|
isPreviewModeOpen: boolean;
|
|
142
132
|
editorVisualMode: string;
|
|
143
133
|
hasChanges: boolean;
|
|
144
|
-
changeSeq: number;
|
|
145
134
|
isStripoInitialized: boolean;
|
|
146
135
|
templateId: string;
|
|
147
136
|
syncModulesEnabled: boolean;
|
|
@@ -155,7 +144,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
155
144
|
isPreviewModeOpen: boolean;
|
|
156
145
|
editorVisualMode: string;
|
|
157
146
|
hasChanges: boolean;
|
|
158
|
-
changeSeq: number;
|
|
159
147
|
isStripoInitialized: boolean;
|
|
160
148
|
templateId: string;
|
|
161
149
|
syncModulesEnabled: boolean;
|
|
@@ -168,7 +156,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
168
156
|
isPreviewModeOpen: boolean;
|
|
169
157
|
editorVisualMode: string;
|
|
170
158
|
hasChanges: boolean;
|
|
171
|
-
changeSeq: number;
|
|
172
159
|
isStripoInitialized: boolean;
|
|
173
160
|
templateId: string;
|
|
174
161
|
syncModulesEnabled: boolean;
|
|
@@ -182,7 +169,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
182
169
|
isPreviewModeOpen: boolean;
|
|
183
170
|
editorVisualMode: string;
|
|
184
171
|
hasChanges: boolean;
|
|
185
|
-
changeSeq: number;
|
|
186
172
|
isStripoInitialized: boolean;
|
|
187
173
|
templateId: string;
|
|
188
174
|
syncModulesEnabled: boolean;
|
|
@@ -195,7 +181,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
195
181
|
isPreviewModeOpen: boolean;
|
|
196
182
|
editorVisualMode: string;
|
|
197
183
|
hasChanges: boolean;
|
|
198
|
-
changeSeq: number;
|
|
199
184
|
isStripoInitialized: boolean;
|
|
200
185
|
templateId: string;
|
|
201
186
|
syncModulesEnabled: boolean;
|
|
@@ -209,7 +194,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
209
194
|
isPreviewModeOpen: boolean;
|
|
210
195
|
editorVisualMode: string;
|
|
211
196
|
hasChanges: boolean;
|
|
212
|
-
changeSeq: number;
|
|
213
197
|
isStripoInitialized: boolean;
|
|
214
198
|
templateId: string;
|
|
215
199
|
syncModulesEnabled: boolean;
|
|
@@ -222,7 +206,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
222
206
|
isPreviewModeOpen: boolean;
|
|
223
207
|
editorVisualMode: string;
|
|
224
208
|
hasChanges: boolean;
|
|
225
|
-
changeSeq: number;
|
|
226
209
|
isStripoInitialized: boolean;
|
|
227
210
|
templateId: string;
|
|
228
211
|
syncModulesEnabled: boolean;
|
|
@@ -236,7 +219,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
236
219
|
isPreviewModeOpen: boolean;
|
|
237
220
|
editorVisualMode: string;
|
|
238
221
|
hasChanges: boolean;
|
|
239
|
-
changeSeq: number;
|
|
240
222
|
isStripoInitialized: boolean;
|
|
241
223
|
templateId: string;
|
|
242
224
|
syncModulesEnabled: boolean;
|
|
@@ -249,7 +231,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
249
231
|
isPreviewModeOpen: boolean;
|
|
250
232
|
editorVisualMode: string;
|
|
251
233
|
hasChanges: boolean;
|
|
252
|
-
changeSeq: number;
|
|
253
234
|
isStripoInitialized: boolean;
|
|
254
235
|
templateId: string;
|
|
255
236
|
syncModulesEnabled: boolean;
|
|
@@ -263,7 +244,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
263
244
|
isPreviewModeOpen: boolean;
|
|
264
245
|
editorVisualMode: string;
|
|
265
246
|
hasChanges: boolean;
|
|
266
|
-
changeSeq: number;
|
|
267
247
|
isStripoInitialized: boolean;
|
|
268
248
|
templateId: string;
|
|
269
249
|
syncModulesEnabled: boolean;
|
|
@@ -276,7 +256,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
276
256
|
isPreviewModeOpen: boolean;
|
|
277
257
|
editorVisualMode: string;
|
|
278
258
|
hasChanges: boolean;
|
|
279
|
-
changeSeq: number;
|
|
280
259
|
isStripoInitialized: boolean;
|
|
281
260
|
templateId: string;
|
|
282
261
|
syncModulesEnabled: boolean;
|
|
@@ -290,7 +269,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
290
269
|
isPreviewModeOpen: boolean;
|
|
291
270
|
editorVisualMode: string;
|
|
292
271
|
hasChanges: boolean;
|
|
293
|
-
changeSeq: number;
|
|
294
272
|
isStripoInitialized: boolean;
|
|
295
273
|
templateId: string;
|
|
296
274
|
syncModulesEnabled: boolean;
|
|
@@ -303,7 +281,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
303
281
|
isPreviewModeOpen: boolean;
|
|
304
282
|
editorVisualMode: string;
|
|
305
283
|
hasChanges: boolean;
|
|
306
|
-
changeSeq: number;
|
|
307
284
|
isStripoInitialized: boolean;
|
|
308
285
|
templateId: string;
|
|
309
286
|
syncModulesEnabled: boolean;
|
|
@@ -317,7 +294,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
317
294
|
isPreviewModeOpen: boolean;
|
|
318
295
|
editorVisualMode: string;
|
|
319
296
|
hasChanges: boolean;
|
|
320
|
-
changeSeq: number;
|
|
321
297
|
isStripoInitialized: boolean;
|
|
322
298
|
templateId: string;
|
|
323
299
|
syncModulesEnabled: boolean;
|
|
@@ -330,7 +306,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
330
306
|
isPreviewModeOpen: boolean;
|
|
331
307
|
editorVisualMode: string;
|
|
332
308
|
hasChanges: boolean;
|
|
333
|
-
changeSeq: number;
|
|
334
309
|
isStripoInitialized: boolean;
|
|
335
310
|
templateId: string;
|
|
336
311
|
syncModulesEnabled: boolean;
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Outbound contract Guido publishes to the host's shared Pinia singleton so
|
|
3
|
+
* cortex-fe can pick up the current editor state and forward it as
|
|
4
|
+
* `clientState.editor` on the next chat-stream POST.
|
|
5
|
+
*
|
|
6
|
+
* State + getters only — `useGuidoStateBridge` writes via `$patch`, no actions
|
|
7
|
+
* live here (architecture invariant).
|
|
8
|
+
*
|
|
9
|
+
* Store id `guidoEmailEditor` is cross-MFE: cortex-fe reads it via
|
|
10
|
+
* `pinia._s.get('guidoEmailEditor')` at runtime. The internal Guido editor
|
|
11
|
+
* store keeps id `guidoEditor` — these are intentionally separate. The
|
|
12
|
+
* internal store carries UI state that cortex-fe should not see; this public
|
|
13
|
+
* store carries the contract Guido is willing to share.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", {
|
|
3
16
|
/** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
|
|
4
17
|
html: string;
|
|
5
18
|
/** Current Stripo CSS — es-p* utility classes used by the html. */
|
|
6
19
|
css: string;
|
|
7
20
|
/** Wall-clock ms when html/css were last written by the bridge. */
|
|
8
21
|
lastUpdatedAt: number;
|
|
9
|
-
/** Template id from the editor config,
|
|
22
|
+
/** Template id from the editor config, for cortex-fe to scope per-template. */
|
|
10
23
|
templateId: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Outbound contract Guido publishes to the host's shared Pinia singleton so a
|
|
14
|
-
* consumer can read the current editor state: cortex-fe forwards it as
|
|
15
|
-
* `clientState.editor` on the next chat-stream POST, email-fe scans it for the
|
|
16
|
-
* Array of Objects lock.
|
|
17
|
-
*
|
|
18
|
-
* Published as `@useinsider/guido/editor-state` and from the root barrel, so a
|
|
19
|
-
* consumer imports this store instead of re-declaring one under the same id.
|
|
20
|
-
*
|
|
21
|
-
* State + getters only, no actions. `useGuidoStateBridge` is the only intended
|
|
22
|
-
* writer, but that is Guido's own convention rather than something the store
|
|
23
|
-
* enforces: publishing the definition hands a consumer `$patch` as well, exactly
|
|
24
|
-
* as the runtime `pinia._s` probe always did.
|
|
25
|
-
*
|
|
26
|
-
* Store id `guidoEmailEditor` is cross-MFE: cortex-fe reads it via
|
|
27
|
-
* `pinia._s.get('guidoEmailEditor')` at runtime rather than importing it, so the
|
|
28
|
-
* id stays part of the contract. The internal Guido editor store keeps id
|
|
29
|
-
* `guidoEditor` — these are intentionally separate. The internal store carries
|
|
30
|
-
* UI state a consumer should not see; this public store carries the contract
|
|
31
|
-
* Guido is willing to share.
|
|
32
|
-
*/
|
|
33
|
-
export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", GuidoEmailEditorState, {
|
|
24
|
+
}, {
|
|
34
25
|
/** True once the bridge has published at least one snapshot. */
|
|
35
26
|
hasSnapshot: (state: {
|
|
36
27
|
html: string;
|
|
37
28
|
css: string;
|
|
38
29
|
lastUpdatedAt: number;
|
|
39
30
|
templateId: string;
|
|
40
|
-
} & import("pinia").PiniaCustomStateProperties<
|
|
31
|
+
} & import("pinia").PiniaCustomStateProperties<{
|
|
32
|
+
/** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
|
|
33
|
+
html: string;
|
|
34
|
+
/** Current Stripo CSS — es-p* utility classes used by the html. */
|
|
35
|
+
css: string;
|
|
36
|
+
/** Wall-clock ms when html/css were last written by the bridge. */
|
|
37
|
+
lastUpdatedAt: number;
|
|
38
|
+
/** Template id from the editor config, for cortex-fe to scope per-template. */
|
|
39
|
+
templateId: string;
|
|
40
|
+
}>) => boolean;
|
|
41
41
|
}, {}>;
|
|
@@ -30,3 +30,9 @@ export declare const replaceString: (string?: string, values?: Record<string, st
|
|
|
30
30
|
* a string nor a number becomes ''.
|
|
31
31
|
*/
|
|
32
32
|
export declare const asText: (value: unknown) => string;
|
|
33
|
+
/**
|
|
34
|
+
* Narrows an unknown API value to a plain JSON object. Arrays and exotic
|
|
35
|
+
* objects (Blob, Date, FormData) are rejected, so a response body that useHttp
|
|
36
|
+
* parsed as text or blob can never be read as a JSON payload.
|
|
37
|
+
*/
|
|
38
|
+
export declare const isPlainObject: <T>(value: T) => value is T & Record<string, unknown>;
|
package/dist/stores/editor.js
CHANGED
|
@@ -8,10 +8,6 @@ const o = e("guidoEditor", {
|
|
|
8
8
|
isPreviewModeOpen: !1,
|
|
9
9
|
editorVisualMode: "desktop",
|
|
10
10
|
hasChanges: !1,
|
|
11
|
-
// Bumped on every Stripo document change. `hasChanges` is a latch that stays
|
|
12
|
-
// true until a save, so it cannot signal the second edit onwards; watchers
|
|
13
|
-
// that need every change (the outbound state bridge) watch this instead.
|
|
14
|
-
changeSeq: 0,
|
|
15
11
|
isStripoInitialized: !1,
|
|
16
12
|
templateId: "",
|
|
17
13
|
syncModulesEnabled: !1,
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { defineStore as e } from "pinia";
|
|
2
2
|
const d = e("guidoEmailEditor", {
|
|
3
3
|
state: () => ({
|
|
4
|
+
/** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
|
|
4
5
|
html: "",
|
|
6
|
+
/** Current Stripo CSS — es-p* utility classes used by the html. */
|
|
5
7
|
css: "",
|
|
8
|
+
/** Wall-clock ms when html/css were last written by the bridge. */
|
|
6
9
|
lastUpdatedAt: 0,
|
|
10
|
+
/** Template id from the editor config, for cortex-fe to scope per-template. */
|
|
7
11
|
templateId: ""
|
|
8
12
|
}),
|
|
9
13
|
getters: {
|
|
@@ -1,69 +1,75 @@
|
|
|
1
|
-
const o = (
|
|
2
|
-
const
|
|
3
|
-
text:
|
|
1
|
+
const o = (a) => {
|
|
2
|
+
const t = a.value.match(/\{\{([^}]+)\}\}/)[1].split("|").map((e) => e.trim()), [s] = t, r = {
|
|
3
|
+
text: a.label,
|
|
4
4
|
value: s || ""
|
|
5
5
|
};
|
|
6
|
-
if (
|
|
7
|
-
const [,
|
|
8
|
-
if (
|
|
9
|
-
let n =
|
|
6
|
+
if (t.length >= 2) {
|
|
7
|
+
const [, e, l] = t;
|
|
8
|
+
if (e.startsWith("default:")) {
|
|
9
|
+
let n = e.slice(8).trim();
|
|
10
10
|
n.startsWith('"') && n.endsWith('"') && (n = n.slice(1, -1)), r.fallback = n;
|
|
11
11
|
} else {
|
|
12
|
-
const n =
|
|
13
|
-
n ? r.format = n :
|
|
12
|
+
const n = e.includes("=") ? { key: e.split("=")[0].trim(), value: e.split("=")[1].trim() } : null;
|
|
13
|
+
n ? r.format = n : l || (r.fallback = e), l && (r.fallback = l);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
return r;
|
|
17
|
-
},
|
|
18
|
-
if (
|
|
17
|
+
}, u = (a, c = !1) => a.map((t) => {
|
|
18
|
+
if (t.format)
|
|
19
19
|
return {
|
|
20
|
-
label: `${
|
|
21
|
-
value: `{{${
|
|
20
|
+
label: `${t.text} | ${t.format.key}=${t.format.value}`,
|
|
21
|
+
value: `{{${t.value}|${t.format.key}=${t.format.value}}}`
|
|
22
22
|
};
|
|
23
23
|
if (c) {
|
|
24
|
-
if (!
|
|
24
|
+
if (!t.fallback)
|
|
25
25
|
return {
|
|
26
|
-
label:
|
|
27
|
-
value: `{{ ${
|
|
26
|
+
label: t.text,
|
|
27
|
+
value: `{{ ${t.value} }}`
|
|
28
28
|
};
|
|
29
|
-
const r = !Number.isNaN(Number(
|
|
29
|
+
const r = !Number.isNaN(Number(t.fallback)) && t.fallback.trim() !== "" ? t.fallback : `"${t.fallback}"`;
|
|
30
30
|
return {
|
|
31
|
-
label: `${
|
|
32
|
-
value: `{{ ${
|
|
31
|
+
label: `${t.text} | ${t.fallback}`,
|
|
32
|
+
value: `{{ ${t.value} | default: ${r} }}`
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
return {
|
|
36
|
-
label:
|
|
37
|
-
value:
|
|
36
|
+
label: t.fallback ? `${t.text} | ${t.fallback}` : t.text,
|
|
37
|
+
value: t.fallback ? `{{${t.value}|${t.fallback}}}` : `{{${t.value}}}`
|
|
38
38
|
};
|
|
39
|
-
}), b = (
|
|
40
|
-
const c = [],
|
|
41
|
-
Array.isArray(
|
|
42
|
-
const n = [...
|
|
39
|
+
}), b = (a) => {
|
|
40
|
+
const c = [], t = /* @__PURE__ */ new Set(), s = (e) => {
|
|
41
|
+
Array.isArray(e) && e.forEach((l) => {
|
|
42
|
+
const n = [...l.children ?? [], ...l.select_items ?? []];
|
|
43
43
|
if (n.length > 0) {
|
|
44
44
|
s(n);
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
|
|
47
|
+
const f = l.text || l.tag_text;
|
|
48
|
+
f && l.value && !t.has(l.value) && (t.add(l.value), c.push({ text: f, value: l.value }));
|
|
49
49
|
});
|
|
50
|
-
}, [r] = Object.values(
|
|
50
|
+
}, [r] = Object.values(a ?? {});
|
|
51
51
|
return s(r), c;
|
|
52
|
-
}, i = (
|
|
53
|
-
const s = new Set(
|
|
52
|
+
}, i = (a, c, t = !1) => {
|
|
53
|
+
const s = new Set(a.map((e) => e.value)), r = c.filter((e) => s.has(e.value) ? !1 : (s.add(e.value), !0));
|
|
54
54
|
return [
|
|
55
|
-
...
|
|
56
|
-
...
|
|
55
|
+
...u(a, t),
|
|
56
|
+
...u(r, t)
|
|
57
57
|
];
|
|
58
|
-
},
|
|
59
|
-
var
|
|
60
|
-
return ((
|
|
61
|
-
},
|
|
58
|
+
}, k = () => {
|
|
59
|
+
var a;
|
|
60
|
+
return ((a = document.head.querySelector('meta[name="csrf-token"]')) == null ? void 0 : a.getAttribute("content")) ?? "";
|
|
61
|
+
}, v = (a) => typeof a == "string" ? a : typeof a == "number" ? String(a) : "", y = (a) => {
|
|
62
|
+
if (a === null || typeof a != "object" || Array.isArray(a))
|
|
63
|
+
return !1;
|
|
64
|
+
const c = Object.getPrototypeOf(a);
|
|
65
|
+
return c === Object.prototype || c === null;
|
|
66
|
+
};
|
|
62
67
|
export {
|
|
63
|
-
|
|
68
|
+
v as asText,
|
|
64
69
|
i as buildMergeTagEntries,
|
|
65
|
-
|
|
70
|
+
u as dynamicContentToMergeTags,
|
|
66
71
|
b as flattenDynamicContentList,
|
|
67
|
-
|
|
72
|
+
k as getCsrfToken,
|
|
73
|
+
y as isPlainObject,
|
|
68
74
|
o as mergeTagToDynamicContent
|
|
69
75
|
};
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
import { useActionsApi as k } from "../composables/useActionsApi.js";
|
|
2
2
|
import { useConfig as U } from "../composables/useConfig.js";
|
|
3
3
|
import { useHtmlCompiler as x } from "../composables/useHtmlCompiler.js";
|
|
4
|
-
import { DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as
|
|
5
|
-
import { useRecommendationExtensionStore as
|
|
4
|
+
import { DEFAULT_CURRENCY as m, DEFAULT_NODE_CONFIG as n } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
|
|
5
|
+
import { useRecommendationExtensionStore as A } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
6
6
|
import { mapLegacyStrategy as L } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
|
|
7
|
-
import { DATA_ATTRIBUTES as
|
|
7
|
+
import { DATA_ATTRIBUTES as T } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
8
8
|
import { parsePageList as R } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
|
|
9
9
|
import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
|
|
10
10
|
import { useEditorStore as z } from "../stores/editor.js";
|
|
11
|
-
import { useUnsubscribeStore as
|
|
11
|
+
import { useUnsubscribeStore as O } from "../stores/unsubscribe.js";
|
|
12
|
+
import { isPlainObject as _ } from "./genericUtil.js";
|
|
12
13
|
import { assignTrackingIds as v } from "./linkTrackingIds.js";
|
|
13
|
-
function
|
|
14
|
-
const
|
|
15
|
-
return
|
|
16
|
-
const o =
|
|
14
|
+
function M(l) {
|
|
15
|
+
const i = new DOMParser().parseFromString(l, "text/html").querySelectorAll(`[${T.PAGE_LIST}]`), t = [];
|
|
16
|
+
return i.forEach((c) => {
|
|
17
|
+
const o = c.getAttribute(T.PAGE_LIST);
|
|
17
18
|
o && t.push(...R(o));
|
|
18
19
|
}), [...new Set(t)];
|
|
19
20
|
}
|
|
20
|
-
async function
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
21
|
+
async function q(l) {
|
|
22
|
+
const a = new DOMParser().parseFromString(l, "text/html").querySelectorAll(".recommendation-block-v2");
|
|
23
|
+
if (a.length === 0)
|
|
23
24
|
return;
|
|
24
|
-
const
|
|
25
|
-
|
|
25
|
+
const i = A();
|
|
26
|
+
a.forEach((t) => {
|
|
26
27
|
var r, d, g, f, s, y;
|
|
27
|
-
const
|
|
28
|
+
const c = t.getAttribute("recommendation-id"), o = c ? Number(c) : NaN;
|
|
28
29
|
if (!Number.isFinite(o))
|
|
29
30
|
return;
|
|
30
31
|
const p = t.getAttribute("esd-ext-config");
|
|
@@ -36,21 +37,21 @@ async function M(l) {
|
|
|
36
37
|
} catch {
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
39
|
-
if (!
|
|
40
|
+
if (!_(e))
|
|
40
41
|
return;
|
|
41
42
|
const b = {
|
|
42
43
|
// Normalize legacy strategy keys (e.g. `mostViewed` → `mostPopular`) so
|
|
43
44
|
// already-saved blocks that never re-run the migrator don't emit a
|
|
44
45
|
// strategy-less campaign URL. `||` also catches '' / undefined (SD-144882).
|
|
45
|
-
strategy: L(e.strategy) ||
|
|
46
|
-
strategyId: e.strategyId ??
|
|
47
|
-
language: e.language ??
|
|
48
|
-
size: e.size ??
|
|
46
|
+
strategy: L(e.strategy) || n.strategy,
|
|
47
|
+
strategyId: e.strategyId ?? n.strategyId,
|
|
48
|
+
language: e.language ?? n.language,
|
|
49
|
+
size: e.size ?? n.size,
|
|
49
50
|
// Spread the default arrays so each block gets a fresh reference
|
|
50
51
|
// instead of sharing the singleton in DEFAULT_NODE_CONFIG.
|
|
51
|
-
productIds: e.productIds ?? [...
|
|
52
|
-
filters: e.filters ?? [...
|
|
53
|
-
shuffleProducts: e.shuffleProducts ??
|
|
52
|
+
productIds: e.productIds ?? [...n.productIds],
|
|
53
|
+
filters: e.filters ?? [...n.filters],
|
|
54
|
+
shuffleProducts: e.shuffleProducts ?? n.shuffleProducts,
|
|
54
55
|
currencyCode: ((r = e.currency) == null ? void 0 : r.code) ?? m.code,
|
|
55
56
|
currencySymbol: ((d = e.currency) == null ? void 0 : d.symbol) ?? m.symbol,
|
|
56
57
|
currencyAlignment: ((g = e.currency) == null ? void 0 : g.alignment) ?? m.alignment,
|
|
@@ -58,10 +59,10 @@ async function M(l) {
|
|
|
58
59
|
currencyDecimalSeparator: ((s = e.currency) == null ? void 0 : s.decimalSeparator) ?? m.decimalSeparator,
|
|
59
60
|
currencyThousandSeparator: ((y = e.currency) == null ? void 0 : y.thousandSeparator) ?? m.thousandSeparator
|
|
60
61
|
};
|
|
61
|
-
|
|
62
|
+
i.seedBlockUrlConfig(o, b);
|
|
62
63
|
});
|
|
63
64
|
try {
|
|
64
|
-
await
|
|
65
|
+
await i.fetchRecommendationCreateData();
|
|
65
66
|
} catch (t) {
|
|
66
67
|
console.warn(
|
|
67
68
|
"Recommendation reference data pre-load failed; validator will skip the availability check.",
|
|
@@ -69,24 +70,24 @@ async function M(l) {
|
|
|
69
70
|
);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
const
|
|
73
|
-
const l = N(), u = z(),
|
|
73
|
+
const te = () => {
|
|
74
|
+
const l = N(), u = z(), a = O(), { getCompiledEmail: i, getTemplateData: t, updateHtmlAndCss: c } = k(), { compileHtml: o, compileAmpHtml: p } = x(), { isFeatureEnabled: e } = U();
|
|
74
75
|
return {
|
|
75
76
|
prepareTemplateDetails: async () => {
|
|
76
77
|
let { html: r, css: d, syncModulesIds: g = [] } = await t();
|
|
77
78
|
if (e("linkTrackingIds"))
|
|
78
79
|
try {
|
|
79
80
|
const { html: h, changed: F, nextSeq: H } = v(r, u.trackIdSessionFloor);
|
|
80
|
-
u.trackIdSessionFloor = H, F && (r = h, await
|
|
81
|
+
u.trackIdSessionFloor = H, F && (r = h, await c(h, d));
|
|
81
82
|
} catch (h) {
|
|
82
83
|
console.error("Tracking-id step failed, saving anyway:", h);
|
|
83
84
|
}
|
|
84
|
-
const { html: f, ampHtml: s = "", ampErrors: y = [] } = await
|
|
85
|
+
const { html: f, ampHtml: s = "", ampErrors: y = [] } = await i({
|
|
85
86
|
minimize: !0,
|
|
86
87
|
resetDataSavedFlag: !1
|
|
87
88
|
});
|
|
88
|
-
|
|
89
|
-
const { compiledHtml: I, stats: S, appliedRules: w } = o(f), D = s && p(s).compiledHtml,
|
|
89
|
+
a.selectedUnsubscribePages.length && await a.fetchTemplates(), await q(r);
|
|
90
|
+
const { compiledHtml: I, stats: S, appliedRules: w } = o(f), D = s && p(s).compiledHtml, P = l.getSelectedDynamicContentList, E = A(), C = M(r);
|
|
90
91
|
return console.debug("HTML Compilation Stats:", {
|
|
91
92
|
originalSize: S.originalSize,
|
|
92
93
|
compiledSize: S.compiledSize,
|
|
@@ -94,7 +95,7 @@ const Z = () => {
|
|
|
94
95
|
appliedRules: w,
|
|
95
96
|
executionTime: `${S.executionTime.toFixed(2)}ms`
|
|
96
97
|
}), {
|
|
97
|
-
dynamicContentList:
|
|
98
|
+
dynamicContentList: P,
|
|
98
99
|
compiledHtml: I,
|
|
99
100
|
rawHtml: r,
|
|
100
101
|
css: d,
|
|
@@ -102,18 +103,18 @@ const Z = () => {
|
|
|
102
103
|
ampErrors: y,
|
|
103
104
|
modules: g.map(Number),
|
|
104
105
|
recommendation: {
|
|
105
|
-
campaignUrls:
|
|
106
|
+
campaignUrls: E.recommendationCampaignUrls,
|
|
106
107
|
configs: {}
|
|
107
108
|
},
|
|
108
109
|
unsubscribe: {
|
|
109
|
-
status:
|
|
110
|
-
config:
|
|
110
|
+
status: C.length > 0,
|
|
111
|
+
config: C
|
|
111
112
|
}
|
|
112
113
|
};
|
|
113
114
|
}
|
|
114
115
|
};
|
|
115
116
|
};
|
|
116
117
|
export {
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
M as getHtmlReferencedUnsubscribePages,
|
|
119
|
+
te as useTemplatePreparation
|
|
119
120
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.18.2-beta.
|
|
3
|
+
"version": "3.18.2-beta.8ef3138",
|
|
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",
|
|
@@ -18,10 +18,6 @@
|
|
|
18
18
|
"types": "./dist/src/public/trackingIds.d.ts",
|
|
19
19
|
"import": "./dist/public/trackingIds.js"
|
|
20
20
|
},
|
|
21
|
-
"./editor-state": {
|
|
22
|
-
"types": "./dist/src/public/editorState.d.ts",
|
|
23
|
-
"import": "./dist/public/editorState.js"
|
|
24
|
-
},
|
|
25
21
|
"./style": "./dist/guido.css"
|
|
26
22
|
},
|
|
27
23
|
"scripts": {
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Published as `@useinsider/guido/editor-state` — the live editor snapshot Guido
|
|
3
|
-
* writes into the host's shared Pinia singleton.
|
|
4
|
-
*
|
|
5
|
-
* Importing from here pulls in nothing but pinia, so the editor never enters a
|
|
6
|
-
* consumer's module graph. Re-export surface only: this is the contract,
|
|
7
|
-
* `stores/guido-email-editor` is the implementation and stays free to move.
|
|
8
|
-
*
|
|
9
|
-
* Consumers read the store by importing it; the id `guidoEmailEditor` remains
|
|
10
|
-
* part of the contract for cortex-fe, which probes `pinia._s` at runtime instead
|
|
11
|
-
* of taking a build-time dependency on this package.
|
|
12
|
-
*/
|
|
13
|
-
export { useGuidoEmailEditorStore } from '../stores/guido-email-editor';
|
|
14
|
-
export type { GuidoEmailEditorState } from '../stores/guido-email-editor';
|