payload-plugin-newsletter 0.16.7 → 0.16.9
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/CHANGELOG.md +30 -0
- package/dist/collections.cjs +128 -39
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +128 -39
- package/dist/collections.js.map +1 -1
- package/dist/components.cjs +3 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +3 -0
- package/dist/components.js.map +1 -1
- package/dist/index.cjs +128 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +128 -39
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +3 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -0
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/collections.js
CHANGED
|
@@ -947,6 +947,9 @@ var EMAIL_SAFE_CONFIG = {
|
|
|
947
947
|
FORBID_ATTR: ["class", "id", "onclick", "onload", "onerror"]
|
|
948
948
|
};
|
|
949
949
|
async function convertToEmailSafeHtml(editorState, options) {
|
|
950
|
+
if (!editorState) {
|
|
951
|
+
return "";
|
|
952
|
+
}
|
|
950
953
|
const rawHtml = await lexicalToEmailHtml(editorState, options?.mediaUrl);
|
|
951
954
|
const sanitizedHtml = DOMPurify.sanitize(rawHtml, EMAIL_SAFE_CONFIG);
|
|
952
955
|
if (options?.wrapInTemplate) {
|
|
@@ -1444,6 +1447,10 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1444
1447
|
async ({ doc, operation, req, previousDoc }) => {
|
|
1445
1448
|
if (!hasProviders) return doc;
|
|
1446
1449
|
if (operation === "create") {
|
|
1450
|
+
if (!doc.subject || !doc.contentSection?.content) {
|
|
1451
|
+
req.payload.logger.info("Skipping provider sync - broadcast has no subject or content yet");
|
|
1452
|
+
return doc;
|
|
1453
|
+
}
|
|
1447
1454
|
try {
|
|
1448
1455
|
const providerConfig = await getBroadcastConfig(req, pluginConfig);
|
|
1449
1456
|
if (!providerConfig || !providerConfig.token) {
|
|
@@ -1454,6 +1461,10 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1454
1461
|
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1455
1462
|
req.payload.logger.info("Converting content to HTML...");
|
|
1456
1463
|
const htmlContent = await convertToEmailSafeHtml(doc.contentSection?.content);
|
|
1464
|
+
if (!htmlContent || htmlContent.trim() === "") {
|
|
1465
|
+
req.payload.logger.info("Skipping provider sync - content is empty after conversion");
|
|
1466
|
+
return doc;
|
|
1467
|
+
}
|
|
1457
1468
|
const createData = {
|
|
1458
1469
|
name: doc.subject,
|
|
1459
1470
|
// Use subject as name since we removed the name field
|
|
@@ -1525,7 +1536,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1525
1536
|
return doc;
|
|
1526
1537
|
}
|
|
1527
1538
|
}
|
|
1528
|
-
if (operation === "update"
|
|
1539
|
+
if (operation === "update") {
|
|
1529
1540
|
req.payload.logger.info("Broadcast afterChange update hook triggered", {
|
|
1530
1541
|
operation,
|
|
1531
1542
|
hasProviderId: !!doc.providerId,
|
|
@@ -1540,57 +1551,135 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1540
1551
|
}
|
|
1541
1552
|
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1542
1553
|
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
return doc;
|
|
1548
|
-
}
|
|
1549
|
-
const contentChanged = doc.subject !== previousDoc?.subject || doc.contentSection?.preheader !== previousDoc?.contentSection?.preheader || JSON.stringify(doc.contentSection?.content) !== JSON.stringify(previousDoc?.contentSection?.content) || doc.settings?.trackOpens !== previousDoc?.settings?.trackOpens || doc.settings?.trackClicks !== previousDoc?.settings?.trackClicks || doc.settings?.replyTo !== previousDoc?.settings?.replyTo || JSON.stringify(doc.audienceIds) !== JSON.stringify(previousDoc?.audienceIds);
|
|
1550
|
-
if (contentChanged) {
|
|
1551
|
-
const updates = {};
|
|
1552
|
-
if (doc.subject !== previousDoc?.subject) {
|
|
1553
|
-
updates.name = doc.subject;
|
|
1554
|
-
updates.subject = doc.subject;
|
|
1555
|
-
}
|
|
1556
|
-
if (doc.contentSection?.preheader !== previousDoc?.contentSection?.preheader) {
|
|
1557
|
-
updates.preheader = doc.contentSection?.preheader;
|
|
1554
|
+
if (!doc.providerId) {
|
|
1555
|
+
if (!doc.subject || !doc.contentSection?.content) {
|
|
1556
|
+
req.payload.logger.info("Still missing required fields for provider sync");
|
|
1557
|
+
return doc;
|
|
1558
1558
|
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1559
|
+
try {
|
|
1560
|
+
req.payload.logger.info("Creating broadcast in provider (deferred from initial create)...");
|
|
1561
|
+
const htmlContent = await convertToEmailSafeHtml(doc.contentSection?.content);
|
|
1562
|
+
if (!htmlContent || htmlContent.trim() === "") {
|
|
1563
|
+
req.payload.logger.info("Skipping provider sync - content is empty after conversion");
|
|
1564
|
+
return doc;
|
|
1565
|
+
}
|
|
1566
|
+
const createData = {
|
|
1567
|
+
name: doc.subject,
|
|
1568
|
+
subject: doc.subject,
|
|
1569
|
+
preheader: doc.contentSection?.preheader,
|
|
1570
|
+
content: htmlContent,
|
|
1571
|
+
trackOpens: doc.settings?.trackOpens,
|
|
1572
|
+
trackClicks: doc.settings?.trackClicks,
|
|
1573
|
+
replyTo: doc.settings?.replyTo || providerConfig.replyTo,
|
|
1574
|
+
audienceIds: doc.audienceIds?.map((a) => a.audienceId)
|
|
1575
|
+
};
|
|
1576
|
+
req.payload.logger.info("Creating broadcast with data:", {
|
|
1577
|
+
name: createData.name,
|
|
1578
|
+
subject: createData.subject,
|
|
1579
|
+
preheader: createData.preheader || "NONE",
|
|
1580
|
+
contentLength: htmlContent ? htmlContent.length : 0,
|
|
1581
|
+
contentPreview: htmlContent ? htmlContent.substring(0, 100) + "..." : "EMPTY",
|
|
1582
|
+
apiUrl: providerConfig.apiUrl,
|
|
1583
|
+
hasToken: !!providerConfig.token
|
|
1584
|
+
});
|
|
1585
|
+
const providerBroadcast = await provider.create(createData);
|
|
1586
|
+
await req.payload.update({
|
|
1587
|
+
collection: "broadcasts",
|
|
1588
|
+
id: doc.id,
|
|
1589
|
+
data: {
|
|
1590
|
+
providerId: providerBroadcast.id,
|
|
1591
|
+
providerData: providerBroadcast.providerData
|
|
1592
|
+
},
|
|
1593
|
+
req
|
|
1594
|
+
});
|
|
1595
|
+
req.payload.logger.info(`Broadcast ${doc.id} created in provider successfully (deferred)`);
|
|
1596
|
+
return {
|
|
1597
|
+
...doc,
|
|
1598
|
+
providerId: providerBroadcast.id,
|
|
1599
|
+
providerData: providerBroadcast.providerData
|
|
1600
|
+
};
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
req.payload.logger.error("Raw error from broadcast provider (deferred create):");
|
|
1603
|
+
req.payload.logger.error(error);
|
|
1604
|
+
if (error instanceof Error) {
|
|
1605
|
+
req.payload.logger.error("Error is instance of Error:", {
|
|
1606
|
+
message: error.message,
|
|
1607
|
+
stack: error.stack,
|
|
1608
|
+
name: error.name,
|
|
1609
|
+
...error.details,
|
|
1610
|
+
...error.response,
|
|
1611
|
+
...error.data,
|
|
1612
|
+
...error.status,
|
|
1613
|
+
...error.statusText
|
|
1614
|
+
});
|
|
1615
|
+
} else if (typeof error === "string") {
|
|
1616
|
+
req.payload.logger.error("Error is a string:", error);
|
|
1617
|
+
} else if (error && typeof error === "object") {
|
|
1618
|
+
req.payload.logger.error("Error is an object:", JSON.stringify(error, null, 2));
|
|
1619
|
+
} else {
|
|
1620
|
+
req.payload.logger.error("Unknown error type:", typeof error);
|
|
1621
|
+
}
|
|
1622
|
+
req.payload.logger.error("Failed broadcast document (deferred create):", {
|
|
1623
|
+
id: doc.id,
|
|
1624
|
+
subject: doc.subject,
|
|
1625
|
+
hasContent: !!doc.contentSection?.content,
|
|
1626
|
+
contentType: doc.contentSection?.content ? typeof doc.contentSection.content : "none"
|
|
1627
|
+
});
|
|
1628
|
+
return doc;
|
|
1567
1629
|
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1630
|
+
}
|
|
1631
|
+
if (doc.providerId) {
|
|
1632
|
+
const capabilities = provider.getCapabilities();
|
|
1633
|
+
const sendStatus = doc.sendStatus || "draft" /* DRAFT */;
|
|
1634
|
+
if (!capabilities.editableStatuses.includes(sendStatus)) {
|
|
1635
|
+
req.payload.logger.info(`Skipping sync for broadcast in status: ${sendStatus}`);
|
|
1636
|
+
return doc;
|
|
1570
1637
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1638
|
+
const contentChanged = doc.subject !== previousDoc?.subject || doc.contentSection?.preheader !== previousDoc?.contentSection?.preheader || JSON.stringify(doc.contentSection?.content) !== JSON.stringify(previousDoc?.contentSection?.content) || doc.settings?.trackOpens !== previousDoc?.settings?.trackOpens || doc.settings?.trackClicks !== previousDoc?.settings?.trackClicks || doc.settings?.replyTo !== previousDoc?.settings?.replyTo || JSON.stringify(doc.audienceIds) !== JSON.stringify(previousDoc?.audienceIds);
|
|
1639
|
+
if (contentChanged) {
|
|
1640
|
+
const updates = {};
|
|
1641
|
+
if (doc.subject !== previousDoc?.subject) {
|
|
1642
|
+
updates.name = doc.subject;
|
|
1643
|
+
updates.subject = doc.subject;
|
|
1644
|
+
}
|
|
1645
|
+
if (doc.contentSection?.preheader !== previousDoc?.contentSection?.preheader) {
|
|
1646
|
+
updates.preheader = doc.contentSection?.preheader;
|
|
1647
|
+
}
|
|
1648
|
+
if (JSON.stringify(doc.contentSection?.content) !== JSON.stringify(previousDoc?.contentSection?.content)) {
|
|
1649
|
+
updates.content = await convertToEmailSafeHtml(doc.contentSection?.content);
|
|
1650
|
+
}
|
|
1651
|
+
if (doc.settings?.trackOpens !== previousDoc?.settings?.trackOpens) {
|
|
1652
|
+
updates.trackOpens = doc.settings.trackOpens;
|
|
1653
|
+
}
|
|
1654
|
+
if (doc.settings?.trackClicks !== previousDoc?.settings?.trackClicks) {
|
|
1655
|
+
updates.trackClicks = doc.settings.trackClicks;
|
|
1656
|
+
}
|
|
1657
|
+
if (doc.settings?.replyTo !== previousDoc?.settings?.replyTo) {
|
|
1658
|
+
updates.replyTo = doc.settings.replyTo || providerConfig.replyTo;
|
|
1659
|
+
}
|
|
1660
|
+
if (JSON.stringify(doc.audienceIds) !== JSON.stringify(previousDoc?.audienceIds)) {
|
|
1661
|
+
updates.audienceIds = doc.audienceIds?.map((a) => a.audienceId);
|
|
1662
|
+
}
|
|
1663
|
+
req.payload.logger.info("Syncing broadcast updates to provider", {
|
|
1664
|
+
providerId: doc.providerId,
|
|
1665
|
+
updates
|
|
1666
|
+
});
|
|
1667
|
+
await provider.update(doc.providerId, updates);
|
|
1668
|
+
req.payload.logger.info(`Broadcast ${doc.id} synced to provider successfully`);
|
|
1669
|
+
} else {
|
|
1670
|
+
req.payload.logger.info("No content changes to sync to provider");
|
|
1573
1671
|
}
|
|
1574
|
-
req.payload.logger.info("Syncing broadcast updates to provider", {
|
|
1575
|
-
providerId: doc.providerId,
|
|
1576
|
-
updates
|
|
1577
|
-
});
|
|
1578
|
-
await provider.update(doc.providerId, updates);
|
|
1579
|
-
req.payload.logger.info(`Broadcast ${doc.id} synced to provider successfully`);
|
|
1580
|
-
} else {
|
|
1581
|
-
req.payload.logger.info("No content changes to sync to provider");
|
|
1582
1672
|
}
|
|
1583
1673
|
} catch (error) {
|
|
1584
1674
|
if (error instanceof Error) {
|
|
1585
|
-
req.payload.logger.error("Failed to
|
|
1675
|
+
req.payload.logger.error("Failed to handle broadcast update operation:", {
|
|
1586
1676
|
message: error.message,
|
|
1587
1677
|
stack: error.stack,
|
|
1588
1678
|
name: error.name,
|
|
1589
|
-
// If it's a BroadcastProviderError, it might have additional details
|
|
1590
1679
|
...error.details
|
|
1591
1680
|
});
|
|
1592
1681
|
} else {
|
|
1593
|
-
req.payload.logger.error("Failed to
|
|
1682
|
+
req.payload.logger.error("Failed to handle broadcast update operation:", error);
|
|
1594
1683
|
}
|
|
1595
1684
|
}
|
|
1596
1685
|
}
|