@useinsider/guido 3.20.1-beta.5e7765e → 3.20.1-beta.7282c91
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/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +9 -9
- package/dist/extensions/Blocks/Recommendation/utils/productIds.js +5 -3
- package/dist/extensions/Blocks/Unsubscribe/block.js +83 -82
- package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +2 -0
- package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import "../constants/selectors.js";
|
|
2
2
|
import { RRS_CONFIG_VERSION as m } from "../constants/defaultConfig.js";
|
|
3
|
-
import { sanitizeProductIds as p } from "./productIds.js";
|
|
4
|
-
const
|
|
5
|
-
function
|
|
3
|
+
import { sanitizeProductIds as p, PRODUCT_ID_SEPARATOR as d } from "./productIds.js";
|
|
4
|
+
const u = "manualMerchandising";
|
|
5
|
+
function f({ strategyId: e, nodeConfigVersion: t }) {
|
|
6
6
|
return !e && t < m;
|
|
7
7
|
}
|
|
8
8
|
const o = (e) => {
|
|
9
9
|
const t = String(e ?? "").trim();
|
|
10
10
|
return /^[1-9]\d*$/.test(t) ? t : null;
|
|
11
11
|
};
|
|
12
|
-
function
|
|
12
|
+
function R({ campaignId: e, templateLibraryId: t }) {
|
|
13
13
|
if (o(e))
|
|
14
14
|
return { scope: "campaign" };
|
|
15
15
|
const n = o(t);
|
|
16
16
|
return n ? { scope: "template", templateId: n } : { scope: "campaign" };
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function S({
|
|
19
19
|
blockId: e,
|
|
20
20
|
url: t,
|
|
21
21
|
campaignId: n,
|
|
@@ -24,7 +24,7 @@ function y({
|
|
|
24
24
|
productIds: s,
|
|
25
25
|
target: r
|
|
26
26
|
}) {
|
|
27
|
-
const i = c ===
|
|
27
|
+
const i = c === u ? p(s).split(d).filter(Boolean) : [];
|
|
28
28
|
return {
|
|
29
29
|
...r.scope === "template" ? { templateId: Number.parseInt(r.templateId) } : {
|
|
30
30
|
campaignId: Number.parseInt(n) || 0,
|
|
@@ -36,7 +36,7 @@ function y({
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
export {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
S as buildLegacyMigrationPayload,
|
|
40
|
+
f as isLegacyStrategyConfig,
|
|
41
|
+
R as resolveMigrationTarget
|
|
42
42
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const i = ",";
|
|
2
|
+
function o(t) {
|
|
3
|
+
return t.map((n) => String(n ?? "").trim()).filter(Boolean).join(",");
|
|
3
4
|
}
|
|
4
5
|
export {
|
|
5
|
-
|
|
6
|
+
i as PRODUCT_ID_SEPARATOR,
|
|
7
|
+
o as sanitizeProductIds
|
|
6
8
|
};
|
|
@@ -1,41 +1,42 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useToaster as
|
|
5
|
-
import { ToasterTypeOptions as
|
|
1
|
+
var S = Object.defineProperty;
|
|
2
|
+
var f = (c, o, e) => o in c ? S(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
|
|
3
|
+
var a = (c, o, e) => f(c, typeof o != "symbol" ? o + "" : o, e);
|
|
4
|
+
import { useToaster as L } from "../../../composables/useToaster.js";
|
|
5
|
+
import { ToasterTypeOptions as A } from "../../../enums/toaster.js";
|
|
6
6
|
import { PAGE_TYPES as h } from "../../../enums/unsubscribe.js";
|
|
7
|
-
import { useEditorStore as
|
|
8
|
-
import { useUnsubscribeStore as
|
|
9
|
-
import { Block as
|
|
10
|
-
import { getDefaultTemplate as
|
|
11
|
-
import { UNSUBSCRIBE_BLOCK_SELECTOR as
|
|
12
|
-
import { parsePageList as
|
|
13
|
-
const
|
|
7
|
+
import { useEditorStore as y } from "../../../stores/editor.js";
|
|
8
|
+
import { useUnsubscribeStore as l } from "../../../stores/unsubscribe.js";
|
|
9
|
+
import { Block as T, BlockCompositionType as I, ContextActionType as B, ModificationDescription as d, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
10
|
+
import { getDefaultTemplate as C } from "./template.js";
|
|
11
|
+
import { UNSUBSCRIBE_BLOCK_SELECTOR as m, DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as b } from "./utils/constants.js";
|
|
12
|
+
import { parsePageList as _ } from "./utils/utils.js";
|
|
13
|
+
const N = "unsubscribe-block", E = 'a[data-unsubscribe-link="true"]', U = "{{ins-unsubscribe-link}}", R = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", D = "Removing the unsubscribe text leaves an empty block, but an active unsubscribe link is required. Undo your last action to restore the text, or delete the unsubscribe block entirely.", w = {
|
|
14
14
|
[h.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
15
15
|
[h.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
class j extends C {
|
|
16
|
+
}, P = 3;
|
|
17
|
+
class W extends T {
|
|
19
18
|
constructor() {
|
|
20
19
|
super();
|
|
21
|
-
|
|
20
|
+
a(this, "selectEventListener", null);
|
|
21
|
+
a(this, "cancelEventListener", null);
|
|
22
|
+
a(this, "currentNode");
|
|
22
23
|
// Per-block "did this instance have a link last time we saw it?" tracking.
|
|
23
24
|
// Keyed by the stable `data-unsubscribe-block-id` we assign, because
|
|
24
25
|
// ImmutableHtmlNode instances are recreated on every document mutation and
|
|
25
26
|
// can't be used as Map keys directly. A singleton boolean here would be
|
|
26
27
|
// polluted across blocks since Stripo fires onDocumentChanged per-instance.
|
|
27
|
-
|
|
28
|
+
a(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
|
|
28
29
|
// Per-block prepend retry counter for the leading text guard (SD-143097).
|
|
29
|
-
|
|
30
|
+
a(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
|
|
30
31
|
}
|
|
31
32
|
getId() {
|
|
32
|
-
return
|
|
33
|
+
return N;
|
|
33
34
|
}
|
|
34
35
|
getIcon() {
|
|
35
36
|
return "unsubscribe-icon";
|
|
36
37
|
}
|
|
37
38
|
getBlockCompositionType() {
|
|
38
|
-
return
|
|
39
|
+
return I.BLOCK;
|
|
39
40
|
}
|
|
40
41
|
getName() {
|
|
41
42
|
return this.api.translate("Unsubscribe Block");
|
|
@@ -44,16 +45,16 @@ class j extends C {
|
|
|
44
45
|
return this.api.translate("Unsubscribe Block Description");
|
|
45
46
|
}
|
|
46
47
|
getTemplate() {
|
|
47
|
-
return
|
|
48
|
+
return C();
|
|
48
49
|
}
|
|
49
50
|
getContextActionsIds() {
|
|
50
|
-
return [
|
|
51
|
+
return [B.MOVE, B.REMOVE];
|
|
51
52
|
}
|
|
52
53
|
onSelect(e) {
|
|
53
|
-
if (this.currentNode = e,
|
|
54
|
+
if (this.currentNode = e, y().isPreviewModeOpen)
|
|
54
55
|
return;
|
|
55
56
|
const t = this._getOrAssignBlockId(e);
|
|
56
|
-
t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (
|
|
57
|
+
t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (l().pendingBlockId = t), this._loadBlockState(e), this._checkExistingBlocks(), this._openDrawer());
|
|
57
58
|
}
|
|
58
59
|
onCreated(e) {
|
|
59
60
|
this._ensureLeadingTextGuard(e);
|
|
@@ -61,7 +62,7 @@ class j extends C {
|
|
|
61
62
|
onDocumentInit() {
|
|
62
63
|
try {
|
|
63
64
|
const e = this.api.getDocumentRoot();
|
|
64
|
-
e && "querySelectorAll" in e && e.querySelectorAll(
|
|
65
|
+
e && "querySelectorAll" in e && e.querySelectorAll(m).forEach((t) => {
|
|
65
66
|
this._ensureLeadingTextGuard(t);
|
|
66
67
|
});
|
|
67
68
|
} catch {
|
|
@@ -72,8 +73,8 @@ class j extends C {
|
|
|
72
73
|
const t = this._getOrAssignBlockId(e);
|
|
73
74
|
if (!t)
|
|
74
75
|
return;
|
|
75
|
-
const
|
|
76
|
-
this.linkStateByBlockId.get(t) === !0 && !
|
|
76
|
+
const s = this._hasUnsubscribeLink(e);
|
|
77
|
+
this.linkStateByBlockId.get(t) === !0 && !s && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, s);
|
|
77
78
|
}
|
|
78
79
|
onDelete(e) {
|
|
79
80
|
this._removeEventListeners(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
|
|
@@ -94,27 +95,27 @@ class j extends C {
|
|
|
94
95
|
const t = e.querySelector(E);
|
|
95
96
|
if (!t)
|
|
96
97
|
return;
|
|
97
|
-
let
|
|
98
|
+
let s = t, r = s.parent();
|
|
98
99
|
for (; r && "getTagName" in r && r.getTagName().toLowerCase() !== "p"; )
|
|
99
|
-
|
|
100
|
+
s = r, r = r.parent();
|
|
100
101
|
if (!r || !("getTagName" in r) || r.getTagName().toLowerCase() !== "p")
|
|
101
102
|
return;
|
|
102
|
-
const
|
|
103
|
-
if (!!(
|
|
104
|
-
const
|
|
105
|
-
|
|
103
|
+
const i = s.previousSibling();
|
|
104
|
+
if (!!(i && i.getType() === "text" && i.getTextContent())) {
|
|
105
|
+
const p = this._readBlockId(e);
|
|
106
|
+
p && this.guardAttemptsByBlockId.delete(p);
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
|
-
const
|
|
109
|
-
if (!
|
|
109
|
+
const g = this._getOrAssignBlockId(e);
|
|
110
|
+
if (!g)
|
|
110
111
|
return;
|
|
111
|
-
const
|
|
112
|
-
if (!(
|
|
113
|
-
this.guardAttemptsByBlockId.set(
|
|
112
|
+
const k = this.guardAttemptsByBlockId.get(g) ?? 0;
|
|
113
|
+
if (!(k >= P)) {
|
|
114
|
+
this.guardAttemptsByBlockId.set(g, k + 1);
|
|
114
115
|
try {
|
|
115
|
-
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new
|
|
116
|
-
} catch (
|
|
117
|
-
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:",
|
|
116
|
+
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new d("Ensure unsubscribe link text guard"));
|
|
117
|
+
} catch (p) {
|
|
118
|
+
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", p);
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
}
|
|
@@ -136,13 +137,13 @@ class j extends C {
|
|
|
136
137
|
return t;
|
|
137
138
|
if (!("getAttribute" in e))
|
|
138
139
|
return null;
|
|
139
|
-
const
|
|
140
|
+
const s = this._generateNextBlockId();
|
|
140
141
|
try {
|
|
141
|
-
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID,
|
|
142
|
+
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new d(`Assign unsubscribe block id ${s}`));
|
|
142
143
|
} catch (r) {
|
|
143
144
|
return console.warn("[UnsubscribeBlock] Failed to assign block id:", r), null;
|
|
144
145
|
}
|
|
145
|
-
return
|
|
146
|
+
return s;
|
|
146
147
|
}
|
|
147
148
|
/**
|
|
148
149
|
* Generates a unique id by scanning the document for the highest existing
|
|
@@ -153,10 +154,10 @@ class j extends C {
|
|
|
153
154
|
let e = 0;
|
|
154
155
|
try {
|
|
155
156
|
const t = this.api.getDocumentRoot();
|
|
156
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
157
|
+
t && "querySelectorAll" in t && t.querySelectorAll(m).forEach((r) => {
|
|
157
158
|
if ("getAttribute" in r) {
|
|
158
|
-
const
|
|
159
|
-
|
|
159
|
+
const i = r.getAttribute(n.BLOCK_ID), u = i ? parseInt(i) : 0;
|
|
160
|
+
u > e && (e = u);
|
|
160
161
|
}
|
|
161
162
|
});
|
|
162
163
|
} catch {
|
|
@@ -165,14 +166,14 @@ class j extends C {
|
|
|
165
166
|
}
|
|
166
167
|
_warnLinkRemoved() {
|
|
167
168
|
try {
|
|
168
|
-
const { showToaster: e } =
|
|
169
|
+
const { showToaster: e } = L();
|
|
169
170
|
e({
|
|
170
|
-
type:
|
|
171
|
-
message: this.api.translate(
|
|
171
|
+
type: A.Warning,
|
|
172
|
+
message: this.api.translate(D),
|
|
172
173
|
actionButton: {
|
|
173
174
|
text: this.api.translate("Visit Academy"),
|
|
174
175
|
onClick: () => {
|
|
175
|
-
window.open(
|
|
176
|
+
window.open(R, "_blank", "noopener,noreferrer");
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
});
|
|
@@ -181,28 +182,28 @@ class j extends C {
|
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
_setupSelectEventListener() {
|
|
184
|
-
this._removeSelectEventListener(),
|
|
185
|
-
const t = e, { collectionType:
|
|
186
|
-
this._updateBlock(
|
|
187
|
-
}, document.addEventListener(
|
|
185
|
+
this._removeSelectEventListener(), this.selectEventListener = (e) => {
|
|
186
|
+
const t = e, { collectionType: s, selectedPages: r } = t.detail;
|
|
187
|
+
this._updateBlock(s, r.join(","));
|
|
188
|
+
}, document.addEventListener(b.SELECT, this.selectEventListener);
|
|
188
189
|
}
|
|
189
190
|
_removeSelectEventListener() {
|
|
190
|
-
|
|
191
|
+
this.selectEventListener && (document.removeEventListener(b.SELECT, this.selectEventListener), this.selectEventListener = null);
|
|
191
192
|
}
|
|
192
193
|
_setupCancelEventListener(e) {
|
|
193
|
-
this._removeCancelEventListener(),
|
|
194
|
-
const { detail:
|
|
195
|
-
((
|
|
196
|
-
}, document.addEventListener(
|
|
194
|
+
this._removeCancelEventListener(), this.cancelEventListener = (t) => {
|
|
195
|
+
const { detail: s } = t;
|
|
196
|
+
((s == null ? void 0 : s.blockId) ?? null) === e && this._handleCancel();
|
|
197
|
+
}, document.addEventListener(b.CANCEL, this.cancelEventListener);
|
|
197
198
|
}
|
|
198
199
|
_removeCancelEventListener() {
|
|
199
|
-
|
|
200
|
+
this.cancelEventListener && (document.removeEventListener(b.CANCEL, this.cancelEventListener), this.cancelEventListener = null);
|
|
200
201
|
}
|
|
201
202
|
_handleCancel() {
|
|
202
203
|
try {
|
|
203
204
|
if (!this.currentNode)
|
|
204
205
|
return;
|
|
205
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${
|
|
206
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new d("Removed unsubscribe block due to cancel"));
|
|
206
207
|
} catch (e) {
|
|
207
208
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
208
209
|
}
|
|
@@ -213,32 +214,32 @@ class j extends C {
|
|
|
213
214
|
_updateBlock(e, t) {
|
|
214
215
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
215
216
|
return;
|
|
216
|
-
const
|
|
217
|
-
if (!
|
|
217
|
+
const s = this.currentNode.querySelector(E);
|
|
218
|
+
if (!s)
|
|
218
219
|
return;
|
|
219
220
|
const r = this._getMergeTag(e);
|
|
220
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
221
|
+
this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new d(`Updated unsubscribe link to ${r}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(n.PAGE_TYPE, e.toString()).setAttribute(n.PAGE_LIST, t).apply(new d("Updated unsubscribe block metadata"));
|
|
221
222
|
}
|
|
222
223
|
_getMergeTag(e) {
|
|
223
|
-
return
|
|
224
|
+
return w[e] ?? U;
|
|
224
225
|
}
|
|
225
226
|
_openDrawer() {
|
|
226
227
|
if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
|
|
227
228
|
try {
|
|
228
|
-
const e =
|
|
229
|
+
const e = l();
|
|
229
230
|
e.typeSelectionDrawerStatus = !0;
|
|
230
231
|
} catch (e) {
|
|
231
232
|
console.error("[UnsubscribeBlock] Failed to open drawer:", e);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
235
|
_checkExistingBlocks() {
|
|
235
|
-
const e =
|
|
236
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
237
|
-
if ("getAttribute" in
|
|
238
|
-
const r =
|
|
236
|
+
const e = l();
|
|
237
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(m).forEach((s) => {
|
|
238
|
+
if ("getAttribute" in s) {
|
|
239
|
+
const r = s.getAttribute(n.PAGE_TYPE);
|
|
239
240
|
if (r) {
|
|
240
|
-
const
|
|
241
|
-
|
|
241
|
+
const i = Number(r);
|
|
242
|
+
i === h.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : i === h.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
245
|
});
|
|
@@ -246,14 +247,14 @@ class j extends C {
|
|
|
246
247
|
async _loadBlockState(e) {
|
|
247
248
|
if (!("getAttribute" in e))
|
|
248
249
|
return;
|
|
249
|
-
const t = e.getAttribute(n.PAGE_TYPE),
|
|
250
|
-
if (!t || !
|
|
250
|
+
const t = e.getAttribute(n.PAGE_TYPE), s = e.getAttribute(n.PAGE_LIST);
|
|
251
|
+
if (!t || !s)
|
|
251
252
|
return;
|
|
252
|
-
const r =
|
|
253
|
-
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(
|
|
253
|
+
const r = l(), i = Number(t), u = _(s);
|
|
254
|
+
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(u);
|
|
254
255
|
}
|
|
255
256
|
_resetStoreState() {
|
|
256
|
-
|
|
257
|
+
l().$reset();
|
|
257
258
|
}
|
|
258
259
|
_removeBlockTemplatesFromStore(e) {
|
|
259
260
|
if (!("getAttribute" in e))
|
|
@@ -261,11 +262,11 @@ class j extends C {
|
|
|
261
262
|
const t = e.getAttribute(n.PAGE_LIST);
|
|
262
263
|
if (!t)
|
|
263
264
|
return;
|
|
264
|
-
const
|
|
265
|
-
|
|
265
|
+
const s = l(), r = _(t);
|
|
266
|
+
s.removeUnsubscribePages(r);
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
export {
|
|
269
|
-
|
|
270
|
-
|
|
270
|
+
N as UNSUBSCRIBE_BLOCK_ID,
|
|
271
|
+
W as UnsubscribeBlock
|
|
271
272
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Separator between product ids in the `productId` value built by `sanitizeProductIds`. */
|
|
2
|
+
export declare const PRODUCT_ID_SEPARATOR = ",";
|
|
1
3
|
/**
|
|
2
4
|
* Builds the request/URL `productId` value from raw product ID segments.
|
|
3
5
|
* Trimming happens here — NOT on input change — so the user's in-progress
|
|
@@ -2,6 +2,8 @@ import type { ImmutableHtmlElementNode, ImmutableHtmlNode } from '@stripoinc/ui-
|
|
|
2
2
|
import { Block, BlockCompositionType } from '@stripoinc/ui-editor-extensions';
|
|
3
3
|
export declare const UNSUBSCRIBE_BLOCK_ID = "unsubscribe-block";
|
|
4
4
|
export declare class UnsubscribeBlock extends Block {
|
|
5
|
+
private selectEventListener;
|
|
6
|
+
private cancelEventListener;
|
|
5
7
|
private currentNode?;
|
|
6
8
|
private linkStateByBlockId;
|
|
7
9
|
private guardAttemptsByBlockId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.20.1-beta.
|
|
3
|
+
"version": "3.20.1-beta.7282c91",
|
|
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",
|