payload-plugin-newsletter 0.25.9 → 0.25.12
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 +24 -0
- package/dist/collections.cjs +89 -95
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +89 -95
- package/dist/collections.js.map +1 -1
- package/dist/fields.cjs +4 -38
- package/dist/fields.cjs.map +1 -1
- package/dist/fields.js +4 -38
- package/dist/fields.js.map +1 -1
- package/dist/server.js +89 -95
- package/dist/utils.cjs +2 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/collections.js
CHANGED
|
@@ -741,25 +741,8 @@ var createEmailSafeFeatures = (additionalBlocks) => {
|
|
|
741
741
|
ItalicFeature(),
|
|
742
742
|
UnderlineFeature(),
|
|
743
743
|
StrikethroughFeature(),
|
|
744
|
-
// Links
|
|
745
|
-
LinkFeature(
|
|
746
|
-
fields: [
|
|
747
|
-
{
|
|
748
|
-
name: "url",
|
|
749
|
-
type: "text",
|
|
750
|
-
required: true,
|
|
751
|
-
admin: {
|
|
752
|
-
description: "Enter the full URL (including https://)"
|
|
753
|
-
}
|
|
754
|
-
},
|
|
755
|
-
{
|
|
756
|
-
name: "newTab",
|
|
757
|
-
type: "checkbox",
|
|
758
|
-
label: "Open in new tab",
|
|
759
|
-
defaultValue: false
|
|
760
|
-
}
|
|
761
|
-
]
|
|
762
|
-
}),
|
|
744
|
+
// Links - use default fields to ensure drawer UI works correctly
|
|
745
|
+
LinkFeature(),
|
|
763
746
|
// Lists
|
|
764
747
|
OrderedListFeature(),
|
|
765
748
|
UnorderedListFeature(),
|
|
@@ -815,25 +798,8 @@ var createEmailLexicalEditor = (customBlocks = []) => {
|
|
|
815
798
|
ItalicFeature(),
|
|
816
799
|
UnderlineFeature(),
|
|
817
800
|
StrikethroughFeature(),
|
|
818
|
-
// Links
|
|
819
|
-
LinkFeature(
|
|
820
|
-
fields: [
|
|
821
|
-
{
|
|
822
|
-
name: "url",
|
|
823
|
-
type: "text",
|
|
824
|
-
required: true,
|
|
825
|
-
admin: {
|
|
826
|
-
description: "Enter the full URL (including https://)"
|
|
827
|
-
}
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
name: "newTab",
|
|
831
|
-
type: "checkbox",
|
|
832
|
-
label: "Open in new tab",
|
|
833
|
-
defaultValue: false
|
|
834
|
-
}
|
|
835
|
-
]
|
|
836
|
-
}),
|
|
801
|
+
// Links - use default fields to ensure drawer UI works correctly
|
|
802
|
+
LinkFeature(),
|
|
837
803
|
// Lists
|
|
838
804
|
OrderedListFeature(),
|
|
839
805
|
UnorderedListFeature(),
|
|
@@ -1401,7 +1367,7 @@ async function getBroadcastConfig(req, pluginConfig) {
|
|
|
1401
1367
|
}
|
|
1402
1368
|
return pluginConfig.providers?.broadcast || null;
|
|
1403
1369
|
} catch (error) {
|
|
1404
|
-
req.payload.logger.error("Failed to get broadcast config from settings
|
|
1370
|
+
req.payload.logger.error({ error: String(error) }, "Failed to get broadcast config from settings");
|
|
1405
1371
|
return pluginConfig.providers?.broadcast || null;
|
|
1406
1372
|
}
|
|
1407
1373
|
}
|
|
@@ -1779,70 +1745,88 @@ var createTestBroadcastEndpoint = (config, collectionSlug) => {
|
|
|
1779
1745
|
};
|
|
1780
1746
|
};
|
|
1781
1747
|
|
|
1782
|
-
// src/
|
|
1748
|
+
// src/utils/mediaPopulation.ts
|
|
1783
1749
|
async function populateMediaFields(content, payload, config) {
|
|
1784
1750
|
if (!content || typeof content !== "object") return content;
|
|
1785
|
-
|
|
1786
|
-
|
|
1751
|
+
const typedContent = content;
|
|
1752
|
+
if (typedContent.root?.children) {
|
|
1753
|
+
for (const child of typedContent.root.children) {
|
|
1787
1754
|
await populateBlockMediaFields(child, payload, config);
|
|
1788
1755
|
}
|
|
1789
1756
|
}
|
|
1790
1757
|
return content;
|
|
1791
1758
|
}
|
|
1792
1759
|
async function populateBlockMediaFields(node, payload, config) {
|
|
1793
|
-
if (node
|
|
1794
|
-
|
|
1760
|
+
if (!node || typeof node !== "object") return;
|
|
1761
|
+
const typedNode = node;
|
|
1762
|
+
if (typedNode.type === "block" && typedNode.fields) {
|
|
1763
|
+
const blockType = typedNode.fields.blockType || typedNode.fields.blockName;
|
|
1795
1764
|
const customBlocks = config.customizations?.broadcasts?.customBlocks || [];
|
|
1796
1765
|
const blockConfig = customBlocks.find((b) => b.slug === blockType);
|
|
1797
1766
|
if (blockConfig && blockConfig.fields) {
|
|
1798
1767
|
for (const field of blockConfig.fields) {
|
|
1799
|
-
if (field.type === "upload" && field.relationTo &&
|
|
1800
|
-
const fieldValue =
|
|
1768
|
+
if (field.type === "upload" && field.relationTo && typedNode.fields[field.name]) {
|
|
1769
|
+
const fieldValue = typedNode.fields[field.name];
|
|
1770
|
+
const collectionName = Array.isArray(field.relationTo) ? field.relationTo[0] : field.relationTo;
|
|
1801
1771
|
if (typeof fieldValue === "string" && fieldValue.match(/^[a-f0-9]{24}$/i)) {
|
|
1802
1772
|
try {
|
|
1803
1773
|
const media = await payload.findByID({
|
|
1804
|
-
collection:
|
|
1774
|
+
collection: collectionName,
|
|
1805
1775
|
id: fieldValue,
|
|
1806
1776
|
depth: 0
|
|
1807
1777
|
});
|
|
1808
1778
|
if (media) {
|
|
1809
|
-
|
|
1810
|
-
payload.logger?.info(
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1779
|
+
typedNode.fields[field.name] = media;
|
|
1780
|
+
payload.logger?.info(
|
|
1781
|
+
{
|
|
1782
|
+
mediaId: fieldValue,
|
|
1783
|
+
mediaUrl: media.url,
|
|
1784
|
+
filename: media.filename
|
|
1785
|
+
},
|
|
1786
|
+
`Populated ${field.name} for block ${blockType}`
|
|
1787
|
+
);
|
|
1815
1788
|
}
|
|
1816
1789
|
} catch (error) {
|
|
1817
|
-
payload.logger?.error(
|
|
1790
|
+
payload.logger?.error(
|
|
1791
|
+
{ error: String(error) },
|
|
1792
|
+
`Failed to populate ${field.name} for block ${blockType}`
|
|
1793
|
+
);
|
|
1818
1794
|
}
|
|
1819
1795
|
}
|
|
1820
1796
|
}
|
|
1821
1797
|
if (field.type === "array" && field.fields) {
|
|
1822
|
-
const arrayValue =
|
|
1798
|
+
const arrayValue = typedNode.fields[field.name];
|
|
1823
1799
|
if (Array.isArray(arrayValue)) {
|
|
1824
1800
|
for (const arrayItem of arrayValue) {
|
|
1825
1801
|
if (arrayItem && typeof arrayItem === "object") {
|
|
1802
|
+
const typedArrayItem = arrayItem;
|
|
1826
1803
|
for (const arrayField of field.fields) {
|
|
1827
|
-
if (arrayField.type === "upload" && arrayField.relationTo &&
|
|
1828
|
-
const arrayFieldValue =
|
|
1804
|
+
if (arrayField.type === "upload" && arrayField.relationTo && typedArrayItem[arrayField.name]) {
|
|
1805
|
+
const arrayFieldValue = typedArrayItem[arrayField.name];
|
|
1806
|
+
const arrayCollectionName = Array.isArray(arrayField.relationTo) ? arrayField.relationTo[0] : arrayField.relationTo;
|
|
1829
1807
|
if (typeof arrayFieldValue === "string" && arrayFieldValue.match(/^[a-f0-9]{24}$/i)) {
|
|
1830
1808
|
try {
|
|
1831
1809
|
const media = await payload.findByID({
|
|
1832
|
-
collection:
|
|
1810
|
+
collection: arrayCollectionName,
|
|
1833
1811
|
id: arrayFieldValue,
|
|
1834
1812
|
depth: 0
|
|
1835
1813
|
});
|
|
1836
1814
|
if (media) {
|
|
1837
|
-
|
|
1838
|
-
payload.logger?.info(
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1815
|
+
typedArrayItem[arrayField.name] = media;
|
|
1816
|
+
payload.logger?.info(
|
|
1817
|
+
{
|
|
1818
|
+
mediaId: arrayFieldValue,
|
|
1819
|
+
mediaUrl: media.url,
|
|
1820
|
+
filename: media.filename
|
|
1821
|
+
},
|
|
1822
|
+
`Populated array ${arrayField.name} for block ${blockType}`
|
|
1823
|
+
);
|
|
1843
1824
|
}
|
|
1844
1825
|
} catch (error) {
|
|
1845
|
-
payload.logger?.error(
|
|
1826
|
+
payload.logger?.error(
|
|
1827
|
+
{ error: String(error) },
|
|
1828
|
+
`Failed to populate array ${arrayField.name} for block ${blockType}`
|
|
1829
|
+
);
|
|
1846
1830
|
}
|
|
1847
1831
|
}
|
|
1848
1832
|
}
|
|
@@ -1851,23 +1835,24 @@ async function populateBlockMediaFields(node, payload, config) {
|
|
|
1851
1835
|
}
|
|
1852
1836
|
}
|
|
1853
1837
|
}
|
|
1854
|
-
if (field.type === "richText" &&
|
|
1855
|
-
await populateRichTextUploads(
|
|
1838
|
+
if (field.type === "richText" && typedNode.fields[field.name]) {
|
|
1839
|
+
await populateRichTextUploads(typedNode.fields[field.name], payload);
|
|
1856
1840
|
payload.logger?.info(`Processed rich text field ${field.name} for upload nodes`);
|
|
1857
1841
|
}
|
|
1858
1842
|
}
|
|
1859
1843
|
}
|
|
1860
1844
|
}
|
|
1861
|
-
if (
|
|
1862
|
-
for (const child of
|
|
1845
|
+
if (typedNode.children) {
|
|
1846
|
+
for (const child of typedNode.children) {
|
|
1863
1847
|
await populateBlockMediaFields(child, payload, config);
|
|
1864
1848
|
}
|
|
1865
1849
|
}
|
|
1866
1850
|
}
|
|
1867
1851
|
async function populateRichTextUploads(content, payload) {
|
|
1868
1852
|
if (!content || typeof content !== "object") return;
|
|
1869
|
-
|
|
1870
|
-
|
|
1853
|
+
const typedContent = content;
|
|
1854
|
+
if (typedContent.root?.children) {
|
|
1855
|
+
await processNodeArray(typedContent.root.children);
|
|
1871
1856
|
}
|
|
1872
1857
|
if (Array.isArray(content)) {
|
|
1873
1858
|
await processNodeArray(content);
|
|
@@ -1877,33 +1862,42 @@ async function populateRichTextUploads(content, payload) {
|
|
|
1877
1862
|
}
|
|
1878
1863
|
async function processNode(node) {
|
|
1879
1864
|
if (!node || typeof node !== "object") return;
|
|
1880
|
-
|
|
1865
|
+
const typedNode = node;
|
|
1866
|
+
if (typedNode.type === "upload" && typedNode.relationTo === "media" && typeof typedNode.value === "string" && typedNode.value.match(/^[a-f0-9]{24}$/i)) {
|
|
1881
1867
|
try {
|
|
1882
1868
|
const media = await payload.findByID({
|
|
1883
1869
|
collection: "media",
|
|
1884
|
-
id:
|
|
1870
|
+
id: typedNode.value,
|
|
1885
1871
|
depth: 0
|
|
1886
1872
|
});
|
|
1887
1873
|
if (media) {
|
|
1888
|
-
|
|
1889
|
-
payload.logger?.info(
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1874
|
+
typedNode.value = media;
|
|
1875
|
+
payload.logger?.info(
|
|
1876
|
+
{
|
|
1877
|
+
mediaId: typedNode.value,
|
|
1878
|
+
mediaUrl: media.url,
|
|
1879
|
+
filename: media.filename
|
|
1880
|
+
},
|
|
1881
|
+
"Populated rich text upload node"
|
|
1882
|
+
);
|
|
1894
1883
|
}
|
|
1895
1884
|
} catch (error) {
|
|
1896
|
-
payload.logger?.error(
|
|
1885
|
+
payload.logger?.error(
|
|
1886
|
+
{ error: String(error) },
|
|
1887
|
+
`Failed to populate rich text upload ${typedNode.value}`
|
|
1888
|
+
);
|
|
1897
1889
|
}
|
|
1898
1890
|
}
|
|
1899
|
-
if (
|
|
1900
|
-
await processNodeArray(
|
|
1891
|
+
if (typedNode.children && Array.isArray(typedNode.children)) {
|
|
1892
|
+
await processNodeArray(typedNode.children);
|
|
1901
1893
|
}
|
|
1902
|
-
if (
|
|
1903
|
-
await processNodeArray(
|
|
1894
|
+
if (typedNode.root?.children && Array.isArray(typedNode.root.children)) {
|
|
1895
|
+
await processNodeArray(typedNode.root.children);
|
|
1904
1896
|
}
|
|
1905
1897
|
}
|
|
1906
1898
|
}
|
|
1899
|
+
|
|
1900
|
+
// src/endpoints/broadcasts/preview.ts
|
|
1907
1901
|
var createBroadcastPreviewEndpoint = (config, _collectionSlug) => {
|
|
1908
1902
|
return {
|
|
1909
1903
|
path: "/preview",
|
|
@@ -2297,7 +2291,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2297
2291
|
return doc;
|
|
2298
2292
|
}
|
|
2299
2293
|
if (operation === "update") {
|
|
2300
|
-
req.payload.logger.info(
|
|
2294
|
+
req.payload.logger.info({
|
|
2301
2295
|
operation,
|
|
2302
2296
|
hasProviderId: !!doc.providerId,
|
|
2303
2297
|
hasExternalId: !!doc.externalId,
|
|
@@ -2305,7 +2299,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2305
2299
|
publishStatus: doc._status,
|
|
2306
2300
|
hasSubject: !!doc.subject,
|
|
2307
2301
|
hasContent: !!doc.contentSection?.content
|
|
2308
|
-
});
|
|
2302
|
+
}, "Broadcast afterChange update hook triggered");
|
|
2309
2303
|
try {
|
|
2310
2304
|
const providerConfig = await getBroadcastConfig(req, pluginConfig);
|
|
2311
2305
|
if (!providerConfig || !providerConfig.token) {
|
|
@@ -2392,10 +2386,10 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2392
2386
|
if (JSON.stringify(doc.audienceIds) !== JSON.stringify(previousDoc?.audienceIds)) {
|
|
2393
2387
|
updates.audienceIds = doc.audienceIds?.map((a) => a.audienceId);
|
|
2394
2388
|
}
|
|
2395
|
-
req.payload.logger.info(
|
|
2389
|
+
req.payload.logger.info({
|
|
2396
2390
|
providerId: doc.providerId,
|
|
2397
2391
|
updates
|
|
2398
|
-
});
|
|
2392
|
+
}, "Syncing broadcast updates to provider");
|
|
2399
2393
|
await provider.update(doc.providerId, updates);
|
|
2400
2394
|
req.payload.logger.info(`Broadcast ${doc.id} synced to provider successfully`);
|
|
2401
2395
|
} else {
|
|
@@ -2417,18 +2411,18 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2417
2411
|
...error.statusText
|
|
2418
2412
|
});
|
|
2419
2413
|
} else if (typeof error === "string") {
|
|
2420
|
-
req.payload.logger.error("Error is a string
|
|
2414
|
+
req.payload.logger.error({ errorValue: error }, "Error is a string");
|
|
2421
2415
|
} else if (error && typeof error === "object") {
|
|
2422
|
-
req.payload.logger.error(
|
|
2416
|
+
req.payload.logger.error({ errorValue: JSON.stringify(error, null, 2) }, "Error is an object");
|
|
2423
2417
|
} else {
|
|
2424
|
-
req.payload.logger.error("Unknown error type
|
|
2418
|
+
req.payload.logger.error({ errorType: typeof error }, "Unknown error type");
|
|
2425
2419
|
}
|
|
2426
|
-
req.payload.logger.error(
|
|
2420
|
+
req.payload.logger.error({
|
|
2427
2421
|
id: doc.id,
|
|
2428
2422
|
subject: doc.subject,
|
|
2429
2423
|
hasContent: !!doc.contentSection?.content,
|
|
2430
2424
|
contentType: doc.contentSection?.content ? typeof doc.contentSection.content : "none"
|
|
2431
|
-
});
|
|
2425
|
+
}, "Failed broadcast document (update operation)");
|
|
2432
2426
|
}
|
|
2433
2427
|
}
|
|
2434
2428
|
return doc;
|
|
@@ -2474,7 +2468,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2474
2468
|
...error.details
|
|
2475
2469
|
});
|
|
2476
2470
|
} else {
|
|
2477
|
-
req.payload.logger.error(`Failed to send broadcast ${doc.id}
|
|
2471
|
+
req.payload.logger.error({ error: String(error) }, `Failed to send broadcast ${doc.id}`);
|
|
2478
2472
|
}
|
|
2479
2473
|
await req.payload.update({
|
|
2480
2474
|
collection: "broadcasts",
|
|
@@ -2517,7 +2511,7 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
2517
2511
|
...error.details
|
|
2518
2512
|
});
|
|
2519
2513
|
} else {
|
|
2520
|
-
req.payload.logger.error("Failed to delete broadcast from provider
|
|
2514
|
+
req.payload.logger.error({ error: String(error) }, "Failed to delete broadcast from provider");
|
|
2521
2515
|
}
|
|
2522
2516
|
}
|
|
2523
2517
|
return doc;
|